fixed typo (missing '\' in '\n')
[acx-mac80211.git] / common.c
blob5c23b3dcb82f3bf28a167f55eeb78df785d9bb1c
1 /**** (legal) claimer in README
2 ** Copyright (C) 2003 ACX100 Open Source Project
3 */
6 /*
7 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
8 #include <linux/config.h>
9 #endif
11 #include <linux/version.h>
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/sched.h>
15 #include <linux/types.h>
16 #include <linux/slab.h>
17 #include <linux/delay.h>
18 #include <linux/proc_fs.h>
19 #include <linux/if_arp.h>
20 #include <linux/rtnetlink.h>
21 #include <linux/netdevice.h>
22 #include <linux/etherdevice.h>
23 #include <linux/wireless.h>
24 #include <linux/pm.h>
25 #include <linux/vmalloc.h>
26 #include <linux/firmware.h>
27 //#include <net/iw_handler.h>
28 #include <linux/ethtool.h>
29 //#include <linux/utsrelease.h>
31 #include "acx.h"
34 /***********************************************************************
37 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf);
41 /***********************************************************************
43 #if ACX_DEBUG
44 unsigned int acx_debug /* will add __read_mostly later */ = ACX_DEFAULT_MSG;
45 /* parameter is 'debug', corresponding var is acx_debug */
46 module_param_named(debug, acx_debug, uint, 0);
47 MODULE_PARM_DESC(debug, "Debug level mask (see L_xxx constants)");
48 #endif
50 #ifdef MODULE_LICENSE
51 MODULE_LICENSE("Dual MPL/GPL");
52 #endif
53 /* USB had this: MODULE_AUTHOR("Martin Wawro <martin.wawro AT uni-dortmund.de>"); */
54 MODULE_AUTHOR("ACX100 Open Source Driver development team");
55 MODULE_DESCRIPTION
56 ("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)");
59 /***********************************************************************
61 /* Probably a number of acx's intermediate buffers for USB transfers,
62 ** not to be confused with number of descriptors in tx/rx rings
63 ** (which are not directly accessible to host in USB devices) */
64 #define USB_RX_CNT 10
65 #define USB_TX_CNT 10
68 /***********************************************************************
71 /* minutes to wait until next radio recalibration: */
72 #define RECALIB_PAUSE 5
74 /* Please keep acx_reg_domain_ids_len in sync... */
75 const u8 acx_reg_domain_ids[acx_reg_domain_ids_len] =
76 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 };
77 static const u16 reg_domain_channel_masks[acx_reg_domain_ids_len] =
78 { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc };
79 const char *const
80 acx_reg_domain_strings[] = {
81 /* 0 */ " 1-11 FCC (USA)",
82 /* 1 */ " 1-11 DOC/IC (Canada)",
83 /* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */
84 /* 2 */ " 1-13 ETSI (Europe)",
85 /* 3 */ "10-11 Spain",
86 /* 4 */ "10-13 France",
87 /* 5 */ " 14 MKK (Japan)",
88 /* 6 */ " 1-14 MKK1",
89 /* 7 */ " 3-9 Israel (not all firmware versions)",
90 NULL /* needs to remain as last entry */
95 /***********************************************************************
96 ** Debugging support
98 #ifdef PARANOID_LOCKING
99 static unsigned max_lock_time;
100 static unsigned max_sem_time;
102 /* Obvious or linux kernel specific derived code follows: */
104 void acx_lock_unhold()
106 max_lock_time = 0;
109 void acx_sem_unhold()
111 max_sem_time = 0;
114 static inline const char *sanitize_str(const char *s)
116 const char *t = strrchr(s, '/');
117 if (t)
118 return t + 1;
119 return s;
122 void acx_lock_debug(acx_device_t * adev, const char *where)
124 unsigned int count = 100 * 1000 * 1000;
125 where = sanitize_str(where);
126 while (--count) {
127 if (!spin_is_locked(&adev->lock))
128 break;
129 cpu_relax();
131 if (!count) {
132 printk(KERN_EMERG "LOCKUP: already taken at %s!\n",
133 adev->last_lock);
134 BUG();
136 adev->last_lock = where;
137 rdtscl(adev->lock_time);
139 void acx_unlock_debug(acx_device_t * adev, const char *where)
141 #ifdef SMP
142 if (!spin_is_locked(&adev->lock)) {
143 where = sanitize_str(where);
144 printk(KERN_EMERG "STRAY UNLOCK at %s!\n", where);
145 BUG();
147 #endif
148 if (acx_debug & L_LOCK) {
149 unsigned long diff;
150 rdtscl(diff);
151 diff -= adev->lock_time;
152 if (diff > max_lock_time) {
153 where = sanitize_str(where);
154 printk("max lock hold time %ld CPU ticks from %s "
155 "to %s\n", diff, adev->last_lock, where);
156 max_lock_time = diff;
160 #endif /* PARANOID_LOCKING */
163 /***********************************************************************
165 #if ACX_DEBUG > 1
167 static int acx_debug_func_indent;
168 #define DEBUG_TSC 0
169 #define FUNC_INDENT_INCREMENT 2
171 #if DEBUG_TSC
172 #define TIMESTAMP(d) unsigned long d; rdtscl(d)
173 #else
174 #define TIMESTAMP(d) unsigned long d = jiffies
175 #endif
177 static const char spaces[] = " " " "; /* Nx10 spaces */
179 void log_fn_enter(const char *funcname)
181 int indent;
182 TIMESTAMP(d);
184 indent = acx_debug_func_indent;
185 if (indent >= sizeof(spaces))
186 indent = sizeof(spaces) - 1;
188 printk("%08ld %s==> %s\n",
189 d % 100000000, spaces + (sizeof(spaces) - 1) - indent, funcname);
191 acx_debug_func_indent += FUNC_INDENT_INCREMENT;
193 void log_fn_exit(const char *funcname)
195 int indent;
196 TIMESTAMP(d);
198 acx_debug_func_indent -= FUNC_INDENT_INCREMENT;
200 indent = acx_debug_func_indent;
201 if (indent >= sizeof(spaces))
202 indent = sizeof(spaces) - 1;
204 printk("%08ld %s<== %s\n",
205 d % 100000000, spaces + (sizeof(spaces) - 1) - indent, funcname);
207 void log_fn_exit_v(const char *funcname, int v)
209 int indent;
210 TIMESTAMP(d);
212 acx_debug_func_indent -= FUNC_INDENT_INCREMENT;
214 indent = acx_debug_func_indent;
215 if (indent >= sizeof(spaces))
216 indent = sizeof(spaces) - 1;
218 printk("%08ld %s<== %s: %08X\n",
219 d % 100000000,
220 spaces + (sizeof(spaces) - 1) - indent, funcname, v);
222 #endif /* ACX_DEBUG > 1 */
225 /***********************************************************************
226 ** Basically a msleep with logging
228 void acx_s_msleep(int ms)
230 FN_ENTER;
231 msleep(ms);
232 FN_EXIT0;
236 /***********************************************************************
237 ** Not inlined: it's larger than it seems
239 void acx_print_mac(const char *head, const u8 * mac, const char *tail)
241 printk("%s" MACSTR "%s", head, MAC(mac), tail);
247 /***********************************************************************
248 ** acx_cmd_status_str
250 const char *acx_cmd_status_str(unsigned int state)
252 static const char *const cmd_error_strings[] = {
253 "Idle",
254 "Success",
255 "Unknown Command",
256 "Invalid Information Element",
257 "Channel rejected",
258 "Channel invalid in current regulatory domain",
259 "MAC invalid",
260 "Command rejected (read-only information element)",
261 "Command rejected",
262 "Already asleep",
263 "TX in progress",
264 "Already awake",
265 "Write only",
266 "RX in progress",
267 "Invalid parameter",
268 "Scan in progress",
269 "Failed"
271 return state < ARRAY_SIZE(cmd_error_strings) ?
272 cmd_error_strings[state] : "?";
275 /***********************************************************************
277 #if ACX_DEBUG
278 void acx_dump_bytes(const void *data, int num)
280 const u8 *ptr = (const u8 *)data;
282 FN_ENTER;
284 if (num <= 0) {
285 printk("\n");
286 return;
289 while (num >= 16) {
290 printk("%02X %02X %02X %02X %02X %02X %02X %02X "
291 "%02X %02X %02X %02X %02X %02X %02X %02X\n",
292 ptr[0], ptr[1], ptr[2], ptr[3],
293 ptr[4], ptr[5], ptr[6], ptr[7],
294 ptr[8], ptr[9], ptr[10], ptr[11],
295 ptr[12], ptr[13], ptr[14], ptr[15]);
296 num -= 16;
297 ptr += 16;
299 if (num > 0) {
300 while (--num > 0)
301 printk("%02X ", *ptr++);
302 printk("%02X\n", *ptr);
305 FN_EXIT0;
308 #endif
311 /***********************************************************************
312 ** acx_s_get_firmware_version
314 ** Obvious
316 void acx_s_get_firmware_version(acx_device_t * adev)
318 fw_ver_t fw;
319 u8 hexarr[4] = { 0, 0, 0, 0 };
320 int hexidx = 0, val = 0;
321 const char *num;
322 char c;
324 FN_ENTER;
326 memset(fw.fw_id, 'E', FW_ID_SIZE);
327 acx_s_interrogate(adev, &fw, ACX1xx_IE_FWREV);
328 memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE);
329 adev->firmware_version[FW_ID_SIZE] = '\0';
331 log(L_DEBUG, "fw_ver: fw_id='%s' hw_id=%08X\n",
332 adev->firmware_version, fw.hw_id);
334 if (strncmp(fw.fw_id, "Rev ", 4) != 0) {
335 printk("acx: strange firmware version string "
336 "'%s', please report\n", adev->firmware_version);
337 adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */
338 } else {
339 num = &fw.fw_id[4];
340 while (1) {
341 c = *num++;
342 if ((c == '.') || (c == '\0')) {
343 hexarr[hexidx++] = val;
344 if ((hexidx > 3) || (c == '\0')) /* end? */
345 break;
346 val = 0;
347 continue;
349 if ((c >= '0') && (c <= '9'))
350 c -= '0';
351 else
352 c = c - 'a' + (char)10;
353 val = val * 16 + c;
356 adev->firmware_numver = (u32) ((hexarr[0] << 24) |
357 (hexarr[1] << 16)
358 | (hexarr[2] << 8) | hexarr[3]);
359 log(L_DEBUG, "firmware_numver 0x%08X\n", adev->firmware_numver);
361 if (IS_ACX111(adev)) {
362 if (adev->firmware_numver == 0x00010011) {
363 /* This one does not survive floodpinging */
364 printk("acx: firmware '%s' is known to be buggy, "
365 "please upgrade\n", adev->firmware_version);
369 adev->firmware_id = le32_to_cpu(fw.hw_id);
371 /* we're able to find out more detailed chip names now */
372 switch (adev->firmware_id & 0xffff0000) {
373 case 0x01010000:
374 case 0x01020000:
375 adev->chip_name = "TNETW1100A";
376 break;
377 case 0x01030000:
378 adev->chip_name = "TNETW1100B";
379 break;
380 case 0x03000000:
381 case 0x03010000:
382 adev->chip_name = "TNETW1130";
383 break;
384 case 0x04030000: /* 0x04030101 is TNETW1450 */
385 adev->chip_name = "TNETW1450";
386 break;
387 default:
388 printk("acx: unknown chip ID 0x%08X, "
389 "please report\n", adev->firmware_id);
390 break;
393 FN_EXIT0;
397 /***********************************************************************
398 ** acx_display_hardware_details
400 ** Displays hw/fw version, radio type etc...
402 ** Obvious
404 void acx_display_hardware_details(acx_device_t * adev)
406 const char *radio_str, *form_str;
408 FN_ENTER;
410 switch (adev->radio_type) {
411 case RADIO_MAXIM_0D:
412 radio_str = "Maxim";
413 break;
414 case RADIO_RFMD_11:
415 radio_str = "RFMD";
416 break;
417 case RADIO_RALINK_15:
418 radio_str = "Ralink";
419 break;
420 case RADIO_RADIA_16:
421 radio_str = "Radia";
422 break;
423 case RADIO_UNKNOWN_17:
424 /* TI seems to have a radio which is
425 * additionally 802.11a capable, too */
426 radio_str = "802.11a/b/g radio?! Please report";
427 break;
428 case RADIO_UNKNOWN_19:
429 radio_str = "A radio used by Safecom cards?! Please report";
430 break;
431 case RADIO_UNKNOWN_1B:
432 radio_str = "An unknown radio used by TNETW1450 USB adapters";
433 break;
434 default:
435 radio_str = "UNKNOWN, please report radio type name!";
436 break;
439 switch (adev->form_factor) {
440 case 0x00:
441 form_str = "unspecified";
442 break;
443 case 0x01:
444 form_str = "(mini-)PCI / CardBus";
445 break;
446 case 0x02:
447 form_str = "USB";
448 break;
449 case 0x03:
450 form_str = "Compact Flash";
451 break;
452 default:
453 form_str = "UNKNOWN, please report";
454 break;
457 printk("acx: chipset %s, radio type 0x%02X (%s), "
458 "form factor 0x%02X (%s), EEPROM version 0x%02X, "
459 "uploaded firmware '%s'\n",
460 adev->chip_name, adev->radio_type, radio_str,
461 adev->form_factor, form_str, adev->eeprom_version,
462 adev->firmware_version);
464 FN_EXIT0;
468 /***********************************************************************
469 ** acx_e_get_stats, acx_e_get_wireless_stats
472 acx_e_get_stats(struct ieee80211_hw *hw,
473 struct ieee80211_low_level_stats *stats)
475 acx_device_t *adev = ieee2adev(hw);
476 unsigned long flags;
477 acx_lock(adev, flags);
478 memcpy(stats, &adev->ieee_stats, sizeof(*stats));
479 acx_unlock(adev, flags);
480 return 0;
484 /***********************************************************************
485 ** maps acx111 tx descr rate field to acx100 one
487 const u8 acx_bitpos2rate100[] = {
488 RATE100_1, /* 0 */
489 RATE100_2, /* 1 */
490 RATE100_5, /* 2 */
491 RATE100_2, /* 3, should not happen */
492 RATE100_2, /* 4, should not happen */
493 RATE100_11, /* 5 */
494 RATE100_2, /* 6, should not happen */
495 RATE100_2, /* 7, should not happen */
496 RATE100_22, /* 8 */
497 RATE100_2, /* 9, should not happen */
498 RATE100_2, /* 10, should not happen */
499 RATE100_2, /* 11, should not happen */
500 RATE100_2, /* 12, should not happen */
501 RATE100_2, /* 13, should not happen */
502 RATE100_2, /* 14, should not happen */
503 RATE100_2, /* 15, should not happen */
506 u8 acx_rate111to100(u16 r)
508 return acx_bitpos2rate100[highest_bit(r)];
512 /***********************************************************************
513 ** Calculate level like the feb 2003 windows driver seems to do
515 static u8 acx_signal_to_winlevel(u8 rawlevel)
517 /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
518 u8 winlevel = ((4 + (rawlevel * 5)) / 8);
520 if (winlevel > 100)
521 winlevel = 100;
522 return winlevel;
525 u8 acx_signal_determine_quality(u8 signal, u8 noise)
527 int qual;
529 qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2;
531 if (qual > 100)
532 return 100;
533 if (qual < 0)
534 return 0;
535 return qual;
539 /***********************************************************************
540 ** Interrogate/configure commands
543 /* FIXME: the lengths given here probably aren't always correct.
544 * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4",
545 * unless the firmware actually expects a different length than the struct length */
546 static const u16 acx100_ie_len[] = {
548 ACX100_IE_ACX_TIMER_LEN,
549 sizeof(acx100_ie_powersave_t) - 4, /* is that 6 or 8??? */
550 ACX1xx_IE_QUEUE_CONFIG_LEN,
551 ACX100_IE_BLOCK_SIZE_LEN,
552 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
553 ACX1xx_IE_RATE_FALLBACK_LEN,
554 ACX100_IE_WEP_OPTIONS_LEN,
555 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
557 ACX1xx_IE_ASSOC_ID_LEN,
559 ACX111_IE_CONFIG_OPTIONS_LEN,
560 ACX1xx_IE_FWREV_LEN,
561 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
562 ACX1xx_IE_MEDIUM_USAGE_LEN,
563 ACX1xx_IE_RXCONFIG_LEN,
566 sizeof(fw_stats_t) - 4,
568 ACX1xx_IE_FEATURE_CONFIG_LEN,
569 ACX111_IE_KEY_CHOOSE_LEN,
570 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
571 ACX1FF_IE_WONE_CONFIG_LEN,
573 ACX1FF_IE_TID_CONFIG_LEN,
577 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
578 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
579 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
580 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
582 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
583 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
584 ACX1FF_IE_CCA_THRESHOLD_LEN,
585 ACX1FF_IE_EVENT_MASK_LEN,
586 ACX1FF_IE_DTIM_PERIOD_LEN,
588 ACX1FF_IE_ACI_CONFIG_SET_LEN,
595 ACX1FF_IE_EEPROM_VER_LEN,
598 static const u16 acx100_ie_len_dot11[] = {
600 ACX1xx_IE_DOT11_STATION_ID_LEN,
602 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
603 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
604 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
605 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
606 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
607 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
609 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
610 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
612 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
613 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
614 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
615 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
621 static const u16 acx111_ie_len[] = {
623 ACX100_IE_ACX_TIMER_LEN,
624 sizeof(acx111_ie_powersave_t) - 4,
625 ACX1xx_IE_QUEUE_CONFIG_LEN,
626 ACX100_IE_BLOCK_SIZE_LEN,
627 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
628 ACX1xx_IE_RATE_FALLBACK_LEN,
629 ACX100_IE_WEP_OPTIONS_LEN,
630 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
632 ACX1xx_IE_ASSOC_ID_LEN,
634 ACX111_IE_CONFIG_OPTIONS_LEN,
635 ACX1xx_IE_FWREV_LEN,
636 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
637 ACX1xx_IE_MEDIUM_USAGE_LEN,
638 ACX1xx_IE_RXCONFIG_LEN,
641 sizeof(fw_stats_t) - 4,
643 ACX1xx_IE_FEATURE_CONFIG_LEN,
644 ACX111_IE_KEY_CHOOSE_LEN,
645 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
646 ACX1FF_IE_WONE_CONFIG_LEN,
648 ACX1FF_IE_TID_CONFIG_LEN,
652 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
653 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
654 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
655 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
657 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
658 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
659 ACX1FF_IE_CCA_THRESHOLD_LEN,
660 ACX1FF_IE_EVENT_MASK_LEN,
661 ACX1FF_IE_DTIM_PERIOD_LEN,
663 ACX1FF_IE_ACI_CONFIG_SET_LEN,
670 ACX1FF_IE_EEPROM_VER_LEN,
673 static const u16 acx111_ie_len_dot11[] = {
675 ACX1xx_IE_DOT11_STATION_ID_LEN,
677 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
678 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
679 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
680 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
681 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
682 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
684 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
685 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
687 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
688 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
689 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
690 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
697 #undef FUNC
698 #define FUNC "configure"
699 #if !ACX_DEBUG
700 int acx_s_configure(acx_device_t * adev, void *pdr, int type)
702 #else
704 acx_s_configure_debug(acx_device_t * adev, void *pdr, int type,
705 const char *typestr)
707 #endif
708 u16 len;
709 int res;
711 if (type < 0x1000)
712 len = adev->ie_len[type];
713 else
714 len = adev->ie_len_dot11[type - 0x1000];
716 log(L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
717 if (unlikely(!len)) {
718 log(L_DEBUG, "zero-length type %s?!\n", typestr);
721 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
722 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
723 res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4);
724 if (unlikely(OK != res)) {
725 #if ACX_DEBUG
726 printk("%s: " FUNC "(type:%s) FAILED\n", wiphy_name(adev->ieee->wiphy),
727 typestr);
728 #else
729 printk("%s: " FUNC "(type:0x%X) FAILED\n", wiphy_name(adev->ieee->wiphy),
730 type);
731 #endif
732 /* dump_stack() is already done in issue_cmd() */
734 return res;
737 #undef FUNC
738 #define FUNC "interrogate"
739 #if !ACX_DEBUG
740 int acx_s_interrogate(acx_device_t * adev, void *pdr, int type)
742 #else
744 acx_s_interrogate_debug(acx_device_t * adev, void *pdr, int type,
745 const char *typestr)
747 #endif
748 u16 len;
749 int res;
751 FN_ENTER;
753 /* FIXME: no check whether this exceeds the array yet.
754 * We should probably remember the number of entries... */
755 if (type < 0x1000)
756 len = adev->ie_len[type];
757 else
758 len = adev->ie_len_dot11[type - 0x1000];
760 log(L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
762 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
763 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
764 res = acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, pdr, len + 4);
765 if (unlikely(OK != res)) {
766 #if ACX_DEBUG
767 printk("%s: " FUNC "(type:%s) FAILED\n", wiphy_name(adev->ieee->wiphy),
768 typestr);
769 #else
770 printk("%s: " FUNC "(type:0x%X) FAILED\n", wiphy_name(adev->ieee->wiphy),
771 type);
772 #endif
773 /* dump_stack() is already done in issue_cmd() */
776 FN_EXIT1(res);
777 return res;
780 #if CMD_DISCOVERY
781 void great_inquisitor(acx_device_t * adev)
783 static struct {
784 u16 type;
785 u16 len;
786 /* 0x200 was too large here: */
787 u8 data[0x100 - 4];
788 } ACX_PACKED ie;
789 u16 type;
791 FN_ENTER;
793 /* 0..0x20, 0x1000..0x1020 */
794 for (type = 0; type <= 0x1020; type++) {
795 if (type == 0x21)
796 type = 0x1000;
797 ie.type = cpu_to_le16(type);
798 ie.len = cpu_to_le16(sizeof(ie) - 4);
799 acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie));
801 FN_EXIT0;
803 #endif
806 #ifdef CONFIG_PROC_FS
807 /***********************************************************************
808 ** /proc files
810 /***********************************************************************
811 ** acx_l_proc_output
812 ** Generate content for our /proc entry
814 ** Arguments:
815 ** buf is a pointer to write output to
816 ** adev is the usual pointer to our private struct acx_device
817 ** Returns:
818 ** number of bytes actually written to buf
819 ** Side effects:
820 ** none
822 static int acx_l_proc_output(char *buf, acx_device_t * adev)
824 char *p = buf;
826 FN_ENTER;
828 p += sprintf(p,
829 "acx driver version:\t\t" ACX_RELEASE "\n"
830 "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n"
831 "chip name:\t\t\t%s (0x%08X)\n"
832 "radio type:\t\t\t0x%02X\n"
833 "form factor:\t\t\t0x%02X\n"
834 "EEPROM version:\t\t\t0x%02X\n"
835 "firmware version:\t\t%s (0x%08X)\n",
836 adev->chip_name, adev->firmware_id,
837 adev->radio_type,
838 adev->form_factor,
839 adev->eeprom_version,
840 adev->firmware_version, adev->firmware_numver);
842 FN_EXIT1(p - buf);
843 return p - buf;
847 /***********************************************************************
849 static int acx_s_proc_diag_output(char *buf, acx_device_t * adev)
851 char *p = buf;
852 unsigned long flags;
853 unsigned int len = 0, partlen;
854 u32 temp1, temp2;
855 u8 *st, *st_end;
856 #ifdef __BIG_ENDIAN
857 u8 *st2;
858 #endif
859 fw_stats_t *fw_stats;
860 char *part_str = NULL;
861 fw_stats_tx_t *tx = NULL;
862 fw_stats_rx_t *rx = NULL;
863 fw_stats_dma_t *dma = NULL;
864 fw_stats_irq_t *irq = NULL;
865 fw_stats_wep_t *wep = NULL;
866 fw_stats_pwr_t *pwr = NULL;
867 fw_stats_mic_t *mic = NULL;
868 fw_stats_aes_t *aes = NULL;
869 fw_stats_event_t *evt = NULL;
871 FN_ENTER;
873 acx_lock(adev, flags);
875 if (IS_PCI(adev))
876 p = acxpci_s_proc_diag_output(p, adev);
878 p += sprintf(p,
879 "\n"
880 "** network status **\n"
881 "dev_state_mask 0x%04X\n"
882 "mode %u, channel %u, "
883 "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
884 adev->dev_state_mask,
885 adev->mode, adev->channel,
886 adev->reg_dom_id, adev->reg_dom_chanmask);
887 p += sprintf(p,
888 "ESSID \"%s\", essid_active %d, essid_len %d, "
889 "essid_for_assoc \"%s\", nick \"%s\"\n"
890 "WEP ena %d, restricted %d, idx %d\n",
891 adev->essid, adev->essid_active, (int)adev->essid_len,
892 adev->essid_for_assoc, adev->nick,
893 adev->wep_enabled, adev->wep_restricted,
894 adev->wep_current_index);
895 p += sprintf(p, "dev_addr " MACSTR "\n", MAC(adev->dev_addr));
896 p += sprintf(p, "bssid " MACSTR "\n", MAC(adev->bssid));
897 p += sprintf(p, "ap_filter " MACSTR "\n", MAC(adev->ap));
899 p += sprintf(p, "\n" "** PHY status **\n"
900 "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
901 "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
902 "rate_basic 0x%04X, rate_oper 0x%04X\n"
903 "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
904 "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
905 adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */
906 adev->sensitivity, adev->antenna, adev->ed_threshold,
907 adev->cca, adev->preamble_mode, adev->rate_basic, adev->rate_oper, adev->rts_threshold,
908 adev->frag_threshold, adev->short_retry, adev->long_retry,
909 adev->msdu_lifetime, adev->listen_interval,
910 adev->beacon_interval);
912 acx_unlock(adev, flags);
914 p += sprintf(p,
915 "\n"
916 "** Firmware **\n"
917 "NOTE: version dependent statistics layout, "
918 "please report if you suspect wrong parsing!\n"
919 "\n" "version \"%s\"\n", adev->firmware_version);
921 /* TODO: may replace kmalloc/memset with kzalloc once
922 * Linux 2.6.14 is widespread */
923 fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL);
924 if (!fw_stats) {
925 FN_EXIT1(0);
926 return 0;
928 memset(fw_stats, 0, sizeof(*fw_stats));
930 st = (u8 *) fw_stats;
932 part_str = "statistics query command";
934 if (OK != acx_s_interrogate(adev, st, ACX1xx_IE_FIRMWARE_STATISTICS))
935 goto fw_stats_end;
937 st += sizeof(u16);
938 len = *(u16 *) st;
940 if (len > sizeof(*fw_stats)) {
941 p += sprintf(p,
942 "firmware version with bigger fw_stats struct detected\n"
943 "(%u vs. %u), please report\n", len,
944 sizeof(fw_stats_t));
945 if (len > sizeof(*fw_stats)) {
946 p += sprintf(p, "struct size exceeded allocation!\n");
947 len = sizeof(*fw_stats);
950 st += sizeof(u16);
951 st_end = st - 2 * sizeof(u16) + len;
953 #ifdef __BIG_ENDIAN
954 /* let's make one bold assumption here:
955 * (hopefully!) *all* statistics fields are u32 only,
956 * thus if we need to make endianness corrections
957 * we can simply do them in one go, in advance */
958 st2 = (u8 *) fw_stats;
959 for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4)
960 *(u32 *) st2 = le32_to_cpu(*(u32 *) st2);
961 #endif
963 part_str = "Rx/Tx";
965 /* directly at end of a struct part? --> no error! */
966 if (st == st_end)
967 goto fw_stats_end;
969 tx = (fw_stats_tx_t *) st;
970 st += sizeof(fw_stats_tx_t);
971 rx = (fw_stats_rx_t *) st;
972 st += sizeof(fw_stats_rx_t);
973 partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t);
975 if (IS_ACX100(adev)) {
976 /* at least ACX100 PCI F/W 1.9.8.b
977 * and ACX100 USB F/W 1.0.7-USB
978 * don't have those two fields... */
979 st -= 2 * sizeof(u32);
981 /* our parsing doesn't quite match this firmware yet,
982 * log failure */
983 if (st > st_end)
984 goto fw_stats_fail;
985 temp1 = temp2 = 999999999;
986 } else {
987 if (st > st_end)
988 goto fw_stats_fail;
989 temp1 = rx->rx_aci_events;
990 temp2 = rx->rx_aci_resets;
993 p += sprintf(p,
994 "%s:\n"
995 " tx_desc_overfl %u\n"
996 " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
997 " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n"
998 " rx_aci_events %u, rx_aci_resets %u\n",
999 part_str,
1000 tx->tx_desc_of,
1001 rx->rx_oom,
1002 rx->rx_hdr_of,
1003 rx->rx_hw_stuck,
1004 rx->rx_dropped_frame,
1005 rx->rx_frame_ptr_err, rx->rx_xfr_hint_trig, temp1, temp2);
1007 part_str = "DMA";
1009 if (st == st_end)
1010 goto fw_stats_end;
1012 dma = (fw_stats_dma_t *) st;
1013 partlen = sizeof(fw_stats_dma_t);
1014 st += partlen;
1016 if (st > st_end)
1017 goto fw_stats_fail;
1019 p += sprintf(p,
1020 "%s:\n"
1021 " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n",
1022 part_str,
1023 dma->rx_dma_req,
1024 dma->rx_dma_err, dma->tx_dma_req, dma->tx_dma_err);
1026 part_str = "IRQ";
1028 if (st == st_end)
1029 goto fw_stats_end;
1031 irq = (fw_stats_irq_t *) st;
1032 partlen = sizeof(fw_stats_irq_t);
1033 st += partlen;
1035 if (st > st_end)
1036 goto fw_stats_fail;
1038 p += sprintf(p,
1039 "%s:\n"
1040 " cmd_cplt %u, fiq %u\n"
1041 " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
1042 " irqs %u, tx_procs %u, decrypt_done %u\n"
1043 " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
1044 " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
1045 " host_acks %u, pci_pm %u, acm_wakeups %u\n",
1046 part_str,
1047 irq->cmd_cplt,
1048 irq->fiq,
1049 irq->rx_hdrs,
1050 irq->rx_cmplt,
1051 irq->rx_mem_of,
1052 irq->rx_rdys,
1053 irq->irqs,
1054 irq->tx_procs,
1055 irq->decrypt_done,
1056 irq->dma_0_done,
1057 irq->dma_1_done,
1058 irq->tx_exch_complet,
1059 irq->commands,
1060 irq->rx_procs,
1061 irq->hw_pm_mode_changes,
1062 irq->host_acks, irq->pci_pm, irq->acm_wakeups);
1064 part_str = "WEP";
1066 if (st == st_end)
1067 goto fw_stats_end;
1069 wep = (fw_stats_wep_t *) st;
1070 partlen = sizeof(fw_stats_wep_t);
1071 st += partlen;
1073 if ((IS_PCI(adev) && IS_ACX100(adev))
1074 || (IS_USB(adev) && IS_ACX100(adev))
1076 /* at least ACX100 PCI F/W 1.9.8.b
1077 * and ACX100 USB F/W 1.0.7-USB
1078 * don't have those two fields... */
1079 st -= 2 * sizeof(u32);
1080 if (st > st_end)
1081 goto fw_stats_fail;
1082 temp1 = temp2 = 999999999;
1083 } else {
1084 if (st > st_end)
1085 goto fw_stats_fail;
1086 temp1 = wep->wep_pkt_decrypt;
1087 temp2 = wep->wep_decrypt_irqs;
1090 p += sprintf(p,
1091 "%s:\n"
1092 " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
1093 " wep_key_not_found %u, wep_decrypt_fail %u\n"
1094 " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
1095 part_str,
1096 wep->wep_key_count,
1097 wep->wep_default_key_count,
1098 wep->dot11_def_key_mib,
1099 wep->wep_key_not_found,
1100 wep->wep_decrypt_fail, temp1, temp2);
1102 part_str = "power";
1104 if (st == st_end)
1105 goto fw_stats_end;
1107 pwr = (fw_stats_pwr_t *) st;
1108 partlen = sizeof(fw_stats_pwr_t);
1109 st += partlen;
1111 if (st > st_end)
1112 goto fw_stats_fail;
1114 p += sprintf(p,
1115 "%s:\n"
1116 " tx_start_ctr %u, no_ps_tx_too_short %u\n"
1117 " rx_start_ctr %u, no_ps_rx_too_short %u\n"
1118 " lppd_started %u\n"
1119 " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n",
1120 part_str,
1121 pwr->tx_start_ctr,
1122 pwr->no_ps_tx_too_short,
1123 pwr->rx_start_ctr,
1124 pwr->no_ps_rx_too_short,
1125 pwr->lppd_started,
1126 pwr->no_lppd_too_noisy,
1127 pwr->no_lppd_too_short, pwr->no_lppd_matching_frame);
1129 part_str = "MIC";
1131 if (st == st_end)
1132 goto fw_stats_end;
1134 mic = (fw_stats_mic_t *) st;
1135 partlen = sizeof(fw_stats_mic_t);
1136 st += partlen;
1138 if (st > st_end)
1139 goto fw_stats_fail;
1141 p += sprintf(p,
1142 "%s:\n"
1143 " mic_rx_pkts %u, mic_calc_fail %u\n",
1144 part_str, mic->mic_rx_pkts, mic->mic_calc_fail);
1146 part_str = "AES";
1148 if (st == st_end)
1149 goto fw_stats_end;
1151 aes = (fw_stats_aes_t *) st;
1152 partlen = sizeof(fw_stats_aes_t);
1153 st += partlen;
1155 if (st > st_end)
1156 goto fw_stats_fail;
1158 p += sprintf(p,
1159 "%s:\n"
1160 " aes_enc_fail %u, aes_dec_fail %u\n"
1161 " aes_enc_pkts %u, aes_dec_pkts %u\n"
1162 " aes_enc_irq %u, aes_dec_irq %u\n",
1163 part_str,
1164 aes->aes_enc_fail,
1165 aes->aes_dec_fail,
1166 aes->aes_enc_pkts,
1167 aes->aes_dec_pkts, aes->aes_enc_irq, aes->aes_dec_irq);
1169 part_str = "event";
1171 if (st == st_end)
1172 goto fw_stats_end;
1174 evt = (fw_stats_event_t *) st;
1175 partlen = sizeof(fw_stats_event_t);
1176 st += partlen;
1178 if (st > st_end)
1179 goto fw_stats_fail;
1181 p += sprintf(p,
1182 "%s:\n"
1183 " heartbeat %u, calibration %u\n"
1184 " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
1185 " oom_late %u\n"
1186 " phy_tx_err %u, tx_stuck %u\n",
1187 part_str,
1188 evt->heartbeat,
1189 evt->calibration,
1190 evt->rx_mismatch,
1191 evt->rx_mem_empty,
1192 evt->rx_pool,
1193 evt->oom_late, evt->phy_tx_err, evt->tx_stuck);
1195 if (st < st_end)
1196 goto fw_stats_bigger;
1198 goto fw_stats_end;
1200 fw_stats_fail:
1201 st -= partlen;
1202 p += sprintf(p,
1203 "failed at %s part (size %u), offset %u (struct size %u), "
1204 "please report\n", part_str, partlen,
1205 (int)((void *)st - (void *)fw_stats), len);
1207 fw_stats_bigger:
1208 for (; st < st_end; st += 4)
1209 p += sprintf(p,
1210 "UNKN%3d: %u\n",
1211 (int)((void *)st - (void *)fw_stats), *(u32 *) st);
1213 fw_stats_end:
1214 kfree(fw_stats);
1216 FN_EXIT1(p - buf);
1217 return p - buf;
1221 /***********************************************************************
1223 static int acx_s_proc_phy_output(char *buf, acx_device_t * adev)
1225 char *p = buf;
1226 int i;
1228 FN_ENTER;
1231 if (RADIO_RFMD_11 != adev->radio_type) {
1232 printk("sorry, not yet adapted for radio types "
1233 "other than RFMD, please verify "
1234 "PHY size etc. first!\n");
1235 goto end;
1239 /* The PHY area is only 0x80 bytes long; further pages after that
1240 * only have some page number registers with altered value,
1241 * all other registers remain the same. */
1242 for (i = 0; i < 0x80; i++) {
1243 acx_s_read_phy_reg(adev, i, p++);
1246 FN_EXIT1(p - buf);
1247 return p - buf;
1251 /***********************************************************************
1252 ** acx_e_read_proc_XXXX
1253 ** Handle our /proc entry
1255 ** Arguments:
1256 ** standard kernel read_proc interface
1257 ** Returns:
1258 ** number of bytes written to buf
1259 ** Side effects:
1260 ** none
1262 static int
1263 acx_e_read_proc(char *buf, char **start, off_t offset, int count,
1264 int *eof, void *data)
1266 acx_device_t *adev = (acx_device_t *) data;
1267 unsigned long flags;
1268 int length;
1270 FN_ENTER;
1272 acx_sem_lock(adev);
1273 acx_lock(adev, flags);
1274 /* fill buf */
1275 length = acx_l_proc_output(buf, adev);
1276 acx_unlock(adev, flags);
1277 acx_sem_unlock(adev);
1279 /* housekeeping */
1280 if (length <= offset + count)
1281 *eof = 1;
1282 *start = buf + offset;
1283 length -= offset;
1284 if (length > count)
1285 length = count;
1286 if (length < 0)
1287 length = 0;
1288 FN_EXIT1(length);
1289 return length;
1292 static int
1293 acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count,
1294 int *eof, void *data)
1296 acx_device_t *adev = (acx_device_t *) data;
1297 int length;
1299 FN_ENTER;
1301 acx_sem_lock(adev);
1302 /* fill buf */
1303 length = acx_s_proc_diag_output(buf, adev);
1304 acx_sem_unlock(adev);
1306 /* housekeeping */
1307 if (length <= offset + count)
1308 *eof = 1;
1309 *start = buf + offset;
1310 length -= offset;
1311 if (length > count)
1312 length = count;
1313 if (length < 0)
1314 length = 0;
1315 FN_EXIT1(length);
1316 return length;
1319 static int
1320 acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count,
1321 int *eof, void *data)
1323 acx_device_t *adev = (acx_device_t *) data;
1324 int length;
1326 FN_ENTER;
1328 /* fill buf */
1329 length = 0;
1330 if (IS_PCI(adev)) {
1331 acx_sem_lock(adev);
1332 length = acxpci_proc_eeprom_output(buf, adev);
1333 acx_sem_unlock(adev);
1336 /* housekeeping */
1337 if (length <= offset + count)
1338 *eof = 1;
1339 *start = buf + offset;
1340 length -= offset;
1341 if (length > count)
1342 length = count;
1343 if (length < 0)
1344 length = 0;
1345 FN_EXIT1(length);
1346 return length;
1349 static int
1350 acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count,
1351 int *eof, void *data)
1353 acx_device_t *adev = (acx_device_t *) data;
1354 int length;
1356 FN_ENTER;
1358 acx_sem_lock(adev);
1359 /* fill buf */
1360 length = acx_s_proc_phy_output(buf, adev);
1361 acx_sem_unlock(adev);
1363 /* housekeeping */
1364 if (length <= offset + count)
1365 *eof = 1;
1366 *start = buf + offset;
1367 length -= offset;
1368 if (length > count)
1369 length = count;
1370 if (length < 0)
1371 length = 0;
1372 FN_EXIT1(length);
1373 return length;
1377 /***********************************************************************
1378 ** /proc files registration
1380 static const char *const
1381 proc_files[] = { "", "_diag", "_eeprom", "_phy" };
1383 static read_proc_t *const
1384 proc_funcs[] = {
1385 acx_e_read_proc,
1386 acx_e_read_proc_diag,
1387 acx_e_read_proc_eeprom,
1388 acx_e_read_proc_phy
1391 static int manage_proc_entries(struct ieee80211_hw *hw, int remove)
1393 acx_device_t *adev = ieee2adev(hw);
1394 char procbuf[80];
1395 int i;
1397 FN_ENTER;
1399 for (i = 0; i < ARRAY_SIZE(proc_files); i++) {
1400 snprintf(procbuf, sizeof(procbuf),
1401 "driver/acx_%s", proc_files[i]);
1402 log(L_INIT, "%sing /proc entry %s\n",
1403 remove ? "remov" : "creat", procbuf);
1404 if (!remove) {
1405 if (!create_proc_read_entry
1406 (procbuf, 0, NULL, proc_funcs[i], adev)) {
1407 printk("acx: cannot register /proc entry %s\n",
1408 procbuf);
1409 FN_EXIT1(NOT_OK);
1410 return NOT_OK;
1412 } else {
1413 remove_proc_entry(procbuf, NULL);
1416 FN_EXIT0;
1417 return OK;
1420 int acx_proc_register_entries(struct ieee80211_hw *ieee)
1422 return manage_proc_entries(ieee, 0);
1425 int acx_proc_unregister_entries(struct ieee80211_hw *ieee)
1427 return manage_proc_entries(ieee, 1);
1429 #endif /* CONFIG_PROC_FS */
1431 /****
1432 ** Gathered From rt2x00 and bcm43xx_mac80211 projects
1434 void acx_free_modes(acx_device_t * adev)
1437 // kfree(adev->modes);
1438 // adev->modes = NULL;
1441 #define RATETAB_ENT(_rate, _rateid, _flags) \
1443 .rate = (_rate), \
1444 .val = (_rateid), \
1445 .val2 = (_rateid), \
1446 .flags = (_flags), \
1450 static struct ieee80211_rate __acx_ratetable[] = {
1451 RATETAB_ENT(10, RATE111_1, IEEE80211_RATE_CCK),
1452 RATETAB_ENT(20, RATE111_2, IEEE80211_RATE_CCK_2),
1453 RATETAB_ENT(55, RATE111_5, IEEE80211_RATE_CCK_2),
1454 RATETAB_ENT(110, RATE111_11, IEEE80211_RATE_CCK_2),
1455 RATETAB_ENT(60, RATE111_6, IEEE80211_RATE_OFDM),
1456 RATETAB_ENT(90, RATE111_9, IEEE80211_RATE_OFDM),
1457 RATETAB_ENT(120, RATE111_12, IEEE80211_RATE_OFDM),
1458 RATETAB_ENT(180, RATE111_18, IEEE80211_RATE_OFDM),
1459 RATETAB_ENT(240, RATE111_24, IEEE80211_RATE_OFDM),
1460 RATETAB_ENT(360, RATE111_36, IEEE80211_RATE_OFDM),
1461 RATETAB_ENT(480, RATE111_48, IEEE80211_RATE_OFDM),
1462 RATETAB_ENT(540, RATE111_54, IEEE80211_RATE_OFDM),
1465 #define acx_b_ratetable (__acx_ratetable + 0)
1466 #define acx_b_ratetable_size 4
1467 #define acx_g_ratetable (__acx_ratetable + 0)
1468 #define acx_g_ratetable_size 12
1470 #define CHANTAB_ENT(_chanid, _freq) \
1472 .chan = (_chanid), \
1473 .freq = (_freq), \
1474 .val = (_chanid), \
1475 .flag = IEEE80211_CHAN_W_SCAN | \
1476 IEEE80211_CHAN_W_ACTIVE_SCAN | \
1477 IEEE80211_CHAN_W_IBSS, \
1478 .power_level = 0xf, \
1479 .antenna_max = 0xFF, \
1481 static struct ieee80211_channel channels[] = {
1482 CHANTAB_ENT(1, 2412),
1483 CHANTAB_ENT(2, 2417),
1484 CHANTAB_ENT(3, 2422),
1485 CHANTAB_ENT(4, 2427),
1486 CHANTAB_ENT(5, 2432),
1487 CHANTAB_ENT(6, 2437),
1488 CHANTAB_ENT(7, 2442),
1489 CHANTAB_ENT(8, 2447),
1490 CHANTAB_ENT(9, 2452),
1491 CHANTAB_ENT(10, 2457),
1492 CHANTAB_ENT(11, 2462),
1493 CHANTAB_ENT(12, 2467),
1494 CHANTAB_ENT(13, 2472),
1497 #define acx_chantable_size ARRAY_SIZE(channels)
1499 static int acx_setup_modes_bphy(acx_device_t * adev)
1501 int err = 0;
1502 struct ieee80211_hw *hw = adev->ieee;
1503 struct ieee80211_hw_mode *mode;
1505 FN_ENTER;
1507 mode = &adev->modes[0];
1508 mode->mode = MODE_IEEE80211B;
1509 mode->num_channels = acx_chantable_size;
1510 mode->channels = channels;
1511 mode->num_rates = acx_b_ratetable_size;
1512 mode->rates = acx_b_ratetable;
1513 err = ieee80211_register_hwmode(hw,mode);
1515 FN_EXIT1(err);
1517 return err;
1520 static int acx_setup_modes_gphy(acx_device_t * adev)
1522 int err = 0;
1523 struct ieee80211_hw *hw = adev->ieee;
1524 struct ieee80211_hw_mode *mode;
1526 FN_ENTER;
1528 mode = &adev->modes[1];
1529 mode->mode = MODE_IEEE80211G;
1530 mode->num_channels = acx_chantable_size;
1531 mode->channels = channels;
1532 mode->num_rates = acx_g_ratetable_size;
1533 mode->rates = acx_g_ratetable;
1534 err = ieee80211_register_hwmode(hw,mode);
1536 FN_EXIT1(err);
1538 return err;
1541 int acx_setup_modes(acx_device_t * adev)
1543 int err = -ENOMEM;
1545 FN_ENTER;
1547 if (IS_ACX111(adev)) {
1548 /* adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);*/
1549 err = acx_setup_modes_gphy(adev);
1550 }/* else {
1551 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1553 err = acx_setup_modes_bphy(adev);
1554 /* if (err && adev->modes)
1555 kfree(adev->modes);*/
1556 FN_EXIT1(err);
1557 return err;
1561 /***********************************************************************
1562 ** acx_fill_beacon_or_proberesp_template
1564 ** Origin: derived from rt2x00 project
1566 static int
1567 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1568 struct acx_template_beacon *templ,
1569 struct sk_buff* skb /* in host order! */)
1571 FN_ENTER;
1573 memcpy(templ,skb->data, skb->len);
1574 FN_EXIT1(skb->len);
1575 return skb->len;
1578 /***********************************************************************
1579 ** acx_s_set_beacon_template
1583 static int
1584 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1586 struct acx_template_beacon bcn;
1587 int len, result;
1589 FN_ENTER;
1590 printk("Size of template: %08X, Size of beacon: %08X\n",sizeof(struct acx_template_beacon),skb->len);
1591 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1592 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1594 FN_EXIT1(result);
1595 return result;
1598 /***********************************************************************
1599 ** acx_cmd_join_bssid
1601 ** Common code for both acx100 and acx111.
1603 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1604 static const u8 bitpos2genframe_txrate[] = {
1605 10, /* 0. 1 Mbit/s */
1606 20, /* 1. 2 Mbit/s */
1607 55, /* 2. 5.5 Mbit/s */
1608 0x0B, /* 3. 6 Mbit/s */
1609 0x0F, /* 4. 9 Mbit/s */
1610 110, /* 5. 11 Mbit/s */
1611 0x0A, /* 6. 12 Mbit/s */
1612 0x0E, /* 7. 18 Mbit/s */
1613 220, /* 8. 22 Mbit/s */
1614 0x09, /* 9. 24 Mbit/s */
1615 0x0D, /* 10. 36 Mbit/s */
1616 0x08, /* 11. 48 Mbit/s */
1617 0x0C, /* 12. 54 Mbit/s */
1618 10, /* 13. 1 Mbit/s, should never happen */
1619 10, /* 14. 1 Mbit/s, should never happen */
1620 10, /* 15. 1 Mbit/s, should never happen */
1623 /* Looks scary, eh?
1624 ** Actually, each one compiled into one AND and one SHIFT,
1625 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1626 static inline unsigned int rate111to5bits(unsigned int rate)
1628 return (rate & 0x7)
1629 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1630 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1634 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1636 acx_joinbss_t tmp;
1637 int dtim_interval;
1638 int i;
1640 if (mac_is_zero(bssid))
1641 return;
1643 FN_ENTER;
1645 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1646 1 : adev->dtim_interval;
1648 memset(&tmp, 0, sizeof(tmp));
1650 for (i = 0; i < ETH_ALEN; i++) {
1651 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1654 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1656 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1657 ** are sent with one of these rates */
1658 if (IS_ACX111(adev)) {
1659 /* It was experimentally determined that rates_basic
1660 ** can take 11g rates as well, not only rates
1661 ** defined with JOINBSS_RATES_BASIC111_nnn.
1662 ** Just use RATE111_nnn constants... */
1663 tmp.u.acx111.dtim_interval = dtim_interval;
1664 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1665 log(L_ASSOC, "rates_basic:%04X, rates_supported:%04X\n",
1666 adev->rate_basic, adev->rate_oper);
1667 } else {
1668 tmp.u.acx100.dtim_interval = dtim_interval;
1669 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1670 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1671 log(L_ASSOC, "rates_basic:%04X->%02X, "
1672 "rates_supported:%04X->%02X\n",
1673 adev->rate_basic, tmp.u.acx100.rates_basic,
1674 adev->rate_oper, tmp.u.acx100.rates_supported);
1677 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1678 ** will be sent (rate/modulation/preamble) */
1679 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1680 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1681 /* we can use short pre *if* all peers can understand it */
1682 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1684 /* we switch fw to STA mode in MONITOR mode, it seems to be
1685 ** the only mode where fw does not emit beacons by itself
1686 ** but allows us to send anything (we really want to retain
1687 ** ability to tx arbitrary frames in MONITOR mode)
1689 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1690 tmp.channel = adev->channel;
1691 tmp.essid_len = adev->essid_len;
1693 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1694 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1696 log(L_ASSOC|L_DEBUG, "BSS_Type = %u\n", tmp.macmode);
1697 acxlog_mac(L_ASSOC|L_DEBUG, "JoinBSSID MAC:", adev->bssid, "\n");
1699 /* acx_update_capabilities(adev); */
1700 FN_EXIT0;
1703 /***********************************************************************
1704 ** acxpci_i_set_multicast_list
1705 ** FIXME: most likely needs refinement
1707 void
1708 acx_i_set_multicast_list(struct ieee80211_hw *hw,
1709 unsigned short netflags, int mc_count)
1711 acx_device_t *adev = ieee2adev(hw);
1712 unsigned long flags;
1714 FN_ENTER;
1716 acx_lock(adev, flags);
1718 /* firmwares don't have allmulti capability,
1719 * so just use promiscuous mode instead in this case. */
1720 if (netflags & (IFF_PROMISC | IFF_ALLMULTI)) {
1721 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1722 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1723 SET_BIT(adev->set_mask, SET_RXCONFIG);
1724 /* let kernel know in case *we* needed to set promiscuous */
1725 } else {
1726 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1727 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1728 SET_BIT(adev->set_mask, SET_RXCONFIG);
1731 /* cannot update card settings directly here, atomic context */
1732 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
1734 acx_unlock(adev, flags);
1736 FN_EXIT0;
1739 /***********************************************************************
1740 ** acx111 feature config
1742 ** Obvious
1744 static int
1745 acx111_s_get_feature_config(acx_device_t * adev,
1746 u32 * feature_options, u32 * data_flow_options)
1748 struct acx111_ie_feature_config feat;
1750 FN_ENTER;
1752 if (!IS_ACX111(adev)) {
1753 return NOT_OK;
1756 memset(&feat, 0, sizeof(feat));
1758 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1759 FN_EXIT1(NOT_OK);
1760 return NOT_OK;
1762 log(L_DEBUG,
1763 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1764 feat.feature_options, feat.data_flow_options);
1766 if (feature_options)
1767 *feature_options = le32_to_cpu(feat.feature_options);
1768 if (data_flow_options)
1769 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1771 FN_EXIT0;
1772 return OK;
1776 static int
1777 acx111_s_set_feature_config(acx_device_t * adev,
1778 u32 feature_options, u32 data_flow_options,
1779 unsigned int mode
1780 /* 0 == remove, 1 == add, 2 == set */ )
1782 struct acx111_ie_feature_config feat;
1784 FN_ENTER;
1786 if (!IS_ACX111(adev)) {
1787 FN_EXIT1(NOT_OK);
1788 return NOT_OK;
1791 if ((mode < 0) || (mode > 2)) {
1792 FN_EXIT1(NOT_OK);
1793 return NOT_OK;
1796 if (mode != 2)
1797 /* need to modify old data */
1798 acx111_s_get_feature_config(adev, &feat.feature_options,
1799 &feat.data_flow_options);
1800 else {
1801 /* need to set a completely new value */
1802 feat.feature_options = 0;
1803 feat.data_flow_options = 0;
1806 if (mode == 0) { /* remove */
1807 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1808 CLEAR_BIT(feat.data_flow_options,
1809 cpu_to_le32(data_flow_options));
1810 } else { /* add or set */
1811 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1812 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1815 log(L_DEBUG,
1816 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1817 "new: feature 0x%08X dataflow 0x%08X\n",
1818 feature_options, data_flow_options, mode,
1819 le32_to_cpu(feat.feature_options),
1820 le32_to_cpu(feat.data_flow_options));
1822 if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1823 FN_EXIT1(NOT_OK);
1824 return NOT_OK;
1827 FN_EXIT0;
1828 return OK;
1831 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1833 return acx111_s_set_feature_config(adev, f, d, 0);
1835 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1837 return acx111_s_set_feature_config(adev, f, d, 1);
1839 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1841 return acx111_s_set_feature_config(adev, f, d, 2);
1845 /***********************************************************************
1846 ** acx100_s_init_memory_pools
1848 static int
1849 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1851 acx100_ie_memblocksize_t MemoryBlockSize;
1852 acx100_ie_memconfigoption_t MemoryConfigOption;
1853 int TotalMemoryBlocks;
1854 int RxBlockNum;
1855 int TotalRxBlockSize;
1856 int TxBlockNum;
1857 int TotalTxBlockSize;
1859 FN_ENTER;
1861 /* Let's see if we can follow this:
1862 first we select our memory block size (which I think is
1863 completely arbitrary) */
1864 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1866 /* Then we alert the card to our decision of block size */
1867 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
1868 goto bad;
1871 /* We figure out how many total blocks we can create, using
1872 the block size we chose, and the beginning and ending
1873 memory pointers, i.e.: end-start/size */
1874 TotalMemoryBlocks =
1875 (le32_to_cpu(mmt->PoolEnd) -
1876 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1878 log(L_DEBUG, "TotalMemoryBlocks=%u (%u bytes)\n",
1879 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1881 /* MemoryConfigOption.DMA_config bitmask:
1882 access to ACX memory is to be done:
1883 0x00080000 using PCI conf space?!
1884 0x00040000 using IO instructions?
1885 0x00000000 using memory access instructions
1886 0x00020000 using local memory block linked list (else what?)
1887 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1889 if (IS_PCI(adev)) {
1890 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1891 /* Declare start of the Rx host pool */
1892 MemoryConfigOption.pRxHostDesc =
1893 cpu2acx(adev->rxhostdesc_startphy);
1894 log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
1895 acx2cpu(MemoryConfigOption.pRxHostDesc),
1896 (long)adev->rxhostdesc_startphy);
1897 } else {
1898 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1901 /* 50% of the allotment of memory blocks go to tx descriptors */
1902 TxBlockNum = TotalMemoryBlocks / 2;
1903 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1905 /* and 50% go to the rx descriptors */
1906 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1907 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1909 /* size of the tx and rx descriptor queues */
1910 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1911 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1912 log(L_DEBUG, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u "
1913 "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum,
1914 TotalTxBlockSize, TotalRxBlockSize);
1917 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1918 MemoryConfigOption.rx_mem =
1919 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1921 /* align the rx descriptor queue to units of 0x20
1922 * and offset it by the tx descriptor queue */
1923 MemoryConfigOption.tx_mem =
1924 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
1925 0x1f) & ~0x1f);
1926 log(L_DEBUG, "rx_mem %08X rx_mem %08X\n", MemoryConfigOption.tx_mem,
1927 MemoryConfigOption.rx_mem);
1929 /* alert the device to our decision */
1930 if (OK !=
1931 acx_s_configure(adev, &MemoryConfigOption,
1932 ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
1933 goto bad;
1936 /* and tell the device to kick it into gear */
1937 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
1938 goto bad;
1940 FN_EXIT1(OK);
1941 return OK;
1942 bad:
1943 FN_EXIT1(NOT_OK);
1944 return NOT_OK;
1948 /***********************************************************************
1949 ** acx100_s_create_dma_regions
1951 ** Note that this fn messes up heavily with hardware, but we cannot
1952 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1954 static int acx100_s_create_dma_regions(acx_device_t * adev)
1956 acx100_ie_queueconfig_t queueconf;
1957 acx_ie_memmap_t memmap;
1958 int res = NOT_OK;
1959 u32 tx_queue_start, rx_queue_start;
1961 FN_ENTER;
1963 /* read out the acx100 physical start address for the queues */
1964 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1965 goto fail;
1968 tx_queue_start = le32_to_cpu(memmap.QueueStart);
1969 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
1971 log(L_DEBUG, "initializing Queue Indicator\n");
1973 memset(&queueconf, 0, sizeof(queueconf));
1975 /* Not needed for PCI, so we can avoid setting them altogether */
1976 if (IS_USB(adev)) {
1977 queueconf.NumTxDesc = USB_TX_CNT;
1978 queueconf.NumRxDesc = USB_RX_CNT;
1981 /* calculate size of queues */
1982 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
1983 RX_CNT * sizeof(rxdesc_t) + 8);
1984 queueconf.NumTxQueues = 1; /* number of tx queues */
1985 /* sets the beginning of the tx descriptor queue */
1986 queueconf.TxQueueStart = memmap.QueueStart;
1987 /* done by memset: queueconf.TxQueuePri = 0; */
1988 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
1989 queueconf.QueueOptions = 1; /* auto reset descriptor */
1990 /* sets the end of the rx descriptor queue */
1991 queueconf.QueueEnd =
1992 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
1994 /* sets the beginning of the next queue */
1995 queueconf.HostQueueEnd =
1996 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
1997 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
1998 goto fail;
2001 if (IS_PCI(adev)) {
2002 /* sets the beginning of the rx descriptor queue, after the tx descrs */
2003 if (OK != acxpci_s_create_hostdesc_queues(adev))
2004 goto fail;
2005 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2008 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2009 goto fail;
2012 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
2013 0x1f) & ~0x1f);
2015 if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2016 goto fail;
2019 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
2020 goto fail;
2023 res = OK;
2024 goto end;
2026 fail:
2027 acx_s_msleep(1000); /* ? */
2028 if (IS_PCI(adev))
2029 acxpci_free_desc_queues(adev);
2030 end:
2031 FN_EXIT1(res);
2032 return res;
2036 /***********************************************************************
2037 ** acx111_s_create_dma_regions
2039 ** Note that this fn messes heavily with hardware, but we cannot
2040 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2042 #define ACX111_PERCENT(percent) ((percent)/5)
2044 static int acx111_s_create_dma_regions(acx_device_t * adev)
2046 struct acx111_ie_memoryconfig memconf;
2047 struct acx111_ie_queueconfig queueconf;
2048 u32 tx_queue_start, rx_queue_start;
2050 FN_ENTER;
2052 /* Calculate memory positions and queue sizes */
2054 /* Set up our host descriptor pool + data pool */
2055 if (IS_PCI(adev)) {
2056 if (OK != acxpci_s_create_hostdesc_queues(adev))
2057 goto fail;
2060 memset(&memconf, 0, sizeof(memconf));
2061 /* the number of STAs (STA contexts) to support
2062 ** NB: was set to 1 and everything seemed to work nevertheless... */
2063 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
2064 /* specify the memory block size. Default is 256 */
2065 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
2066 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
2067 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
2068 /* set the count of our queues
2069 ** NB: struct acx111_ie_memoryconfig shall be modified
2070 ** if we ever will switch to more than one rx and/or tx queue */
2071 memconf.count_rx_queues = 1;
2072 memconf.count_tx_queues = 1;
2073 /* 0 == Busmaster Indirect Memory Organization, which is what we want
2074 * (using linked host descs with their allocated mem).
2075 * 2 == Generic Bus Slave */
2076 /* done by memset: memconf.options = 0; */
2077 /* let's use 25% for fragmentations and 75% for frame transfers
2078 * (specified in units of 5%) */
2079 memconf.fragmentation = ACX111_PERCENT(75);
2080 /* Rx descriptor queue config */
2081 memconf.rx_queue1_count_descs = RX_CNT;
2082 memconf.rx_queue1_type = 7; /* must be set to 7 */
2083 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2084 if (IS_PCI(adev)) {
2085 memconf.rx_queue1_host_rx_start =
2086 cpu2acx(adev->rxhostdesc_startphy);
2088 /* Tx descriptor queue config */
2089 memconf.tx_queue1_count_descs = TX_CNT;
2090 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2092 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
2093 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2094 ** But it is actually correct wrt IE numbers.
2095 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
2096 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2097 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2098 if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
2099 goto fail;
2102 acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
2104 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2105 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2107 log(L_INIT, "dump queue head (from card):\n"
2108 "len: %u\n"
2109 "tx_memory_block_address: %X\n"
2110 "rx_memory_block_address: %X\n"
2111 "tx1_queue address: %X\n"
2112 "rx1_queue address: %X\n",
2113 le16_to_cpu(queueconf.len),
2114 le32_to_cpu(queueconf.tx_memory_block_address),
2115 le32_to_cpu(queueconf.rx_memory_block_address),
2116 tx_queue_start, rx_queue_start);
2118 if (IS_PCI(adev))
2119 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2121 FN_EXIT1(OK);
2122 return OK;
2123 fail:
2124 if (IS_PCI(adev))
2125 acxpci_free_desc_queues(adev);
2127 FN_EXIT1(NOT_OK);
2128 return NOT_OK;
2132 /***********************************************************************
2134 static void acx_s_initialize_rx_config(acx_device_t * adev)
2136 struct {
2137 u16 id;
2138 u16 len;
2139 u16 rx_cfg1;
2140 u16 rx_cfg2;
2141 } ACX_PACKED cfg;
2142 switch (adev->mode) {
2143 case ACX_MODE_MONITOR:
2144 adev->rx_config_1 = (u16) (0
2145 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2146 /* | RX_CFG1_FILTER_SSID */
2147 /* | RX_CFG1_FILTER_BCAST */
2148 /* | RX_CFG1_RCV_MC_ADDR1 */
2149 /* | RX_CFG1_RCV_MC_ADDR0 */
2150 /* | RX_CFG1_FILTER_ALL_MULTI */
2151 /* | RX_CFG1_FILTER_BSSID */
2152 /* | RX_CFG1_FILTER_MAC */
2153 | RX_CFG1_RCV_PROMISCUOUS
2154 | RX_CFG1_INCLUDE_FCS
2155 /* | RX_CFG1_INCLUDE_PHY_HDR */
2157 adev->rx_config_2 = (u16) (0
2158 | RX_CFG2_RCV_ASSOC_REQ
2159 | RX_CFG2_RCV_AUTH_FRAMES
2160 | RX_CFG2_RCV_BEACON_FRAMES
2161 | RX_CFG2_RCV_CONTENTION_FREE
2162 | RX_CFG2_RCV_CTRL_FRAMES
2163 | RX_CFG2_RCV_DATA_FRAMES
2164 | RX_CFG2_RCV_BROKEN_FRAMES
2165 | RX_CFG2_RCV_MGMT_FRAMES
2166 | RX_CFG2_RCV_PROBE_REQ
2167 | RX_CFG2_RCV_PROBE_RESP
2168 | RX_CFG2_RCV_ACK_FRAMES
2169 | RX_CFG2_RCV_OTHER);
2170 break;
2171 default:
2172 adev->rx_config_1 = (u16) (0
2173 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2174 /* | RX_CFG1_FILTER_SSID */
2175 /* | RX_CFG1_FILTER_BCAST */
2176 /* | RX_CFG1_RCV_MC_ADDR1 */
2177 /* | RX_CFG1_RCV_MC_ADDR0 */
2178 /* | RX_CFG1_FILTER_ALL_MULTI */
2179 /* | RX_CFG1_FILTER_BSSID */
2180 /* | RX_CFG1_FILTER_MAC */
2181 | RX_CFG1_RCV_PROMISCUOUS
2182 /* | RX_CFG1_INCLUDE_FCS */
2183 /* | RX_CFG1_INCLUDE_PHY_HDR */
2185 adev->rx_config_2 = (u16) (0
2186 | RX_CFG2_RCV_ASSOC_REQ
2187 | RX_CFG2_RCV_AUTH_FRAMES
2188 | RX_CFG2_RCV_BEACON_FRAMES
2189 | RX_CFG2_RCV_CONTENTION_FREE
2190 | RX_CFG2_RCV_CTRL_FRAMES
2191 | RX_CFG2_RCV_DATA_FRAMES
2192 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2193 | RX_CFG2_RCV_MGMT_FRAMES
2194 | RX_CFG2_RCV_PROBE_REQ
2195 | RX_CFG2_RCV_PROBE_RESP
2196 | RX_CFG2_RCV_ACK_FRAMES
2197 | RX_CFG2_RCV_OTHER);
2198 break;
2200 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2202 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2203 || (adev->firmware_numver >= 0x02000000))
2204 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2205 else
2206 adev->phy_header_len = 0;
2208 log(L_INIT, "setting RXconfig to %04X:%04X\n",
2209 adev->rx_config_1, adev->rx_config_2);
2210 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2211 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2212 acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
2216 /***********************************************************************
2217 ** acx_s_set_defaults
2219 void acx_s_set_defaults(acx_device_t * adev)
2221 unsigned long flags;
2223 FN_ENTER;
2225 acx_lock(adev, flags);
2226 /* do it before getting settings, prevent bogus channel 0 warning */
2227 adev->channel = 1;
2229 /* query some settings from the card.
2230 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2231 * query is REQUIRED, otherwise the card won't work correctly! */
2232 adev->get_mask =
2233 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2234 GETSET_REG_DOMAIN;
2235 /* Only ACX100 supports ED and CCA */
2236 if (IS_ACX100(adev))
2237 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2239 acx_s_update_card_settings(adev);
2242 /* set our global interrupt mask */
2243 if (IS_PCI(adev))
2244 acxpci_set_interrupt_mask(adev);
2246 adev->led_power = 1; /* LED is active on startup */
2247 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2248 adev->brange_time_last_state_change = jiffies;
2250 /* copy the MAC address we just got from the card
2251 * into our MAC address used during current 802.11 session */
2252 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
2253 MAC_BCAST(adev->ap);
2255 adev->essid_len =
2256 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2257 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2258 adev->essid_active = 1;
2260 /* we have a nick field to waste, so why not abuse it
2261 * to announce the driver version? ;-) */
2262 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2264 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2265 /* first regulatory domain entry in EEPROM == default reg. domain */
2266 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2269 /* 0xffff would be better, but then we won't get a "scan complete"
2270 * interrupt, so our current infrastructure will fail: */
2271 adev->scan_count = 1;
2272 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2273 adev->scan_duration = 100;
2274 adev->scan_probe_delay = 200;
2275 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2276 adev->scan_rate = ACX_SCAN_RATE_1;
2279 adev->mode = ACX_MODE_2_STA;
2280 adev->listen_interval = 100;
2281 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2282 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2284 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2286 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2287 adev->frag_threshold = 2346;
2289 /* use standard default values for retry limits */
2290 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2291 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2293 adev->preamble_mode = 2; /* auto */
2294 adev->fallback_threshold = 3;
2295 adev->stepup_threshold = 10;
2296 adev->rate_bcast = RATE111_1;
2297 adev->rate_bcast100 = RATE100_1;
2298 adev->rate_basic = RATE111_1 | RATE111_2;
2299 adev->rate_auto = 1;
2300 if (IS_ACX111(adev)) {
2301 adev->rate_oper = RATE111_ALL;
2302 } else {
2303 adev->rate_oper = RATE111_ACX100_COMPAT;
2306 /* Supported Rates element - the rates here are given in units of
2307 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2308 acx_l_update_ratevector(adev);
2310 /* set some more defaults */
2311 if (IS_ACX111(adev)) {
2312 /* 30mW (15dBm) is default, at least in my acx111 card: */
2313 adev->tx_level_dbm = 15;
2314 } else {
2315 /* don't use max. level, since it might be dangerous
2316 * (e.g. WRT54G people experience
2317 * excessive Tx power damage!) */
2318 adev->tx_level_dbm = 18;
2320 /* adev->tx_level_auto = 1; */
2321 if (IS_ACX111(adev)) {
2322 /* start with sensitivity level 1 out of 3: */
2323 adev->sensitivity = 1;
2326 /* #define ENABLE_POWER_SAVE */
2327 #ifdef ENABLE_POWER_SAVE
2328 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2329 adev->ps_listen_interval = 1;
2330 adev->ps_options =
2331 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2332 adev->ps_hangover_period = 30;
2333 adev->ps_enhanced_transition_time = 0;
2334 #else
2335 adev->ps_wakeup_cfg = 0;
2336 adev->ps_listen_interval = 0;
2337 adev->ps_options = 0;
2338 adev->ps_hangover_period = 0;
2339 adev->ps_enhanced_transition_time = 0;
2340 #endif
2342 /* These settings will be set in fw on ifup */
2343 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2344 /* configure card to do rate fallback when in auto rate mode */
2345 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2346 /* better re-init the antenna value we got above */
2347 | GETSET_ANTENNA
2348 #if POWER_SAVE_80211
2349 | GETSET_POWER_80211
2350 #endif
2353 acx_unlock(adev, flags);
2354 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2356 acx_s_initialize_rx_config(adev);
2358 FN_EXIT0;
2362 /***********************************************************************
2363 ** FIXME: this should be solved in a general way for all radio types
2364 ** by decoding the radio firmware module,
2365 ** since it probably has some standard structure describing how to
2366 ** set the power level of the radio module which it controls.
2367 ** Or maybe not, since the radio module probably has a function interface
2368 ** instead which then manages Tx level programming :-\
2370 ** Obvious
2372 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2374 struct acx111_ie_tx_level tx_level;
2376 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2377 * 1 (30mW) [15dBm]
2378 * 2 (10mW) [10dBm]
2379 * For now, just assume all other acx111 cards have the same.
2380 * FIXME: Ideally we would query it here, but we first need a
2381 * standard way to query individual configoptions easily.
2382 * Well, now we have proper cfgopt txpower variables, but this still
2383 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2384 if (level_dbm <= 12) {
2385 tx_level.level = 2; /* 10 dBm */
2386 adev->tx_level_dbm = 10;
2387 } else {
2388 tx_level.level = 1; /* 15 dBm */
2389 adev->tx_level_dbm = 15;
2391 /* if (level_dbm != adev->tx_level_dbm)
2392 log(L_INIT, "acx111 firmware has specific "
2393 "power levels only: adjusted %d dBm to %d dBm!\n",
2394 level_dbm, adev->tx_level_dbm);
2396 return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
2399 static int acx_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2401 if (IS_ACX111(adev)) {
2402 return acx111_s_set_tx_level(adev, level_dbm);
2404 if (IS_PCI(adev)) {
2405 return acx100pci_s_set_tx_level(adev, level_dbm);
2407 return OK;
2410 /***********************************************************************
2411 ** acx_l_process_rxbuf
2413 ** NB: used by USB code also
2415 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2417 struct ieee80211_hdr *hdr;
2418 u16 fc, buf_len;
2419 hdr = acx_get_wlan_hdr(adev, rxbuf);
2420 fc = le16_to_cpu(hdr->frame_control);
2421 /* length of frame from control field to first byte of FCS */
2422 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2424 if (unlikely(acx_debug & L_DATA)) {
2425 printk("rx: 802.11 buf[%u]: ", buf_len);
2426 acx_dump_bytes(hdr, buf_len);
2430 acx_l_rx(adev, rxbuf);
2431 /* Now check Rx quality level, AFTER processing packet.
2432 * I tried to figure out how to map these levels to dBm
2433 * values, but for the life of me I really didn't
2434 * manage to get it. Either these values are not meant to
2435 * be expressed in dBm, or it's some pretty complicated
2436 * calculation. */
2438 #ifdef FROM_SCAN_SOURCE_ONLY
2439 /* only consider packets originating from the MAC
2440 * address of the device that's managing our BSSID.
2441 * Disable it for now, since it removes information (levels
2442 * from different peers) and slows the Rx path. *//*
2443 if (adev->ap_client && mac_is_equal(hdr->a2, adev->ap_client->address)) {
2445 #endif
2449 /***********************************************************************
2450 ** acx_l_handle_txrate_auto
2452 ** Theory of operation:
2453 ** client->rate_cap is a bitmask of rates client is capable of.
2454 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2455 ** It is set as a result of iwconfig rate N [auto]
2456 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2457 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2458 ** auto (0x00ff == 18Mbit or any lower value),
2459 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2461 ** client->rate_cur is a value for rate111 field in tx descriptor.
2462 ** It is always set to txrate_cfg sans zero or more most significant
2463 ** bits. This routine handles selection of new rate_cur value depending on
2464 ** outcome of last tx event.
2466 ** client->rate_100 is a precalculated rate value for acx100
2467 ** (we can do without it, but will need to calculate it on each tx).
2469 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2470 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2471 ** In theory you can implement it, but so far it is considered not worth doing.
2473 ** 22Mbit, of course, is PBCC always. */
2475 /* maps acx100 tx descr rate field to acx111 one */
2477 static u16 rate100to111(u8 r)
2479 switch (r) {
2480 case RATE100_1:
2481 return RATE111_1;
2482 case RATE100_2:
2483 return RATE111_2;
2484 case RATE100_5:
2485 case (RATE100_5 | RATE100_PBCC511):
2486 return RATE111_5;
2487 case RATE100_11:
2488 case (RATE100_11 | RATE100_PBCC511):
2489 return RATE111_11;
2490 case RATE100_22:
2491 return RATE111_22;
2492 default:
2493 printk("acx: unexpected acx100 txrate: %u! "
2494 "Please report\n", r);
2495 return RATE111_1;
2502 acx_i_start_xmit(struct ieee80211_hw *hw,
2503 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2505 acx_device_t *adev = ieee2adev(hw);
2506 tx_t *tx;
2507 void *txbuf;
2508 unsigned long flags;
2510 int txresult = NOT_OK;
2512 FN_ENTER;
2514 if (unlikely(!skb)) {
2515 /* indicate success */
2516 txresult = OK;
2517 goto end_no_unlock;
2520 if (unlikely(!adev)) {
2521 goto end_no_unlock;
2525 acx_lock(adev, flags);
2527 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2528 goto end;
2530 if (unlikely(!adev->initialized)) {
2531 goto end;
2534 tx = acx_l_alloc_tx(adev);
2536 if (unlikely(!tx)) {
2537 printk_ratelimited("%s: start_xmit: txdesc ring is full, "
2538 "dropping tx\n", wiphy_name(adev->ieee->wiphy));
2539 txresult = NOT_OK;
2540 goto end;
2543 txbuf = acx_l_get_txbuf(adev, tx);
2545 if (unlikely(!txbuf)) {
2546 /* Card was removed */
2547 txresult = NOT_OK;
2548 acx_l_dealloc_tx(adev, tx);
2549 goto end;
2551 memcpy(txbuf, skb->data, skb->len);
2553 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2555 txresult = OK;
2556 adev->stats.tx_packets++;
2557 adev->stats.tx_bytes += skb->len;
2559 end:
2560 acx_unlock(adev, flags);
2562 end_no_unlock:
2564 FN_EXIT1(txresult);
2565 return txresult;
2567 /***********************************************************************
2568 ** acx_l_update_ratevector
2570 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2572 const u8 acx_bitpos2ratebyte[] = {
2573 DOT11RATEBYTE_1,
2574 DOT11RATEBYTE_2,
2575 DOT11RATEBYTE_5_5,
2576 DOT11RATEBYTE_6_G,
2577 DOT11RATEBYTE_9_G,
2578 DOT11RATEBYTE_11,
2579 DOT11RATEBYTE_12_G,
2580 DOT11RATEBYTE_18_G,
2581 DOT11RATEBYTE_22,
2582 DOT11RATEBYTE_24_G,
2583 DOT11RATEBYTE_36_G,
2584 DOT11RATEBYTE_48_G,
2585 DOT11RATEBYTE_54_G,
2588 void acx_l_update_ratevector(acx_device_t * adev)
2590 u16 bcfg = adev->rate_basic;
2591 u16 ocfg = adev->rate_oper;
2592 u8 *supp = adev->rate_supported;
2593 const u8 *dot11 = acx_bitpos2ratebyte;
2595 FN_ENTER;
2597 while (ocfg) {
2598 if (ocfg & 1) {
2599 *supp = *dot11;
2600 if (bcfg & 1) {
2601 *supp |= 0x80;
2603 supp++;
2605 dot11++;
2606 ocfg >>= 1;
2607 bcfg >>= 1;
2609 adev->rate_supported_len = supp - adev->rate_supported;
2610 if (acx_debug & L_ASSOC) {
2611 printk("new ratevector: ");
2612 acx_dump_bytes(adev->rate_supported, adev->rate_supported_len);
2614 FN_EXIT0;
2617 /***********************************************************************
2618 ** acx_i_timer
2620 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2622 ** Obvious
2624 void acx_i_timer(unsigned long address)
2626 unsigned long flags;
2627 acx_device_t *adev = (acx_device_t *) address;
2629 FN_ENTER;
2631 acx_lock(adev, flags);
2633 FIXME();
2634 /* We need calibration and stats gather tasks to perform here */
2636 acx_unlock(adev, flags);
2638 FN_EXIT0;
2642 /***********************************************************************
2643 ** acx_set_timer
2645 ** Sets the 802.11 state management timer's timeout.
2647 ** Linux derived
2649 void acx_set_timer(acx_device_t * adev, int timeout_us)
2651 FN_ENTER;
2653 log(L_DEBUG | L_IRQ, "%s(%u ms)\n", __func__, timeout_us / 1000);
2654 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2655 printk("attempt to set the timer "
2656 "when the card interface is not up!\n");
2657 goto end;
2660 /* first check if the timer was already initialized, THEN modify it */
2661 if (adev->mgmt_timer.function) {
2662 mod_timer(&adev->mgmt_timer,
2663 jiffies + (timeout_us * HZ / 1000000));
2665 end:
2666 FN_EXIT0;
2669 /** acx_plcp_get_bitrate_cck
2671 ** Obvious
2673 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2675 switch (plcp) {
2676 case 0x0A:
2677 return ACX_CCK_RATE_1MB;
2678 case 0x14:
2679 return ACX_CCK_RATE_2MB;
2680 case 0x37:
2681 return ACX_CCK_RATE_5MB;
2682 case 0x6E:
2683 return ACX_CCK_RATE_11MB;
2685 return 0;
2688 /* Extract the bitrate out of an OFDM PLCP header. */
2689 /** Obvious **/
2690 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2692 switch (plcp & 0xF) {
2693 case 0xB:
2694 return ACX_OFDM_RATE_6MB;
2695 case 0xF:
2696 return ACX_OFDM_RATE_9MB;
2697 case 0xA:
2698 return ACX_OFDM_RATE_12MB;
2699 case 0xE:
2700 return ACX_OFDM_RATE_18MB;
2701 case 0x9:
2702 return ACX_OFDM_RATE_24MB;
2703 case 0xD:
2704 return ACX_OFDM_RATE_36MB;
2705 case 0x8:
2706 return ACX_OFDM_RATE_48MB;
2707 case 0xC:
2708 return ACX_OFDM_RATE_54MB;
2710 return 0;
2714 /***********************************************************************
2715 ** acx_l_rx
2717 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2718 ** buffer and feeds it to the network stack via netif_rx().
2720 ** Look to bcm43xx or p54
2722 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2725 struct ieee80211_rx_status* status = &adev->rx_status;
2726 struct ieee80211_hdr *w_hdr;
2727 int buflen;
2728 FN_ENTER;
2730 if (likely(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2731 struct sk_buff *skb;
2732 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2733 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2734 skb = dev_alloc_skb(buflen + 2);
2735 skb_reserve(skb, 2);
2736 skb_put(skb, buflen);
2737 memcpy(skb->data, w_hdr, buflen);
2739 // memset(&status, 0, sizeof(status));
2741 if (likely(skb)) {
2742 adev->acx_stats.last_rx = jiffies;
2743 status->mactime = rxbuf->time;
2744 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2745 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr);
2746 status->flag = 0;
2747 status->rate = rxbuf->phy_plcp_signal;
2748 status->antenna = 1;
2750 #ifndef OLD_QUALITY
2751 qual = acx_signal_determine_quality(adev->wstats.qual.level,
2752 adev->wstats.qual.noise);
2753 #else
2754 qual = (adev->wstats.qual.noise <= 100) ?
2755 100 - adev->wstats.qual.noise : 0;
2756 #endif
2757 adev->wstats.qual.qual = qual;
2758 adev->wstats.qual.updated = 7; *//* all 3 indicators updated */
2760 #ifdef FROM_SCAN_SOURCE_ONLY
2762 #endif
2764 if (rxbuf->phy_stat_baseband & (1 << 3)) /* Uses OFDM */
2766 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2767 } else
2769 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2771 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2772 adev->stats.rx_packets++;
2773 adev->stats.rx_bytes += skb->len;
2776 FN_EXIT0;
2781 /***********************************************************************
2782 ** acx_s_read_fw
2784 ** Loads a firmware image
2786 ** Returns:
2787 ** 0 unable to load file
2788 ** pointer to firmware success
2790 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2791 u32 * size)
2793 firmware_image_t *res;
2794 const struct firmware *fw_entry;
2796 res = NULL;
2797 log(L_INIT, "requesting firmware image '%s'\n", file);
2798 if (!request_firmware(&fw_entry, file, dev)) {
2799 *size = 8;
2800 if (fw_entry->size >= 8)
2801 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2802 if (fw_entry->size != *size) {
2803 printk("acx: firmware size does not match "
2804 "firmware header: %d != %d, "
2805 "aborting fw upload\n",
2806 (int)fw_entry->size, (int)*size);
2807 goto release_ret;
2809 res = vmalloc(*size);
2810 if (!res) {
2811 printk("acx: no memory for firmware "
2812 "(%u bytes)\n", *size);
2813 goto release_ret;
2815 memcpy(res, fw_entry->data, fw_entry->size);
2816 release_ret:
2817 release_firmware(fw_entry);
2818 return res;
2820 printk("acx: firmware image '%s' was not provided. "
2821 "Check your hotplug scripts\n", file);
2823 /* checksum will be verified in write_fw, so don't bother here */
2824 return res;
2828 /***********************************************************************
2829 ** acx_s_set_wepkey
2831 static void acx100_s_set_wepkey(acx_device_t * adev)
2833 ie_dot11WEPDefaultKey_t dk;
2834 int i;
2836 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2837 if (adev->wep_keys[i].size != 0) {
2838 log(L_INIT, "setting WEP key: %d with "
2839 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2840 dk.action = 1;
2841 dk.keySize = adev->wep_keys[i].size;
2842 dk.defaultKeyNum = i;
2843 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2844 acx_s_configure(adev, &dk,
2845 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
2850 static void acx111_s_set_wepkey(acx_device_t * adev)
2852 acx111WEPDefaultKey_t dk;
2853 int i;
2855 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2856 if (adev->wep_keys[i].size != 0) {
2857 log(L_INIT, "setting WEP key: %d with "
2858 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2859 memset(&dk, 0, sizeof(dk));
2860 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2861 dk.keySize = adev->wep_keys[i].size;
2863 /* are these two lines necessary? */
2864 dk.type = 0; /* default WEP key */
2865 dk.index = 0; /* ignored when setting default key */
2867 dk.defaultKeyNum = i;
2868 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2869 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2870 sizeof(dk));
2874 /* Obvious */
2875 static void acx_s_set_wepkey(acx_device_t * adev)
2877 if (IS_ACX111(adev))
2878 acx111_s_set_wepkey(adev);
2879 else
2880 acx100_s_set_wepkey(adev);
2884 /***********************************************************************
2885 ** acx100_s_init_wep
2887 ** FIXME: this should probably be moved into the new card settings
2888 ** management, but since we're also modifying the memory map layout here
2889 ** due to the WEP key space we want, we should take care...
2891 static int acx100_s_init_wep(acx_device_t * adev)
2893 acx100_ie_wep_options_t options;
2894 ie_dot11WEPDefaultKeyID_t dk;
2895 acx_ie_memmap_t pt;
2896 int res = NOT_OK;
2898 FN_ENTER;
2900 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2901 goto fail;
2904 log(L_DEBUG, "CodeEnd:%X\n", pt.CodeEnd);
2906 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2907 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2909 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2910 goto fail;
2913 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2914 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2915 options.WEPOption = 0x00;
2917 log(L_ASSOC, "writing WEP options\n");
2918 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
2920 acx100_s_set_wepkey(adev);
2922 if (adev->wep_keys[adev->wep_current_index].size != 0) {
2923 log(L_ASSOC, "setting active default WEP key number: %d\n",
2924 adev->wep_current_index);
2925 dk.KeyID = adev->wep_current_index;
2926 acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
2928 /* FIXME!!! wep_key_struct is filled nowhere! But adev
2929 * is initialized to 0, and we don't REALLY need those keys either */
2930 /* for (i = 0; i < 10; i++) {
2931 if (adev->wep_key_struct[i].len != 0) {
2932 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
2933 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
2934 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
2935 wep_mgmt.Action = cpu_to_le16(1);
2936 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
2937 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
2938 adev->wep_key_struct[i].index = i;
2944 /* now retrieve the updated WEPCacheEnd pointer... */
2945 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2946 printk("%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
2947 wiphy_name(adev->ieee->wiphy));
2948 goto fail;
2950 /* ...and tell it to start allocating templates at that location */
2951 /* (no endianness conversion needed) */
2952 pt.PacketTemplateStart = pt.WEPCacheEnd;
2954 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2955 printk("%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
2956 wiphy_name(adev->ieee->wiphy));
2957 goto fail;
2959 res = OK;
2961 fail:
2962 FN_EXIT1(res);
2963 return res;
2967 static int
2968 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
2969 unsigned int cmd)
2971 int res;
2972 union {
2973 acx_template_nullframe_t null;
2974 acx_template_beacon_t b;
2975 acx_template_tim_t tim;
2976 acx_template_probereq_t preq;
2977 acx_template_proberesp_t presp;
2978 } templ;
2980 memset(&templ, 0, len);
2981 templ.null.size = cpu_to_le16(len - 2);
2982 res = acx_s_issue_cmd(adev, cmd, &templ, len);
2983 return res;
2986 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
2988 return acx_s_init_max_template_generic(adev,
2989 sizeof(acx_template_nullframe_t),
2990 ACX1xx_CMD_CONFIG_NULL_DATA);
2993 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
2995 return acx_s_init_max_template_generic(adev,
2996 sizeof(acx_template_beacon_t),
2997 ACX1xx_CMD_CONFIG_BEACON);
3000 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
3002 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
3003 ACX1xx_CMD_CONFIG_TIM);
3006 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
3008 return acx_s_init_max_template_generic(adev,
3009 sizeof(acx_template_proberesp_t),
3010 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
3013 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
3015 return acx_s_init_max_template_generic(adev,
3016 sizeof(acx_template_probereq_t),
3017 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
3020 /***********************************************************************
3021 ** acx_s_set_tim_template
3023 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
3024 ** by calling this function
3025 ** (it can be done by irq handler on each DTIM irq or by timer...)
3027 [802.11 7.3.2.6] TIM information element:
3028 - 1 EID
3029 - 1 Length
3030 1 1 DTIM Count
3031 indicates how many beacons (including this) appear before next DTIM
3032 (0=this one is a DTIM)
3033 2 1 DTIM Period
3034 number of beacons between successive DTIMs
3035 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
3036 3 1 Bitmap Control
3037 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
3038 set to 1 in TIM elements with a value of 0 in the DTIM Count field
3039 when one or more broadcast or multicast frames are buffered at the AP.
3040 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
3041 4 n Partial Virtual Bitmap
3042 Visible part of traffic-indication bitmap.
3043 Full bitmap consists of 2008 bits (251 octets) such that bit number N
3044 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
3045 in octet number N/8 where the low-order bit of each octet is bit0,
3046 and the high order bit is bit7.
3047 Each set bit in virtual bitmap corresponds to traffic buffered by AP
3048 for a specific station (with corresponding AID?).
3049 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
3050 Bitmap Offset is a number of skipped zero octets (see above).
3051 'Missing' octets at the tail are also assumed to be zero.
3052 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
3053 This means that traffic-indication bitmap is:
3054 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
3055 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
3057 static int acx_s_set_tim_template(acx_device_t * adev)
3059 /* For now, configure smallish test bitmap, all zero ("no pending data") */
3060 enum { bitmap_size = 5 };
3062 acx_template_tim_t t;
3063 int result;
3065 FN_ENTER;
3067 memset(&t, 0, sizeof(t));
3068 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3069 t.tim_eid = WLAN_EID_TIM;
3070 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3071 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3072 FN_EXIT1(result);
3073 return result;
3079 #if POWER_SAVE_80211
3080 /***********************************************************************
3081 ** acx_s_set_null_data_template
3083 static int acx_s_set_null_data_template(acx_device_t * adev)
3085 struct acx_template_nullframe b;
3086 int result;
3088 FN_ENTER;
3090 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3092 b.size = cpu_to_le16(sizeof(b) - 2);
3093 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3094 b.hdr.dur = 0;
3095 MAC_BCAST(b.hdr.a1);
3096 MAC_COPY(b.hdr.a2, adev->dev_addr);
3097 MAC_COPY(b.hdr.a3, adev->bssid);
3098 b.hdr.seq = 0;
3100 result =
3101 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3103 FN_EXIT1(result);
3104 return result;
3106 #endif
3113 /***********************************************************************
3114 ** acx_s_init_packet_templates()
3116 ** NOTE: order is very important here, to have a correct memory layout!
3117 ** init templates: max Probe Request (station mode), max NULL data,
3118 ** max Beacon, max TIM, max Probe Response.
3120 static int acx_s_init_packet_templates(acx_device_t * adev)
3122 acx_ie_memmap_t mm; /* ACX100 only */
3123 int result = NOT_OK;
3125 FN_ENTER;
3127 log(L_DEBUG | L_INIT, "initializing max packet templates\n");
3129 if (OK != acx_s_init_max_probe_request_template(adev))
3130 goto failed;
3132 if (OK != acx_s_init_max_null_data_template(adev))
3133 goto failed;
3135 if (OK != acx_s_init_max_beacon_template(adev))
3136 goto failed;
3138 if (OK != acx_s_init_max_tim_template(adev))
3139 goto failed;
3141 if (OK != acx_s_init_max_probe_response_template(adev))
3142 goto failed;
3144 if (IS_ACX111(adev)) {
3145 /* ACX111 doesn't need the memory map magic below,
3146 * and the other templates will be set later (acx_start) */
3147 result = OK;
3148 goto success;
3151 /* ACX100 will have its TIM template set,
3152 * and we also need to update the memory map */
3154 if (OK != acx_s_set_tim_template(adev))
3155 goto failed_acx100;
3157 log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3159 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3160 goto failed_acx100;
3162 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3163 if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3164 goto failed_acx100;
3166 result = OK;
3167 goto success;
3169 failed_acx100:
3170 log(L_DEBUG | L_INIT,
3171 /* "cb=0x%X\n" */
3172 "ACXMemoryMap:\n"
3173 ".CodeStart=0x%X\n"
3174 ".CodeEnd=0x%X\n"
3175 ".WEPCacheStart=0x%X\n"
3176 ".WEPCacheEnd=0x%X\n"
3177 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3178 /* len, */
3179 le32_to_cpu(mm.CodeStart),
3180 le32_to_cpu(mm.CodeEnd),
3181 le32_to_cpu(mm.WEPCacheStart),
3182 le32_to_cpu(mm.WEPCacheEnd),
3183 le32_to_cpu(mm.PacketTemplateStart),
3184 le32_to_cpu(mm.PacketTemplateEnd));
3186 failed:
3187 printk("%s: %s() FAILED\n", wiphy_name(adev->ieee->wiphy), __func__);
3189 success:
3190 FN_EXIT1(result);
3191 return result;
3196 /***********************************************************************
3197 ** acx_s_init_mac
3199 int acx_s_init_mac(acx_device_t * adev)
3201 int result = NOT_OK;
3203 FN_ENTER;
3205 if (IS_ACX111(adev)) {
3206 adev->ie_len = acx111_ie_len;
3207 adev->ie_len_dot11 = acx111_ie_len_dot11;
3208 } else {
3209 adev->ie_len = acx100_ie_len;
3210 adev->ie_len_dot11 = acx100_ie_len_dot11;
3213 if (IS_PCI(adev)) {
3214 adev->memblocksize = 256; /* 256 is default */
3215 /* try to load radio for both ACX100 and ACX111, since both
3216 * chips have at least some firmware versions making use of an
3217 * external radio module */
3218 acxpci_s_upload_radio(adev);
3219 } else {
3220 adev->memblocksize = 128;
3223 if (IS_ACX111(adev)) {
3224 /* for ACX111, the order is different from ACX100
3225 1. init packet templates
3226 2. create station context and create dma regions
3227 3. init wep default keys
3229 if (OK != acx_s_init_packet_templates(adev))
3230 goto fail;
3231 if (OK != acx111_s_create_dma_regions(adev)) {
3232 printk("%s: acx111_create_dma_regions FAILED\n",
3233 wiphy_name(adev->ieee->wiphy));
3234 goto fail;
3236 } else {
3237 if (OK != acx100_s_init_wep(adev))
3238 goto fail;
3239 if (OK != acx_s_init_packet_templates(adev))
3240 goto fail;
3241 if (OK != acx100_s_create_dma_regions(adev)) {
3242 printk("%s: acx100_create_dma_regions FAILED\n",
3243 wiphy_name(adev->ieee->wiphy));
3244 goto fail;
3248 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3249 result = OK;
3251 fail:
3252 if (result)
3253 printk("acx: init_mac() FAILED\n");
3254 FN_EXIT1(result);
3255 return result;
3260 #if POWER_SAVE_80211
3261 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3263 /* merge both structs in a union to be able to have common code */
3264 union {
3265 acx111_ie_powersave_t acx111;
3266 acx100_ie_powersave_t acx100;
3267 } pm;
3269 /* change 802.11 power save mode settings */
3270 log(L_INIT, "updating 802.11 power save mode settings: "
3271 "wakeup_cfg 0x%02X, listen interval %u, "
3272 "options 0x%02X, hangover period %u, "
3273 "enhanced_ps_transition_time %u\n",
3274 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3275 adev->ps_options, adev->ps_hangover_period,
3276 adev->ps_enhanced_transition_time);
3277 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3278 log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, "
3279 "listen interval %u, options 0x%02X, "
3280 "hangover period %u, "
3281 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3282 pm.acx111.wakeup_cfg,
3283 pm.acx111.listen_interval,
3284 pm.acx111.options,
3285 pm.acx111.hangover_period,
3286 IS_ACX111(adev) ?
3287 pm.acx111.enhanced_ps_transition_time
3288 : pm.acx100.enhanced_ps_transition_time,
3289 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3290 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3291 pm.acx111.listen_interval = adev->ps_listen_interval;
3292 pm.acx111.options = adev->ps_options;
3293 pm.acx111.hangover_period = adev->ps_hangover_period;
3294 if (IS_ACX111(adev)) {
3295 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3296 pm.acx111.enhanced_ps_transition_time =
3297 cpu_to_le32(adev->ps_enhanced_transition_time);
3298 } else {
3299 pm.acx100.enhanced_ps_transition_time =
3300 cpu_to_le16(adev->ps_enhanced_transition_time);
3302 acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT);
3303 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3304 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3305 acx_s_msleep(40);
3306 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3307 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3308 log(L_INIT, "power save mode change %s\n",
3309 (pm.acx111.
3310 wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful");
3311 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3312 * that power save mode change was successful. */
3313 /* FIXME: we shouldn't trigger a scan immediately after
3314 * fiddling with power save mode (since the firmware is sending
3315 * a NULL frame then). */
3317 #endif
3320 /***********************************************************************
3321 ** acx_s_update_card_settings
3323 ** Applies accumulated changes in various adev->xxxx members
3324 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3325 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3327 void acx_s_set_sane_reg_domain(acx_device_t * adev, int do_set)
3330 FIXME();
3331 if (do_set) {
3332 acx_ie_generic_t dom;
3333 dom.m.bytes[0] = adev->reg_dom_id;
3334 acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3339 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3341 u32 feature1, feature2;
3343 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3344 printk("%s: invalid sensitivity setting (1..3), "
3345 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3346 adev->sensitivity = 1;
3348 acx111_s_get_feature_config(adev, &feature1, &feature2);
3349 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3350 if (adev->sensitivity > 1)
3351 SET_BIT(feature1, FEATURE1_LOW_RX);
3352 if (adev->sensitivity > 2)
3353 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3354 acx111_s_feature_set(adev, feature1, feature2);
3358 void acx_s_update_card_settings(acx_device_t * adev)
3360 unsigned long flags;
3361 unsigned int start_scan = 0;
3362 int i;
3364 FN_ENTER;
3366 log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3367 adev->get_mask, adev->set_mask);
3369 /* Track dependencies betweed various settings */
3371 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3372 log(L_INIT, "important setting has been changed. "
3373 "Need to update packet templates, too\n");
3374 SET_BIT(adev->set_mask, SET_TEMPLATES);
3376 if (adev->set_mask & GETSET_CHANNEL) {
3377 /* This will actually tune RX/TX to the channel */
3378 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3379 switch (adev->mode) {
3380 case ACX_MODE_0_ADHOC:
3381 case ACX_MODE_3_AP:
3382 /* Beacons contain channel# - update them */
3383 SET_BIT(adev->set_mask, SET_TEMPLATES);
3386 switch (adev->mode) {
3387 case ACX_MODE_0_ADHOC:
3388 case ACX_MODE_2_STA:
3389 start_scan = 1;
3393 /* Apply settings */
3396 if (adev->get_mask & GETSET_STATION_ID) {
3397 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3398 const u8 *paddr;
3400 acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3401 paddr = &stationID[4];
3402 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3403 for (i = 0; i < ETH_ALEN; i++) {
3404 /* we copy the MAC address (reversed in
3405 * the card) to the netdevice's MAC
3406 * address, and on ifup it will be
3407 * copied into iwadev->dev_addr */
3408 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3410 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3411 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3414 if (adev->get_mask & GETSET_SENSITIVITY) {
3415 if ((RADIO_RFMD_11 == adev->radio_type)
3416 || (RADIO_MAXIM_0D == adev->radio_type)
3417 || (RADIO_RALINK_15 == adev->radio_type)) {
3418 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3419 } else {
3420 log(L_INIT, "don't know how to get sensitivity "
3421 "for radio type 0x%02X\n", adev->radio_type);
3422 adev->sensitivity = 0;
3424 log(L_INIT, "got sensitivity value %u\n", adev->sensitivity);
3426 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3429 if (adev->get_mask & GETSET_ANTENNA) {
3430 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3432 memset(antenna, 0, sizeof(antenna));
3433 acx_s_interrogate(adev, antenna,
3434 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3435 adev->antenna = antenna[4];
3436 log(L_INIT, "got antenna value 0x%02X\n", adev->antenna);
3437 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3440 if (adev->get_mask & GETSET_ED_THRESH) {
3441 if (IS_ACX100(adev)) {
3442 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3444 memset(ed_threshold, 0, sizeof(ed_threshold));
3445 acx_s_interrogate(adev, ed_threshold,
3446 ACX100_IE_DOT11_ED_THRESHOLD);
3447 adev->ed_threshold = ed_threshold[4];
3448 } else {
3449 log(L_INIT, "acx111 doesn't support ED\n");
3450 adev->ed_threshold = 0;
3452 log(L_INIT, "got Energy Detect (ED) threshold %u\n",
3453 adev->ed_threshold);
3454 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3457 if (adev->get_mask & GETSET_CCA) {
3458 if (IS_ACX100(adev)) {
3459 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3461 memset(cca, 0, sizeof(adev->cca));
3462 acx_s_interrogate(adev, cca,
3463 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3464 adev->cca = cca[4];
3465 } else {
3466 log(L_INIT, "acx111 doesn't support CCA\n");
3467 adev->cca = 0;
3469 log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n",
3470 adev->cca);
3471 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3474 if (adev->get_mask & GETSET_REG_DOMAIN) {
3475 acx_ie_generic_t dom;
3477 acx_s_interrogate(adev, &dom,
3478 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3479 adev->reg_dom_id = dom.m.bytes[0];
3480 acx_s_set_sane_reg_domain(adev, 0);
3481 log(L_INIT, "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3482 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3485 if (adev->set_mask & GETSET_STATION_ID) {
3486 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3487 u8 *paddr;
3489 paddr = &stationID[4];
3490 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3491 for (i = 0; i < ETH_ALEN; i++) {
3492 /* copy the MAC address we obtained when we noticed
3493 * that the ethernet iface's MAC changed
3494 * to the card (reversed in
3495 * the card!) */
3496 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3498 acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3499 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3502 if (adev->set_mask & SET_STA_LIST) {
3503 acx_lock(adev, flags);
3504 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3505 acx_unlock(adev, flags);
3507 if (adev->set_mask & SET_RATE_FALLBACK) {
3508 u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
3510 /* configure to not do fallbacks when not in auto rate mode */
3511 rate[4] =
3512 (adev->
3513 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3514 log(L_INIT, "updating Tx fallback to %u retries\n", rate[4]);
3515 acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK);
3516 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3518 if (adev->set_mask & GETSET_TXPOWER) {
3519 log(L_INIT, "updating transmit power: %u dBm\n",
3520 adev->tx_level_dbm);
3521 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3522 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3525 if (adev->set_mask & GETSET_SENSITIVITY) {
3526 log(L_INIT, "updating sensitivity value: %u\n",
3527 adev->sensitivity);
3528 switch (adev->radio_type) {
3529 case RADIO_RFMD_11:
3530 case RADIO_MAXIM_0D:
3531 case RADIO_RALINK_15:
3532 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3533 break;
3534 case RADIO_RADIA_16:
3535 case RADIO_UNKNOWN_17:
3536 acx111_s_sens_radio_16_17(adev);
3537 break;
3538 default:
3539 log(L_INIT, "don't know how to modify sensitivity "
3540 "for radio type 0x%02X\n", adev->radio_type);
3542 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3545 if (adev->set_mask & GETSET_ANTENNA) {
3546 /* antenna */
3547 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3549 memset(antenna, 0, sizeof(antenna));
3550 antenna[4] = adev->antenna;
3551 log(L_INIT, "updating antenna value: 0x%02X\n", adev->antenna);
3552 acx_s_configure(adev, &antenna,
3553 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3554 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3557 if (adev->set_mask & GETSET_ED_THRESH) {
3558 /* ed_threshold */
3559 log(L_INIT, "updating Energy Detect (ED) threshold: %u\n",
3560 adev->ed_threshold);
3561 if (IS_ACX100(adev)) {
3562 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3564 memset(ed_threshold, 0, sizeof(ed_threshold));
3565 ed_threshold[4] = adev->ed_threshold;
3566 acx_s_configure(adev, &ed_threshold,
3567 ACX100_IE_DOT11_ED_THRESHOLD);
3568 } else
3569 log(L_INIT, "acx111 doesn't support ED!\n");
3570 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3573 if (adev->set_mask & GETSET_CCA) {
3574 /* CCA value */
3575 log(L_INIT, "updating Channel Clear Assessment "
3576 "(CCA) value: 0x%02X\n", adev->cca);
3577 if (IS_ACX100(adev)) {
3578 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3580 memset(cca, 0, sizeof(cca));
3581 cca[4] = adev->cca;
3582 acx_s_configure(adev, &cca,
3583 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3584 } else
3585 log(L_INIT, "acx111 doesn't support CCA!\n");
3586 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3589 if (adev->set_mask & GETSET_LED_POWER) {
3590 /* Enable Tx */
3591 log(L_INIT, "updating power LED status: %u\n", adev->led_power);
3593 acx_lock(adev, flags);
3594 if (IS_PCI(adev))
3595 acxpci_l_power_led(adev, adev->led_power);
3596 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3597 acx_unlock(adev, flags);
3600 if (adev->set_mask & GETSET_POWER_80211) {
3601 #if POWER_SAVE_80211
3602 acx_s_update_80211_powersave_mode(adev);
3603 #endif
3604 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3607 if (adev->set_mask & GETSET_CHANNEL) {
3608 /* channel */
3609 log(L_INIT, "updating channel to: %u\n", adev->channel);
3610 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3613 if (adev->set_mask & GETSET_TX) {
3614 /* set Tx */
3615 log(L_INIT, "updating: %s Tx\n",
3616 adev->tx_disabled ? "disable" : "enable");
3617 if (adev->tx_disabled)
3618 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3619 else {
3620 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3621 &adev->channel, 1);
3622 FIXME();
3623 /* This needs to be keyed on WEP? */
3624 // acx111_s_feature_on(adev, 0,
3625 // FEATURE2_NO_TXCRYPT |
3626 // FEATURE2_SNIFFER);
3628 CLEAR_BIT(adev->set_mask, GETSET_TX);
3631 if (adev->set_mask & GETSET_RX) {
3632 /* Enable Rx */
3633 log(L_INIT, "updating: enable Rx on channel: %u\n",
3634 adev->channel);
3635 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3636 CLEAR_BIT(adev->set_mask, GETSET_RX);
3639 if (adev->set_mask & GETSET_RETRY) {
3640 u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
3641 u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
3643 log(L_INIT,
3644 "updating short retry limit: %u, long retry limit: %u\n",
3645 adev->short_retry, adev->long_retry);
3646 short_retry[0x4] = adev->short_retry;
3647 long_retry[0x4] = adev->long_retry;
3648 acx_s_configure(adev, &short_retry,
3649 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
3650 acx_s_configure(adev, &long_retry,
3651 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
3652 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3655 if (adev->set_mask & SET_MSDU_LIFETIME) {
3656 u8 xmt_msdu_lifetime[4 +
3657 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3659 log(L_INIT, "updating tx MSDU lifetime: %u\n",
3660 adev->msdu_lifetime);
3661 *(u32 *) & xmt_msdu_lifetime[4] =
3662 cpu_to_le32((u32) adev->msdu_lifetime);
3663 acx_s_configure(adev, &xmt_msdu_lifetime,
3664 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
3665 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3668 if (adev->set_mask & GETSET_REG_DOMAIN) {
3669 log(L_INIT, "updating regulatory domain: 0x%02X\n",
3670 adev->reg_dom_id);
3671 acx_s_set_sane_reg_domain(adev, 1);
3672 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3674 if (adev->set_mask & GETSET_MODE ) {
3675 acx111_s_feature_on(adev, 0,
3676 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3677 switch (adev->mode) {
3678 case ACX_MODE_3_AP:
3679 adev->aid = 0;
3680 //acx111_s_feature_off(adev, 0,
3681 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3682 MAC_COPY(adev->bssid,adev->dev_addr);
3683 acx_s_cmd_join_bssid(adev,adev->dev_addr);
3684 break;
3685 case ACX_MODE_MONITOR:
3686 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3687 break;
3688 case ACX_MODE_0_ADHOC:
3689 case ACX_MODE_2_STA:
3690 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3691 break;
3692 default:
3693 break;
3695 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3697 if (adev->set_mask & SET_TEMPLATES) {
3698 switch (adev->mode)
3700 case ACX_MODE_3_AP:
3701 acx_s_set_tim_template(adev);
3702 break;
3703 default:
3704 break;
3706 if (adev->beacon_cache)
3708 acx_s_set_beacon_template(adev, adev->beacon_cache);
3709 dev_kfree_skb(adev->beacon_cache);
3710 adev->beacon_cache = NULL;
3712 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3715 if (adev->set_mask & SET_RXCONFIG) {
3716 acx_s_initialize_rx_config(adev);
3717 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3720 if (adev->set_mask & GETSET_RESCAN) {
3721 /* switch (adev->mode) {
3722 case ACX_MODE_0_ADHOC:
3723 case ACX_MODE_2_STA:
3724 start_scan = 1;
3725 break;
3727 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3730 if (adev->set_mask & GETSET_WEP) {
3731 /* encode */
3733 ie_dot11WEPDefaultKeyID_t dkey;
3734 #ifdef DEBUG_WEP
3735 struct {
3736 u16 type;
3737 u16 len;
3738 u8 val;
3739 } ACX_PACKED keyindic;
3740 #endif
3741 log(L_INIT, "updating WEP key settings\n");
3743 acx_s_set_wepkey(adev);
3744 if (adev->wep_enabled) {
3745 dkey.KeyID = adev->wep_current_index;
3746 log(L_INIT, "setting WEP key %u as default\n",
3747 dkey.KeyID);
3748 acx_s_configure(adev, &dkey,
3749 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
3750 #ifdef DEBUG_WEP
3751 keyindic.val = 3;
3752 acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
3753 #endif
3756 // start_scan = 1;
3757 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3760 if (adev->set_mask & SET_WEP_OPTIONS) {
3761 acx100_ie_wep_options_t options;
3763 if (IS_ACX111(adev)) {
3764 log(L_DEBUG,
3765 "setting WEP Options for acx111 is not supported\n");
3766 } else {
3767 log(L_INIT, "setting WEP Options\n");
3769 /* let's choose maximum setting: 4 default keys,
3770 * plus 10 other keys: */
3771 options.NumKeys =
3772 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3773 /* don't decrypt default key only,
3774 * don't override decryption: */
3775 options.WEPOption = 0;
3776 if (adev->mode == ACX_MODE_3_AP) {
3777 /* don't decrypt default key only,
3778 * override decryption mechanism: */
3779 options.WEPOption = 2;
3782 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3784 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3788 /* debug, rate, and nick don't need any handling */
3789 /* what about sniffing mode?? */
3791 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3792 adev->get_mask, adev->set_mask);
3794 /* end: */
3795 FN_EXIT0;
3798 #if 0
3799 /***********************************************************************
3800 ** acx_e_after_interrupt_task
3802 static int acx_s_recalib_radio(acx_device_t * adev)
3804 if (IS_ACX111(adev)) {
3805 acx111_cmd_radiocalib_t cal;
3807 /* automatic recalibration, choose all methods: */
3808 cal.methods = cpu_to_le32(0x8000000f);
3809 /* automatic recalibration every 60 seconds (value in TUs)
3810 * I wonder what the firmware default here is? */
3811 cal.interval = cpu_to_le32(58594);
3812 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3813 &cal, sizeof(cal),
3814 CMD_TIMEOUT_MS(100));
3815 } else {
3816 /* On ACX100, we need to recalibrate the radio
3817 * by issuing a GETSET_TX|GETSET_RX */
3818 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3819 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3820 (OK ==
3821 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3822 &adev->channel, 1))
3823 && (OK ==
3824 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3825 &adev->channel, 1)))
3826 return OK;
3827 return NOT_OK;
3830 #endif // if 0
3831 #if 0
3832 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3834 int res;
3836 /* this helps with ACX100 at least;
3837 * hopefully ACX111 also does a
3838 * recalibration here */
3840 /* clear flag beforehand, since we want to make sure
3841 * it's cleared; then only set it again on specific circumstances */
3842 CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3844 /* better wait a bit between recalibrations to
3845 * prevent overheating due to torturing the card
3846 * into working too long despite high temperature
3847 * (just a safety measure) */
3848 if (adev->recalib_time_last_success
3849 && time_before(jiffies, adev->recalib_time_last_success
3850 + RECALIB_PAUSE * 60 * HZ)) {
3851 if (adev->recalib_msg_ratelimit <= 4) {
3852 printk("%s: less than " STRING(RECALIB_PAUSE)
3853 " minutes since last radio recalibration, "
3854 "not recalibrating (maybe card is too hot?)\n",
3855 wiphy_name(adev->ieee->wiphy));
3856 adev->recalib_msg_ratelimit++;
3857 if (adev->recalib_msg_ratelimit == 5)
3858 printk("disabling above message until next recalib\n");
3860 return;
3863 adev->recalib_msg_ratelimit = 0;
3865 /* note that commands sometimes fail (card busy),
3866 * so only clear flag if we were fully successful */
3867 res = acx_s_recalib_radio(adev);
3868 if (res == OK) {
3869 printk("%s: successfully recalibrated radio\n",
3870 wiphy_name(adev->ieee->wiphy));
3871 adev->recalib_time_last_success = jiffies;
3872 adev->recalib_failure_count = 0;
3873 } else {
3874 /* failed: resubmit, but only limited
3875 * amount of times within some time range
3876 * to prevent endless loop */
3878 adev->recalib_time_last_success = 0; /* we failed */
3880 /* if some time passed between last
3881 * attempts, then reset failure retry counter
3882 * to be able to do next recalib attempt */
3883 if (time_after
3884 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3885 adev->recalib_failure_count = 0;
3887 if (adev->recalib_failure_count < 5) {
3888 /* increment inside only, for speedup of outside path */
3889 adev->recalib_failure_count++;
3890 adev->recalib_time_last_attempt = jiffies;
3891 acx_schedule_task(adev,
3892 ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3896 #endif // if 0
3898 void acx_e_after_interrupt_task(struct work_struct *work)
3900 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
3901 unsigned int flags;
3902 FN_ENTER;
3903 acx_lock(adev, flags);
3904 if (!adev->after_interrupt_jobs || !adev->initialized)
3905 goto end; /* no jobs to do */
3907 /* we see lotsa tx errors */
3908 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) {
3909 // acx_s_after_interrupt_recalib(adev);
3912 /* a poor interrupt code wanted to do update_card_settings() */
3913 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) {
3914 if (ACX_STATE_IFACE_UP & adev->dev_state_mask)
3915 acx_s_update_card_settings(adev);
3916 CLEAR_BIT(adev->after_interrupt_jobs,
3917 ACX_AFTER_IRQ_UPDATE_CARD_CFG);
3919 /* 1) we detected that no Scan_Complete IRQ came from fw, or
3920 ** 2) we found too many STAs */
3921 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) {
3922 log(L_IRQ, "sending a stop scan cmd...\n");
3923 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
3924 /* HACK: set the IRQ bit, since we won't get a
3925 * scan complete IRQ any more on ACX111 (works on ACX100!),
3926 * since _we_, not a fw, have stopped the scan */
3927 SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
3928 CLEAR_BIT(adev->after_interrupt_jobs,
3929 ACX_AFTER_IRQ_CMD_STOP_SCAN);
3932 /* either fw sent Scan_Complete or we detected that
3933 ** no Scan_Complete IRQ came from fw. Finish scanning,
3934 ** pick join partner if any */
3935 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) {
3936 /* + scan kills current join status - restore it
3937 ** (do we need it for STA?) */
3938 /* + does it happen only with active scans?
3939 ** active and passive scans? ALL scans including
3940 ** background one? */
3941 /* + was not verified that everything is restored
3942 ** (but at least we start to emit beacons again) */
3943 CLEAR_BIT(adev->after_interrupt_jobs,
3944 ACX_AFTER_IRQ_COMPLETE_SCAN);
3947 /* STA auth or assoc timed out, start over again */
3949 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) {
3950 log(L_IRQ, "sending a start_scan cmd...\n");
3951 CLEAR_BIT(adev->after_interrupt_jobs,
3952 ACX_AFTER_IRQ_RESTART_SCAN);
3955 /* whee, we got positive assoc response! 8) */
3956 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) {
3957 CLEAR_BIT(adev->after_interrupt_jobs,
3958 ACX_AFTER_IRQ_CMD_ASSOCIATE);
3960 end:
3961 if(adev->after_interrupt_jobs)
3963 printk("Jobs still to be run: %x\n",adev->after_interrupt_jobs);
3964 adev->after_interrupt_jobs = 0;
3966 acx_unlock(adev, flags);
3967 // acx_sem_unlock(adev);
3968 FN_EXIT0;
3972 /***********************************************************************
3973 ** acx_schedule_task
3975 ** Schedule the call of the after_interrupt method after leaving
3976 ** the interrupt context.
3978 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
3980 if (!adev->after_interrupt_jobs)
3982 SET_BIT(adev->after_interrupt_jobs, set_flag);
3983 schedule_work(&adev->after_interrupt_task);
3988 /***********************************************************************
3990 void acx_init_task_scheduler(acx_device_t * adev)
3992 /* configure task scheduler */
3993 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
3997 /***********************************************************************
3998 ** acx_s_start
4000 void acx_s_start(acx_device_t * adev)
4002 FN_ENTER;
4005 * Ok, now we do everything that can possibly be done with ioctl
4006 * calls to make sure that when it was called before the card
4007 * was up we get the changes asked for
4010 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4011 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4012 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4013 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4015 log(L_INIT, "updating initial settings on iface activation\n");
4016 acx_s_update_card_settings(adev);
4018 FN_EXIT0;
4022 /***********************************************************************
4023 ** acx_update_capabilities
4024 *//*
4025 void acx_update_capabilities(acx_device_t * adev)
4027 u16 cap = 0;
4029 switch (adev->mode) {
4030 case ACX_MODE_3_AP:
4031 SET_BIT(cap, WF_MGMT_CAP_ESS);
4032 break;
4033 case ACX_MODE_0_ADHOC:
4034 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4035 break;
4036 */ /* other types of stations do not emit beacons */
4037 /* }
4039 if (adev->wep_restricted) {
4040 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4042 if (adev->cfgopt_dot11ShortPreambleOption) {
4043 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4045 if (adev->cfgopt_dot11PBCCOption) {
4046 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4048 if (adev->cfgopt_dot11ChannelAgility) {
4049 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4051 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4052 adev->capabilities, cap);
4053 adev->capabilities = cap;
4057 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4060 static void acx_select_opmode(acx_device_t * adev)
4062 FN_ENTER;
4064 int changed = 0;
4065 if (adev->interface.operating) {
4066 switch (adev->interface.type) {
4067 case IEEE80211_IF_TYPE_AP:
4068 if (adev->mode != ACX_MODE_3_AP)
4070 adev->mode = ACX_MODE_3_AP;
4071 changed = 1;
4073 break;
4074 case IEEE80211_IF_TYPE_IBSS:
4075 if (adev->mode != ACX_MODE_0_ADHOC)
4077 adev->mode = ACX_MODE_0_ADHOC;
4078 changed = 1;
4080 break;
4081 case IEEE80211_IF_TYPE_STA:
4082 if (adev->mode != ACX_MODE_2_STA)
4084 adev->mode = ACX_MODE_2_STA;
4085 changed = 1;
4087 break;
4088 case IEEE80211_IF_TYPE_WDS:
4089 default:
4090 if (adev->mode != ACX_MODE_OFF)
4092 adev->mode = ACX_MODE_OFF;
4093 changed = 1;
4095 break;
4097 } else {
4098 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4100 if (adev->mode != ACX_MODE_MONITOR)
4102 adev->mode = ACX_MODE_MONITOR;
4103 changed = 1;
4106 else
4108 if (adev->mode != ACX_MODE_OFF)
4110 adev->mode = ACX_MODE_OFF;
4111 changed = 1;
4115 if (changed)
4117 SET_BIT(adev->set_mask, GETSET_MODE);
4118 acx_s_update_card_settings(adev);
4119 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4124 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4128 int acx_add_interface(struct ieee80211_hw *ieee,
4129 struct ieee80211_if_init_conf *conf)
4131 acx_device_t *adev = ieee2adev(ieee);
4132 unsigned long flags;
4133 int err = -EOPNOTSUPP;
4135 FN_ENTER;
4136 acx_lock(adev, flags);
4138 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4139 adev->interface.monitor++;
4140 } else {
4141 if (adev->interface.operating)
4142 goto out_unlock;
4143 adev->interface.operating = 1;
4144 adev->interface.if_id = conf->if_id;
4145 adev->interface.mac_addr = conf->mac_addr;
4146 adev->interface.type = conf->type;
4148 // adev->mode = conf->type;
4149 if (adev->initialized)
4150 acx_select_opmode(adev);
4151 err = 0;
4153 printk(KERN_INFO "Virtual interface added "
4154 "(type: 0x%08X, ID: %d, MAC: "
4155 MAC_FMT ")\n",
4156 conf->type, conf->if_id, MAC_ARG(conf->mac_addr));
4158 out_unlock:
4159 acx_unlock(adev, flags);
4161 FN_EXIT0;
4162 return err;
4165 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4169 void acx_remove_interface(struct ieee80211_hw *hw,
4170 struct ieee80211_if_init_conf *conf)
4172 acx_device_t *adev = ieee2adev(hw);
4173 unsigned long flags;
4174 FN_ENTER;
4176 acx_lock(adev, flags);
4177 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4178 adev->interface.monitor--;
4179 // assert(bcm->interface.monitor >= 0);
4180 } else
4181 adev->interface.operating = 0;
4182 printk("Removing interface: %d %d\n", adev->interface.operating, conf->type);
4183 if (adev->initialized)
4184 acx_select_opmode(adev);
4185 flush_scheduled_work();
4186 acx_unlock(adev, flags);
4188 printk(KERN_INFO "Virtual interface removed "
4189 "(type: 0x%08X, ID: %d, MAC: "
4190 MAC_FMT ")\n",
4191 conf->type, conf->if_id, MAC_ARG(conf->mac_addr));
4192 FN_EXIT0;
4195 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4199 int acx_net_reset(struct ieee80211_hw *ieee)
4201 acx_device_t *adev = ieee2adev(ieee);
4202 FN_ENTER;
4203 if (IS_PCI(adev))
4204 acxpci_s_reset_dev(adev);
4205 else
4206 TODO();
4208 FN_EXIT0;
4209 return 0;
4213 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4216 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4218 int result;
4220 FN_ENTER;
4222 acx_sem_lock(adev);
4223 adev->rx_status.channel = channel;
4224 adev->rx_status.freq = freq;
4226 adev->channel = channel;
4227 /* hmm, the following code part is strange, but this is how
4228 * it was being done before... */
4229 log(L_IOCTL, "Changing to channel %d\n", channel);
4230 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4231 result = -EINPROGRESS; /* need to call commit handler */
4233 acx_sem_unlock(adev);
4234 FN_EXIT1(result);
4235 return result;
4239 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4242 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4244 acx_device_t *adev = ieee2adev(hw);
4245 unsigned long flags;
4246 #if 0
4247 int change = 0;
4248 #endif
4249 FN_ENTER;
4251 acx_lock(adev, flags);
4252 //FIXME();
4253 if (!adev->initialized) {
4254 acx_unlock(adev,flags);
4255 return 0;
4257 if (conf->beacon_int != adev->beacon_interval)
4258 adev->beacon_interval = conf->beacon_int;
4259 if (conf->channel != adev->channel) {
4260 acx_selectchannel(adev, conf->channel,conf->freq);
4261 /* acx_schedule_task(adev,
4262 ACX_AFTER_IRQ_UPDATE_CARD_CFG
4263 */ /*+ ACX_AFTER_IRQ_RESTART_SCAN */ /*);*/
4266 if (conf->short_slot_time != adev->short_slot) {
4267 // assert(phy->type == BCM43xx_PHYTYPE_G);
4268 if (conf->short_slot_time)
4269 acx_short_slot_timing_enable(adev);
4270 else
4271 acx_short_slot_timing_disable(adev);
4272 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4275 adev->tx_disabled = !conf->radio_enabled;
4276 if (conf->power_level != 0 && adev->tx_level_dbm > 15){
4277 adev->tx_level_dbm = conf->power_level;
4278 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4279 //acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4282 //FIXME: This does not seem to wake up:
4283 #if 0
4284 if (conf->power_level == 0) {
4285 if (radio->enabled)
4286 bcm43xx_radio_turn_off(bcm);
4287 } else {
4288 if (!radio->enabled)
4289 bcm43xx_radio_turn_on(bcm);
4291 #endif
4293 //TODO: phymode
4294 //TODO: antennas
4295 if (adev->set_mask > 0)
4296 acx_s_update_card_settings(adev);
4297 acx_unlock(adev, flags);
4299 FN_EXIT0;
4300 return 0;
4304 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4308 int acx_config_interface(struct ieee80211_hw *ieee, int if_id,
4309 struct ieee80211_if_conf *conf)
4311 acx_device_t *adev = ieee2adev(ieee);
4312 unsigned long flags;
4313 int err = -ENODEV;
4314 FN_ENTER;
4315 if (!adev->interface.operating)
4316 goto err_out;
4317 acx_lock(adev, flags);
4319 if (adev->initialized)
4320 acx_select_opmode(adev);
4322 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4323 && (adev->interface.if_id == if_id)) {
4324 if (conf->bssid)
4326 adev->interface.bssid = conf->bssid;
4327 MAC_COPY(adev->bssid,conf->bssid);
4330 if ((conf->type == IEEE80211_IF_TYPE_AP)
4331 && (adev->interface.if_id == if_id)) {
4332 if ((conf->ssid_len > 0) && conf->ssid)
4334 adev->essid_len = conf->ssid_len;
4335 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4336 SET_BIT(adev->set_mask, SET_TEMPLATES);
4339 if (conf->beacon != 0)
4341 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4342 adev->beacon_cache = conf->beacon;
4343 SET_BIT(adev->set_mask, SET_TEMPLATES);
4345 if (adev->set_mask != 0)
4346 acx_s_update_card_settings(adev);
4347 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4348 acx_unlock(adev, flags);
4349 err = 0;
4350 err_out:
4351 FN_EXIT1(err);
4352 return err;
4356 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4360 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4361 struct ieee80211_tx_queue_stats *stats)
4363 // acx_device_t *adev = ndev2adev(net_dev);
4364 struct ieee80211_tx_queue_stats_data *data;
4365 int err = -ENODEV;
4367 FN_ENTER;
4369 // acx_lock(adev, flags);
4370 data = &(stats->data[0]);
4371 data->len = 0;
4372 data->limit = TX_CNT;
4373 data->count = 0;
4374 // acx_unlock(adev, flags);
4376 FN_EXIT0;
4377 return err;
4380 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4384 int acx_net_conf_tx(struct ieee80211_hw *hw,
4385 int queue, const struct ieee80211_tx_queue_params *params)
4387 FN_ENTER;
4388 // TODO();
4389 FN_EXIT0;
4390 return 0;
4393 static void keymac_write(acx_device_t * adev, u8 index, const u32 * addr)
4395 /* for keys 0-3 there is no associated mac address */
4396 if (index < 4)
4397 return;
4399 index -= 4;
4400 if (1) {
4401 TODO();
4403 bcm43xx_shm_write32(bcm,
4404 BCM43xx_SHM_HWMAC,
4405 index * 2,
4406 cpu_to_be32(*addr));
4407 bcm43xx_shm_write16(bcm,
4408 BCM43xx_SHM_HWMAC,
4409 (index * 2) + 1,
4410 cpu_to_be16(*((u16 *)(addr + 1))));
4412 } else {
4413 if (index < 8) {
4414 TODO(); /* Put them in the macaddress filter */
4415 } else {
4416 TODO();
4417 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4418 Keep in mind to update the count of keymacs in 0x003 */
4424 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4428 int acx_clear_keys(acx_device_t * adev)
4430 static const u32 zero_mac[2] = { 0 };
4431 unsigned int i, j, nr_keys = 54;
4432 u16 offset;
4434 /* FixMe:Check for Number of Keys available */
4436 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4438 for (i = 0; i < nr_keys; i++) {
4439 adev->key[i].enabled = 0;
4440 /* returns for i < 4 immediately */
4441 keymac_write(adev, i, zero_mac);
4443 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4444 0x100 + (i * 2), 0x0000);
4446 for (j = 0; j < 8; j++) {
4447 offset =
4448 adev->security_offset + (j * 4) +
4449 (i * ACX_SEC_KEYSIZE);
4451 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4452 offset, 0x0000);
4456 return 1;
4460 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4464 int acx_key_write(acx_device_t * adev,
4465 u8 index,
4466 u8 algorithm,
4467 const u8 * _key, int key_len, const u8 * mac_addr)
4469 // struct iw_point *dwrq = &wrqu->encoding;
4470 // acx_device_t *adev = ndev2adev(ndev);
4471 int result;
4473 FN_ENTER;
4475 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4476 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4478 acx_sem_lock(adev);
4480 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4481 if (key_len > 0) {
4482 /* if index is 0 or invalid, use default key */
4483 if (index > 3)
4484 index = (int)adev->wep_current_index;
4485 if ((algorithm == ACX_SEC_ALGO_WEP)
4486 || (algorithm == ACX_SEC_ALGO_WEP104)) {
4487 if (key_len > 29)
4488 key_len = 29; /* restrict it */
4490 if (key_len > 13) {
4491 /* 29*8 == 232, WEP256 */
4492 adev->wep_keys[index].size = 29;
4493 } else if (key_len > 5) {
4494 /* 13*8 == 104bit, WEP128 */
4495 adev->wep_keys[index].size = 13;
4496 } else if (key_len > 0) {
4497 /* 5*8 == 40bit, WEP64 */
4498 adev->wep_keys[index].size = 5;
4499 } else {
4500 /* disable key */
4501 adev->wep_keys[index].size = 0;
4504 memset(adev->wep_keys[index].key, 0,
4505 sizeof(adev->wep_keys[index].key));
4506 memcpy(adev->wep_keys[index].key, _key, key_len);
4508 } else {
4509 /* set transmit key */
4510 if (index <= 3)
4511 adev->wep_current_index = index;
4512 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4513 /* complain if we were not just setting
4514 * the key mode */
4515 // result = -EINVAL;
4516 // goto end_unlock;
4517 // }
4520 adev->wep_enabled = (algorithm == ALG_WEP);
4522 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4524 if (algorithm & IW_ENCODE_OPEN) {
4525 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4526 adev->wep_restricted = 0;
4528 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4529 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4530 adev->wep_restricted = 1;
4533 // adev->auth_alg = algorithm;
4534 /* set flag to make sure the card WEP settings get updated */
4535 if (adev->wep_enabled) {
4536 SET_BIT(adev->set_mask, GETSET_WEP);
4537 acx_s_update_card_settings(adev);
4538 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4541 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4542 dwrq->length, extra, dwrq->flags);
4543 for (index = 0; index <= 3; index++) {
4544 if (adev->wep_keys[index].size) {
4545 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4546 adev->wep_keys[index].index,
4547 (int) adev->wep_keys[index].size,
4548 adev->wep_keys[index].key);
4552 result = -EINPROGRESS;
4553 acx_sem_unlock(adev);
4555 FN_EXIT1(result);
4556 return result;
4562 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4566 int acx_net_set_key(struct ieee80211_hw *ieee,
4567 set_key_cmd cmd,
4568 u8 * addr, struct ieee80211_key_conf *key, int aid)
4570 // return 0;
4571 struct acx_device *adev = ieee2adev(ieee);
4572 unsigned long flags;
4573 u8 algorithm;
4574 u8 index;
4575 int err = -EINVAL;
4576 FN_ENTER;
4577 // TODO();
4578 switch (key->alg) {
4579 default:
4580 case ALG_NONE:
4581 case ALG_NULL:
4582 algorithm = ACX_SEC_ALGO_NONE;
4583 break;
4584 case ALG_WEP:
4585 if (key->keylen == 5)
4586 algorithm = ACX_SEC_ALGO_WEP;
4587 else
4588 algorithm = ACX_SEC_ALGO_WEP104;
4589 break;
4590 case ALG_TKIP:
4591 algorithm = ACX_SEC_ALGO_TKIP;
4592 break;
4593 case ALG_CCMP:
4594 algorithm = ACX_SEC_ALGO_AES;
4595 break;
4598 index = (u8) (key->keyidx);
4599 if (index >= ARRAY_SIZE(adev->key))
4600 goto out;
4601 acx_lock(adev, flags);
4602 switch (cmd) {
4603 case SET_KEY:
4604 err = acx_key_write(adev, index, algorithm,
4605 key->key, key->keylen, addr);
4606 if (err)
4607 goto out_unlock;
4608 key->hw_key_idx = index;
4609 CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);
4610 if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4611 adev->default_key_idx = index;
4612 adev->key[index].enabled = 1;
4613 break;
4614 case DISABLE_KEY:
4615 adev->key[index].enabled = 0;
4616 err = 0;
4617 break;
4618 case REMOVE_ALL_KEYS:
4619 acx_clear_keys(adev);
4620 err = 0;
4621 break;
4622 /* case ENABLE_COMPRESSION:
4623 case DISABLE_COMPRESSION:
4624 err = 0;
4625 break; */
4627 out_unlock:
4628 acx_unlock(adev, flags);
4629 out:
4630 FN_EXIT0;
4631 return err;
4636 /***********************************************************************
4637 ** Common function to parse ALL configoption struct formats
4638 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4639 ** FIXME: logging should be removed here and added to a /proc file instead
4641 ** Look into bcm43xx
4643 void
4644 acx_s_parse_configoption(acx_device_t * adev,
4645 const acx111_ie_configoption_t * pcfg)
4647 const u8 *pEle;
4648 int i;
4649 int is_acx111 = IS_ACX111(adev);
4651 if (acx_debug & L_DEBUG) {
4652 printk("configoption struct content:\n");
4653 acx_dump_bytes(pcfg, sizeof(*pcfg));
4656 if ((is_acx111 && (adev->eeprom_version == 5))
4657 || (!is_acx111 && (adev->eeprom_version == 4))
4658 || (!is_acx111 && (adev->eeprom_version == 5))) {
4659 /* these versions are known to be supported */
4660 } else {
4661 printk("unknown chip and EEPROM version combination (%s, v%d), "
4662 "don't know how to parse config options yet. "
4663 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4664 adev->eeprom_version);
4665 return;
4668 /* first custom-parse the first part which has chip-specific layout */
4670 pEle = (const u8 *)pcfg;
4672 pEle += 4; /* skip (type,len) header */
4674 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4675 pEle += sizeof(adev->cfgopt_NVSv);
4677 if (is_acx111) {
4678 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4679 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4681 adev->cfgopt_probe_delay = 200; /* good default value? */
4682 pEle += 2; /* FIXME: unknown, value 0x0001 */
4683 } else {
4684 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4685 pEle += sizeof(adev->cfgopt_MAC);
4687 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4688 pEle += sizeof(adev->cfgopt_probe_delay);
4689 if ((adev->cfgopt_probe_delay < 100)
4690 || (adev->cfgopt_probe_delay > 500)) {
4691 printk("strange probe_delay value %d, "
4692 "tweaking to 200\n", adev->cfgopt_probe_delay);
4693 adev->cfgopt_probe_delay = 200;
4697 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4698 pEle += sizeof(adev->cfgopt_eof_memory);
4700 printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n",
4701 adev->cfgopt_NVS_vendor_offs,
4702 adev->cfgopt_probe_delay, adev->cfgopt_eof_memory);
4704 adev->cfgopt_dot11CCAModes = *pEle++;
4705 adev->cfgopt_dot11Diversity = *pEle++;
4706 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4707 adev->cfgopt_dot11PBCCOption = *pEle++;
4708 adev->cfgopt_dot11ChannelAgility = *pEle++;
4709 adev->cfgopt_dot11PhyType = *pEle++;
4710 adev->cfgopt_dot11TempType = *pEle++;
4711 printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4712 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4713 adev->cfgopt_dot11CCAModes,
4714 adev->cfgopt_dot11Diversity,
4715 adev->cfgopt_dot11ShortPreambleOption,
4716 adev->cfgopt_dot11PBCCOption,
4717 adev->cfgopt_dot11ChannelAgility,
4718 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4720 /* then use common parsing for next part which has common layout */
4722 pEle++; /* skip table_count (6) */
4724 adev->cfgopt_antennas.type = pEle[0];
4725 adev->cfgopt_antennas.len = pEle[1];
4726 printk("AntennaID:%02X Len:%02X Data:",
4727 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4728 for (i = 0; i < pEle[1]; i++) {
4729 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4730 printk("%02X ", pEle[i + 2]);
4732 printk("\n");
4734 pEle += pEle[1] + 2;
4735 adev->cfgopt_power_levels.type = pEle[0];
4736 adev->cfgopt_power_levels.len = pEle[1];
4737 printk("PowerLevelID:%02X Len:%02X Data:",
4738 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4739 for (i = 0; i < pEle[1]; i++) {
4740 adev->cfgopt_power_levels.list[i] =
4741 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4742 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4744 printk("\n");
4746 pEle += pEle[1] * 2 + 2;
4747 adev->cfgopt_data_rates.type = pEle[0];
4748 adev->cfgopt_data_rates.len = pEle[1];
4749 printk("DataRatesID:%02X Len:%02X Data:",
4750 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4751 for (i = 0; i < pEle[1]; i++) {
4752 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4753 printk("%02X ", pEle[i + 2]);
4755 printk("\n");
4757 pEle += pEle[1] + 2;
4758 adev->cfgopt_domains.type = pEle[0];
4759 adev->cfgopt_domains.len = pEle[1];
4760 printk("DomainID:%02X Len:%02X Data:",
4761 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4762 for (i = 0; i < pEle[1]; i++) {
4763 adev->cfgopt_domains.list[i] = pEle[i + 2];
4764 printk("%02X ", pEle[i + 2]);
4766 printk("\n");
4768 pEle += pEle[1] + 2;
4769 adev->cfgopt_product_id.type = pEle[0];
4770 adev->cfgopt_product_id.len = pEle[1];
4771 for (i = 0; i < pEle[1]; i++) {
4772 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4774 printk("ProductID:%02X Len:%02X Data:%.*s\n",
4775 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4776 adev->cfgopt_product_id.len,
4777 (char *)adev->cfgopt_product_id.list);
4779 pEle += pEle[1] + 2;
4780 adev->cfgopt_manufacturer.type = pEle[0];
4781 adev->cfgopt_manufacturer.len = pEle[1];
4782 for (i = 0; i < pEle[1]; i++) {
4783 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4785 printk("ManufacturerID:%02X Len:%02X Data:%.*s\n",
4786 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4787 adev->cfgopt_manufacturer.len,
4788 (char *)adev->cfgopt_manufacturer.list);
4790 printk("EEPROM part:\n");
4791 for (i=0; i<58; i++) {
4792 printk("%02X =======> 0x%02X\n",
4793 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4799 /***********************************************************************
4800 ** Linux Kernel Specific
4802 static int __init acx_e_init_module(void)
4804 int r1, r2;
4806 acx_struct_size_check();
4808 printk("acx: this driver is still EXPERIMENTAL\n"
4809 "acx: reading README file and/or Craig's HOWTO is "
4810 "recommended, visit http://acx100.sourceforge.net/wiki in case "
4811 "of further questions/discussion\n");
4813 #if defined(CONFIG_ACX_MAC80211_PCI)
4814 r1 = acxpci_e_init_module();
4815 #else
4816 r1 = -EINVAL;
4817 #endif
4818 #if defined(CONFIG_ACX_MAC80211_USB)
4819 r2 = acxusb_e_init_module();
4820 #else
4821 r2 = -EINVAL;
4822 #endif
4823 if (r2 && r1) /* both failed! */
4824 return r2 ? r2 : r1;
4825 /* return success if at least one succeeded */
4826 return 0;
4829 static void __exit acx_e_cleanup_module(void)
4831 #if defined(CONFIG_ACX_MAC80211_PCI)
4832 acxpci_e_cleanup_module();
4833 #endif
4834 #if defined(CONFIG_ACX_MAC80211_USB)
4835 acxusb_e_cleanup_module();
4836 #endif
4839 module_init(acx_e_init_module)
4840 module_exit(acx_e_cleanup_module)