replaced acx_s_msleep with acx_s_mdelay (it now uses mdelay() instead of msleep(...
[acx-mac80211.git] / common.c
blobeb67ad93abc59bc80df5bd9c44912a0df38de54d
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 mdelay with logging
228 void acx_s_mdelay(int ms)
230 FN_ENTER;
231 mdelay(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);
1516 return err;
1519 static int acx_setup_modes_gphy(acx_device_t * adev)
1521 int err = 0;
1522 struct ieee80211_hw *hw = adev->ieee;
1523 struct ieee80211_hw_mode *mode;
1525 FN_ENTER;
1527 mode = &adev->modes[1];
1528 mode->mode = MODE_IEEE80211G;
1529 mode->num_channels = acx_chantable_size;
1530 mode->channels = channels;
1531 mode->num_rates = acx_g_ratetable_size;
1532 mode->rates = acx_g_ratetable;
1533 err = ieee80211_register_hwmode(hw,mode);
1535 FN_EXIT1(err);
1536 return err;
1539 int acx_setup_modes(acx_device_t * adev)
1541 int err = -ENOMEM;
1543 FN_ENTER;
1545 if (IS_ACX111(adev)) {
1546 /* adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);*/
1547 err = acx_setup_modes_gphy(adev);
1548 }/* else {
1549 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1551 err = acx_setup_modes_bphy(adev);
1552 /* if (err && adev->modes)
1553 kfree(adev->modes);*/
1554 FN_EXIT1(err);
1555 return err;
1559 /***********************************************************************
1560 ** acx_fill_beacon_or_proberesp_template
1562 ** Origin: derived from rt2x00 project
1564 static int
1565 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1566 struct acx_template_beacon *templ,
1567 struct sk_buff* skb /* in host order! */)
1569 FN_ENTER;
1571 memcpy(templ,skb->data, skb->len);
1572 FN_EXIT1(skb->len);
1573 return skb->len;
1576 /***********************************************************************
1577 ** acx_s_set_beacon_template
1581 static int
1582 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1584 struct acx_template_beacon bcn;
1585 int len, result;
1587 FN_ENTER;
1588 printk("Size of template: %08X, Size of beacon: %08X\n",sizeof(struct acx_template_beacon),skb->len);
1589 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1590 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1592 FN_EXIT1(result);
1593 return result;
1596 /***********************************************************************
1597 ** acx_cmd_join_bssid
1599 ** Common code for both acx100 and acx111.
1601 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1602 static const u8 bitpos2genframe_txrate[] = {
1603 10, /* 0. 1 Mbit/s */
1604 20, /* 1. 2 Mbit/s */
1605 55, /* 2. 5.5 Mbit/s */
1606 0x0B, /* 3. 6 Mbit/s */
1607 0x0F, /* 4. 9 Mbit/s */
1608 110, /* 5. 11 Mbit/s */
1609 0x0A, /* 6. 12 Mbit/s */
1610 0x0E, /* 7. 18 Mbit/s */
1611 220, /* 8. 22 Mbit/s */
1612 0x09, /* 9. 24 Mbit/s */
1613 0x0D, /* 10. 36 Mbit/s */
1614 0x08, /* 11. 48 Mbit/s */
1615 0x0C, /* 12. 54 Mbit/s */
1616 10, /* 13. 1 Mbit/s, should never happen */
1617 10, /* 14. 1 Mbit/s, should never happen */
1618 10, /* 15. 1 Mbit/s, should never happen */
1621 /* Looks scary, eh?
1622 ** Actually, each one compiled into one AND and one SHIFT,
1623 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1624 static inline unsigned int rate111to5bits(unsigned int rate)
1626 return (rate & 0x7)
1627 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1628 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1632 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1634 acx_joinbss_t tmp;
1635 int dtim_interval;
1636 int i;
1638 if (mac_is_zero(bssid))
1639 return;
1641 FN_ENTER;
1643 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1644 1 : adev->dtim_interval;
1646 memset(&tmp, 0, sizeof(tmp));
1648 for (i = 0; i < ETH_ALEN; i++) {
1649 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1652 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1654 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1655 ** are sent with one of these rates */
1656 if (IS_ACX111(adev)) {
1657 /* It was experimentally determined that rates_basic
1658 ** can take 11g rates as well, not only rates
1659 ** defined with JOINBSS_RATES_BASIC111_nnn.
1660 ** Just use RATE111_nnn constants... */
1661 tmp.u.acx111.dtim_interval = dtim_interval;
1662 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1663 log(L_ASSOC, "rates_basic:%04X, rates_supported:%04X\n",
1664 adev->rate_basic, adev->rate_oper);
1665 } else {
1666 tmp.u.acx100.dtim_interval = dtim_interval;
1667 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1668 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1669 log(L_ASSOC, "rates_basic:%04X->%02X, "
1670 "rates_supported:%04X->%02X\n",
1671 adev->rate_basic, tmp.u.acx100.rates_basic,
1672 adev->rate_oper, tmp.u.acx100.rates_supported);
1675 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1676 ** will be sent (rate/modulation/preamble) */
1677 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1678 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1679 /* we can use short pre *if* all peers can understand it */
1680 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1682 /* we switch fw to STA mode in MONITOR mode, it seems to be
1683 ** the only mode where fw does not emit beacons by itself
1684 ** but allows us to send anything (we really want to retain
1685 ** ability to tx arbitrary frames in MONITOR mode)
1687 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1688 tmp.channel = adev->channel;
1689 tmp.essid_len = adev->essid_len;
1691 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1692 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1694 log(L_ASSOC|L_DEBUG, "BSS_Type = %u\n", tmp.macmode);
1695 acxlog_mac(L_ASSOC|L_DEBUG, "JoinBSSID MAC:", adev->bssid, "\n");
1697 /* acx_update_capabilities(adev); */
1698 FN_EXIT0;
1701 /***********************************************************************
1702 ** acxpci_i_set_multicast_list
1703 ** FIXME: most likely needs refinement
1705 void
1706 acx_i_set_multicast_list(struct ieee80211_hw *hw,
1707 unsigned short netflags, int mc_count)
1709 acx_device_t *adev = ieee2adev(hw);
1710 unsigned long flags;
1712 FN_ENTER;
1714 acx_lock(adev, flags);
1716 if (netflags & (IFF_PROMISC | IFF_ALLMULTI)) {
1717 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1718 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1719 SET_BIT(adev->set_mask, SET_RXCONFIG);
1720 /* let kernel know in case *we* needed to set promiscuous */
1721 } else {
1722 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1723 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1724 SET_BIT(adev->set_mask, SET_RXCONFIG);
1727 /* cannot update card settings directly here, atomic context */
1728 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
1730 acx_unlock(adev, flags);
1732 FN_EXIT0;
1735 /***********************************************************************
1736 ** acx111 feature config
1738 ** Obvious
1740 static int
1741 acx111_s_get_feature_config(acx_device_t * adev,
1742 u32 * feature_options, u32 * data_flow_options)
1744 struct acx111_ie_feature_config feat;
1746 FN_ENTER;
1748 if (!IS_ACX111(adev)) {
1749 return NOT_OK;
1752 memset(&feat, 0, sizeof(feat));
1754 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1755 FN_EXIT1(NOT_OK);
1756 return NOT_OK;
1758 log(L_DEBUG,
1759 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1760 feat.feature_options, feat.data_flow_options);
1762 if (feature_options)
1763 *feature_options = le32_to_cpu(feat.feature_options);
1764 if (data_flow_options)
1765 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1767 FN_EXIT0;
1768 return OK;
1772 static int
1773 acx111_s_set_feature_config(acx_device_t * adev,
1774 u32 feature_options, u32 data_flow_options,
1775 unsigned int mode
1776 /* 0 == remove, 1 == add, 2 == set */ )
1778 struct acx111_ie_feature_config feat;
1780 FN_ENTER;
1782 if (!IS_ACX111(adev)) {
1783 FN_EXIT1(NOT_OK);
1784 return NOT_OK;
1787 if ((mode < 0) || (mode > 2)) {
1788 FN_EXIT1(NOT_OK);
1789 return NOT_OK;
1792 if (mode != 2)
1793 /* need to modify old data */
1794 acx111_s_get_feature_config(adev, &feat.feature_options,
1795 &feat.data_flow_options);
1796 else {
1797 /* need to set a completely new value */
1798 feat.feature_options = 0;
1799 feat.data_flow_options = 0;
1802 if (mode == 0) { /* remove */
1803 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1804 CLEAR_BIT(feat.data_flow_options,
1805 cpu_to_le32(data_flow_options));
1806 } else { /* add or set */
1807 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1808 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1811 log(L_DEBUG,
1812 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1813 "new: feature 0x%08X dataflow 0x%08X\n",
1814 feature_options, data_flow_options, mode,
1815 le32_to_cpu(feat.feature_options),
1816 le32_to_cpu(feat.data_flow_options));
1818 if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1819 FN_EXIT1(NOT_OK);
1820 return NOT_OK;
1823 FN_EXIT0;
1824 return OK;
1827 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1829 return acx111_s_set_feature_config(adev, f, d, 0);
1831 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1833 return acx111_s_set_feature_config(adev, f, d, 1);
1835 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1837 return acx111_s_set_feature_config(adev, f, d, 2);
1841 /***********************************************************************
1842 ** acx100_s_init_memory_pools
1844 static int
1845 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1847 acx100_ie_memblocksize_t MemoryBlockSize;
1848 acx100_ie_memconfigoption_t MemoryConfigOption;
1849 int TotalMemoryBlocks;
1850 int RxBlockNum;
1851 int TotalRxBlockSize;
1852 int TxBlockNum;
1853 int TotalTxBlockSize;
1855 FN_ENTER;
1857 /* Let's see if we can follow this:
1858 first we select our memory block size (which I think is
1859 completely arbitrary) */
1860 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1862 /* Then we alert the card to our decision of block size */
1863 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
1864 goto bad;
1867 /* We figure out how many total blocks we can create, using
1868 the block size we chose, and the beginning and ending
1869 memory pointers, i.e.: end-start/size */
1870 TotalMemoryBlocks =
1871 (le32_to_cpu(mmt->PoolEnd) -
1872 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1874 log(L_DEBUG, "TotalMemoryBlocks=%u (%u bytes)\n",
1875 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1877 /* MemoryConfigOption.DMA_config bitmask:
1878 access to ACX memory is to be done:
1879 0x00080000 using PCI conf space?!
1880 0x00040000 using IO instructions?
1881 0x00000000 using memory access instructions
1882 0x00020000 using local memory block linked list (else what?)
1883 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1885 if (IS_PCI(adev)) {
1886 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1887 /* Declare start of the Rx host pool */
1888 MemoryConfigOption.pRxHostDesc =
1889 cpu2acx(adev->rxhostdesc_startphy);
1890 log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
1891 acx2cpu(MemoryConfigOption.pRxHostDesc),
1892 (long)adev->rxhostdesc_startphy);
1893 } else {
1894 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1897 /* 50% of the allotment of memory blocks go to tx descriptors */
1898 TxBlockNum = TotalMemoryBlocks / 2;
1899 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1901 /* and 50% go to the rx descriptors */
1902 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1903 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1905 /* size of the tx and rx descriptor queues */
1906 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1907 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1908 log(L_DEBUG, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u "
1909 "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum,
1910 TotalTxBlockSize, TotalRxBlockSize);
1913 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1914 MemoryConfigOption.rx_mem =
1915 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1917 /* align the rx descriptor queue to units of 0x20
1918 * and offset it by the tx descriptor queue */
1919 MemoryConfigOption.tx_mem =
1920 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
1921 0x1f) & ~0x1f);
1922 log(L_DEBUG, "rx_mem %08X rx_mem %08X\n", MemoryConfigOption.tx_mem,
1923 MemoryConfigOption.rx_mem);
1925 /* alert the device to our decision */
1926 if (OK !=
1927 acx_s_configure(adev, &MemoryConfigOption,
1928 ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
1929 goto bad;
1932 /* and tell the device to kick it into gear */
1933 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
1934 goto bad;
1936 FN_EXIT1(OK);
1937 return OK;
1938 bad:
1939 FN_EXIT1(NOT_OK);
1940 return NOT_OK;
1944 /***********************************************************************
1945 ** acx100_s_create_dma_regions
1947 ** Note that this fn messes up heavily with hardware, but we cannot
1948 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1950 static int acx100_s_create_dma_regions(acx_device_t * adev)
1952 acx100_ie_queueconfig_t queueconf;
1953 acx_ie_memmap_t memmap;
1954 int res = NOT_OK;
1955 u32 tx_queue_start, rx_queue_start;
1957 FN_ENTER;
1959 /* read out the acx100 physical start address for the queues */
1960 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1961 goto fail;
1964 tx_queue_start = le32_to_cpu(memmap.QueueStart);
1965 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
1967 log(L_DEBUG, "initializing Queue Indicator\n");
1969 memset(&queueconf, 0, sizeof(queueconf));
1971 /* Not needed for PCI, so we can avoid setting them altogether */
1972 if (IS_USB(adev)) {
1973 queueconf.NumTxDesc = USB_TX_CNT;
1974 queueconf.NumRxDesc = USB_RX_CNT;
1977 /* calculate size of queues */
1978 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
1979 RX_CNT * sizeof(rxdesc_t) + 8);
1980 queueconf.NumTxQueues = 1; /* number of tx queues */
1981 /* sets the beginning of the tx descriptor queue */
1982 queueconf.TxQueueStart = memmap.QueueStart;
1983 /* done by memset: queueconf.TxQueuePri = 0; */
1984 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
1985 queueconf.QueueOptions = 1; /* auto reset descriptor */
1986 /* sets the end of the rx descriptor queue */
1987 queueconf.QueueEnd =
1988 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
1990 /* sets the beginning of the next queue */
1991 queueconf.HostQueueEnd =
1992 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
1993 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
1994 goto fail;
1997 if (IS_PCI(adev)) {
1998 /* sets the beginning of the rx descriptor queue, after the tx descrs */
1999 if (OK != acxpci_s_create_hostdesc_queues(adev))
2000 goto fail;
2001 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2004 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2005 goto fail;
2008 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
2009 0x1f) & ~0x1f);
2011 if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2012 goto fail;
2015 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
2016 goto fail;
2019 res = OK;
2020 goto end;
2022 fail:
2023 acx_s_mdelay(1000); /* ? */
2024 if (IS_PCI(adev))
2025 acxpci_free_desc_queues(adev);
2026 end:
2027 FN_EXIT1(res);
2028 return res;
2032 /***********************************************************************
2033 ** acx111_s_create_dma_regions
2035 ** Note that this fn messes heavily with hardware, but we cannot
2036 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2038 #define ACX111_PERCENT(percent) ((percent)/5)
2040 static int acx111_s_create_dma_regions(acx_device_t * adev)
2042 struct acx111_ie_memoryconfig memconf;
2043 struct acx111_ie_queueconfig queueconf;
2044 u32 tx_queue_start, rx_queue_start;
2046 FN_ENTER;
2048 /* Calculate memory positions and queue sizes */
2050 /* Set up our host descriptor pool + data pool */
2051 if (IS_PCI(adev)) {
2052 if (OK != acxpci_s_create_hostdesc_queues(adev))
2053 goto fail;
2056 memset(&memconf, 0, sizeof(memconf));
2057 /* the number of STAs (STA contexts) to support
2058 ** NB: was set to 1 and everything seemed to work nevertheless... */
2059 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
2060 /* specify the memory block size. Default is 256 */
2061 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
2062 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
2063 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
2064 /* set the count of our queues
2065 ** NB: struct acx111_ie_memoryconfig shall be modified
2066 ** if we ever will switch to more than one rx and/or tx queue */
2067 memconf.count_rx_queues = 1;
2068 memconf.count_tx_queues = 1;
2069 /* 0 == Busmaster Indirect Memory Organization, which is what we want
2070 * (using linked host descs with their allocated mem).
2071 * 2 == Generic Bus Slave */
2072 /* done by memset: memconf.options = 0; */
2073 /* let's use 25% for fragmentations and 75% for frame transfers
2074 * (specified in units of 5%) */
2075 memconf.fragmentation = ACX111_PERCENT(75);
2076 /* Rx descriptor queue config */
2077 memconf.rx_queue1_count_descs = RX_CNT;
2078 memconf.rx_queue1_type = 7; /* must be set to 7 */
2079 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2080 if (IS_PCI(adev)) {
2081 memconf.rx_queue1_host_rx_start =
2082 cpu2acx(adev->rxhostdesc_startphy);
2084 /* Tx descriptor queue config */
2085 memconf.tx_queue1_count_descs = TX_CNT;
2086 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2088 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
2089 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2090 ** But it is actually correct wrt IE numbers.
2091 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
2092 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2093 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2094 if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
2095 goto fail;
2098 acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
2100 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2101 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2103 log(L_INIT, "dump queue head (from card):\n"
2104 "len: %u\n"
2105 "tx_memory_block_address: %X\n"
2106 "rx_memory_block_address: %X\n"
2107 "tx1_queue address: %X\n"
2108 "rx1_queue address: %X\n",
2109 le16_to_cpu(queueconf.len),
2110 le32_to_cpu(queueconf.tx_memory_block_address),
2111 le32_to_cpu(queueconf.rx_memory_block_address),
2112 tx_queue_start, rx_queue_start);
2114 if (IS_PCI(adev))
2115 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2117 FN_EXIT1(OK);
2118 return OK;
2119 fail:
2120 if (IS_PCI(adev))
2121 acxpci_free_desc_queues(adev);
2123 FN_EXIT1(NOT_OK);
2124 return NOT_OK;
2128 /***********************************************************************
2130 static void acx_s_initialize_rx_config(acx_device_t * adev)
2132 struct {
2133 u16 id;
2134 u16 len;
2135 u16 rx_cfg1;
2136 u16 rx_cfg2;
2137 } ACX_PACKED cfg;
2138 switch (adev->mode) {
2139 case ACX_MODE_MONITOR:
2140 adev->rx_config_1 = (u16) (0
2141 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2142 /* | RX_CFG1_FILTER_SSID */
2143 /* | RX_CFG1_FILTER_BCAST */
2144 /* | RX_CFG1_RCV_MC_ADDR1 */
2145 /* | RX_CFG1_RCV_MC_ADDR0 */
2146 /* | RX_CFG1_FILTER_ALL_MULTI */
2147 /* | RX_CFG1_FILTER_BSSID */
2148 /* | RX_CFG1_FILTER_MAC */
2149 | RX_CFG1_RCV_PROMISCUOUS
2150 | RX_CFG1_INCLUDE_FCS
2151 /* | RX_CFG1_INCLUDE_PHY_HDR */
2153 adev->rx_config_2 = (u16) (0
2154 | RX_CFG2_RCV_ASSOC_REQ
2155 | RX_CFG2_RCV_AUTH_FRAMES
2156 | RX_CFG2_RCV_BEACON_FRAMES
2157 | RX_CFG2_RCV_CONTENTION_FREE
2158 | RX_CFG2_RCV_CTRL_FRAMES
2159 | RX_CFG2_RCV_DATA_FRAMES
2160 | RX_CFG2_RCV_BROKEN_FRAMES
2161 | RX_CFG2_RCV_MGMT_FRAMES
2162 | RX_CFG2_RCV_PROBE_REQ
2163 | RX_CFG2_RCV_PROBE_RESP
2164 | RX_CFG2_RCV_ACK_FRAMES
2165 | RX_CFG2_RCV_OTHER);
2166 break;
2167 default:
2168 adev->rx_config_1 = (u16) (0
2169 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2170 /* | RX_CFG1_FILTER_SSID */
2171 /* | RX_CFG1_FILTER_BCAST */
2172 /* | RX_CFG1_RCV_MC_ADDR1 */
2173 /* | RX_CFG1_RCV_MC_ADDR0 */
2174 /* | RX_CFG1_FILTER_ALL_MULTI */
2175 /* | RX_CFG1_FILTER_BSSID */
2176 /* | RX_CFG1_FILTER_MAC */
2177 | RX_CFG1_RCV_PROMISCUOUS
2178 /* | RX_CFG1_INCLUDE_FCS */
2179 /* | RX_CFG1_INCLUDE_PHY_HDR */
2181 adev->rx_config_2 = (u16) (0
2182 | RX_CFG2_RCV_ASSOC_REQ
2183 | RX_CFG2_RCV_AUTH_FRAMES
2184 | RX_CFG2_RCV_BEACON_FRAMES
2185 | RX_CFG2_RCV_CONTENTION_FREE
2186 | RX_CFG2_RCV_CTRL_FRAMES
2187 | RX_CFG2_RCV_DATA_FRAMES
2188 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2189 | RX_CFG2_RCV_MGMT_FRAMES
2190 | RX_CFG2_RCV_PROBE_REQ
2191 | RX_CFG2_RCV_PROBE_RESP
2192 | RX_CFG2_RCV_ACK_FRAMES
2193 | RX_CFG2_RCV_OTHER);
2194 break;
2196 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2198 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2199 || (adev->firmware_numver >= 0x02000000))
2200 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2201 else
2202 adev->phy_header_len = 0;
2204 log(L_INIT, "setting RXconfig to %04X:%04X\n",
2205 adev->rx_config_1, adev->rx_config_2);
2206 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2207 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2208 acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
2212 /***********************************************************************
2213 ** acx_s_set_defaults
2215 void acx_s_set_defaults(acx_device_t * adev)
2217 unsigned long flags;
2219 FN_ENTER;
2221 acx_lock(adev, flags);
2222 /* do it before getting settings, prevent bogus channel 0 warning */
2223 adev->channel = 1;
2225 /* query some settings from the card.
2226 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2227 * query is REQUIRED, otherwise the card won't work correctly! */
2228 adev->get_mask =
2229 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2230 GETSET_REG_DOMAIN;
2231 /* Only ACX100 supports ED and CCA */
2232 if (IS_ACX100(adev))
2233 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2235 acx_s_update_card_settings(adev);
2238 /* set our global interrupt mask */
2239 if (IS_PCI(adev))
2240 acxpci_set_interrupt_mask(adev);
2242 adev->led_power = 1; /* LED is active on startup */
2243 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2244 adev->brange_time_last_state_change = jiffies;
2246 /* copy the MAC address we just got from the card
2247 * into our MAC address used during current 802.11 session */
2248 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
2249 MAC_BCAST(adev->ap);
2251 adev->essid_len =
2252 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2253 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2254 adev->essid_active = 1;
2256 /* we have a nick field to waste, so why not abuse it
2257 * to announce the driver version? ;-) */
2258 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2260 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2261 /* first regulatory domain entry in EEPROM == default reg. domain */
2262 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2265 /* 0xffff would be better, but then we won't get a "scan complete"
2266 * interrupt, so our current infrastructure will fail: */
2267 adev->scan_count = 1;
2268 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2269 adev->scan_duration = 100;
2270 adev->scan_probe_delay = 200;
2271 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2272 adev->scan_rate = ACX_SCAN_RATE_1;
2275 adev->mode = ACX_MODE_2_STA;
2276 adev->listen_interval = 100;
2277 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2278 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2280 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2282 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2283 adev->frag_threshold = 2346;
2285 /* use standard default values for retry limits */
2286 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2287 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2289 adev->preamble_mode = 2; /* auto */
2290 adev->fallback_threshold = 3;
2291 adev->stepup_threshold = 10;
2292 adev->rate_bcast = RATE111_1;
2293 adev->rate_bcast100 = RATE100_1;
2294 adev->rate_basic = RATE111_1 | RATE111_2;
2295 adev->rate_auto = 1;
2296 if (IS_ACX111(adev)) {
2297 adev->rate_oper = RATE111_ALL;
2298 } else {
2299 adev->rate_oper = RATE111_ACX100_COMPAT;
2302 /* Supported Rates element - the rates here are given in units of
2303 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2304 acx_l_update_ratevector(adev);
2306 /* set some more defaults */
2307 if (IS_ACX111(adev)) {
2308 /* 30mW (15dBm) is default, at least in my acx111 card: */
2309 adev->tx_level_dbm = 15;
2310 } else {
2311 /* don't use max. level, since it might be dangerous
2312 * (e.g. WRT54G people experience
2313 * excessive Tx power damage!) */
2314 adev->tx_level_dbm = 18;
2316 /* adev->tx_level_auto = 1; */
2317 if (IS_ACX111(adev)) {
2318 /* start with sensitivity level 1 out of 3: */
2319 adev->sensitivity = 1;
2322 /* #define ENABLE_POWER_SAVE */
2323 #ifdef ENABLE_POWER_SAVE
2324 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2325 adev->ps_listen_interval = 1;
2326 adev->ps_options =
2327 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2328 adev->ps_hangover_period = 30;
2329 adev->ps_enhanced_transition_time = 0;
2330 #else
2331 adev->ps_wakeup_cfg = 0;
2332 adev->ps_listen_interval = 0;
2333 adev->ps_options = 0;
2334 adev->ps_hangover_period = 0;
2335 adev->ps_enhanced_transition_time = 0;
2336 #endif
2338 /* These settings will be set in fw on ifup */
2339 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2340 /* configure card to do rate fallback when in auto rate mode */
2341 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2342 /* better re-init the antenna value we got above */
2343 | GETSET_ANTENNA
2344 #if POWER_SAVE_80211
2345 | GETSET_POWER_80211
2346 #endif
2349 acx_unlock(adev, flags);
2350 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2352 acx_s_initialize_rx_config(adev);
2354 FN_EXIT0;
2358 /***********************************************************************
2359 ** FIXME: this should be solved in a general way for all radio types
2360 ** by decoding the radio firmware module,
2361 ** since it probably has some standard structure describing how to
2362 ** set the power level of the radio module which it controls.
2363 ** Or maybe not, since the radio module probably has a function interface
2364 ** instead which then manages Tx level programming :-\
2366 ** Obvious
2368 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2370 struct acx111_ie_tx_level tx_level;
2372 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2373 * 1 (30mW) [15dBm]
2374 * 2 (10mW) [10dBm]
2375 * For now, just assume all other acx111 cards have the same.
2376 * FIXME: Ideally we would query it here, but we first need a
2377 * standard way to query individual configoptions easily.
2378 * Well, now we have proper cfgopt txpower variables, but this still
2379 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2380 if (level_dbm <= 12) {
2381 tx_level.level = 2; /* 10 dBm */
2382 adev->tx_level_dbm = 10;
2383 } else {
2384 tx_level.level = 1; /* 15 dBm */
2385 adev->tx_level_dbm = 15;
2387 /* if (level_dbm != adev->tx_level_dbm)
2388 log(L_INIT, "acx111 firmware has specific "
2389 "power levels only: adjusted %d dBm to %d dBm!\n",
2390 level_dbm, adev->tx_level_dbm);
2392 return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
2395 static int acx_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2397 if (IS_ACX111(adev)) {
2398 return acx111_s_set_tx_level(adev, level_dbm);
2400 if (IS_PCI(adev)) {
2401 return acx100pci_s_set_tx_level(adev, level_dbm);
2403 return OK;
2406 /***********************************************************************
2407 ** acx_l_process_rxbuf
2409 ** NB: used by USB code also
2411 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2413 struct ieee80211_hdr *hdr;
2414 u16 fc, buf_len;
2415 hdr = acx_get_wlan_hdr(adev, rxbuf);
2416 fc = le16_to_cpu(hdr->frame_control);
2417 /* length of frame from control field to first byte of FCS */
2418 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2420 if (unlikely(acx_debug & L_DATA)) {
2421 printk("rx: 802.11 buf[%u]: ", buf_len);
2422 acx_dump_bytes(hdr, buf_len);
2426 acx_l_rx(adev, rxbuf);
2427 /* Now check Rx quality level, AFTER processing packet.
2428 * I tried to figure out how to map these levels to dBm
2429 * values, but for the life of me I really didn't
2430 * manage to get it. Either these values are not meant to
2431 * be expressed in dBm, or it's some pretty complicated
2432 * calculation. */
2434 #ifdef FROM_SCAN_SOURCE_ONLY
2435 /* only consider packets originating from the MAC
2436 * address of the device that's managing our BSSID.
2437 * Disable it for now, since it removes information (levels
2438 * from different peers) and slows the Rx path. *//*
2439 if (adev->ap_client && mac_is_equal(hdr->a2, adev->ap_client->address)) {
2441 #endif
2445 /***********************************************************************
2446 ** acx_l_handle_txrate_auto
2448 ** Theory of operation:
2449 ** client->rate_cap is a bitmask of rates client is capable of.
2450 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2451 ** It is set as a result of iwconfig rate N [auto]
2452 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2453 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2454 ** auto (0x00ff == 18Mbit or any lower value),
2455 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2457 ** client->rate_cur is a value for rate111 field in tx descriptor.
2458 ** It is always set to txrate_cfg sans zero or more most significant
2459 ** bits. This routine handles selection of new rate_cur value depending on
2460 ** outcome of last tx event.
2462 ** client->rate_100 is a precalculated rate value for acx100
2463 ** (we can do without it, but will need to calculate it on each tx).
2465 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2466 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2467 ** In theory you can implement it, but so far it is considered not worth doing.
2469 ** 22Mbit, of course, is PBCC always. */
2471 /* maps acx100 tx descr rate field to acx111 one */
2473 static u16 rate100to111(u8 r)
2475 switch (r) {
2476 case RATE100_1:
2477 return RATE111_1;
2478 case RATE100_2:
2479 return RATE111_2;
2480 case RATE100_5:
2481 case (RATE100_5 | RATE100_PBCC511):
2482 return RATE111_5;
2483 case RATE100_11:
2484 case (RATE100_11 | RATE100_PBCC511):
2485 return RATE111_11;
2486 case RATE100_22:
2487 return RATE111_22;
2488 default:
2489 printk("acx: unexpected acx100 txrate: %u! "
2490 "Please report\n", r);
2491 return RATE111_1;
2498 acx_i_start_xmit(struct ieee80211_hw *hw,
2499 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2501 acx_device_t *adev = ieee2adev(hw);
2502 tx_t *tx;
2503 void *txbuf;
2504 unsigned long flags;
2506 int txresult = NOT_OK;
2508 FN_ENTER;
2510 if (unlikely(!skb)) {
2511 /* indicate success */
2512 txresult = OK;
2513 goto end_no_unlock;
2516 if (unlikely(!adev)) {
2517 goto end_no_unlock;
2521 acx_lock(adev, flags);
2523 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2524 goto end;
2526 if (unlikely(!adev->initialized)) {
2527 goto end;
2530 tx = acx_l_alloc_tx(adev);
2532 if (unlikely(!tx)) {
2533 printk_ratelimited("%s: start_xmit: txdesc ring is full, "
2534 "dropping tx\n", wiphy_name(adev->ieee->wiphy));
2535 txresult = NOT_OK;
2536 goto end;
2539 txbuf = acx_l_get_txbuf(adev, tx);
2541 if (unlikely(!txbuf)) {
2542 /* Card was removed */
2543 txresult = NOT_OK;
2544 acx_l_dealloc_tx(adev, tx);
2545 goto end;
2547 memcpy(txbuf, skb->data, skb->len);
2549 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2551 txresult = OK;
2552 adev->stats.tx_packets++;
2553 adev->stats.tx_bytes += skb->len;
2555 end:
2556 acx_unlock(adev, flags);
2558 end_no_unlock:
2560 FN_EXIT1(txresult);
2561 return txresult;
2563 /***********************************************************************
2564 ** acx_l_update_ratevector
2566 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2568 const u8 acx_bitpos2ratebyte[] = {
2569 DOT11RATEBYTE_1,
2570 DOT11RATEBYTE_2,
2571 DOT11RATEBYTE_5_5,
2572 DOT11RATEBYTE_6_G,
2573 DOT11RATEBYTE_9_G,
2574 DOT11RATEBYTE_11,
2575 DOT11RATEBYTE_12_G,
2576 DOT11RATEBYTE_18_G,
2577 DOT11RATEBYTE_22,
2578 DOT11RATEBYTE_24_G,
2579 DOT11RATEBYTE_36_G,
2580 DOT11RATEBYTE_48_G,
2581 DOT11RATEBYTE_54_G,
2584 void acx_l_update_ratevector(acx_device_t * adev)
2586 u16 bcfg = adev->rate_basic;
2587 u16 ocfg = adev->rate_oper;
2588 u8 *supp = adev->rate_supported;
2589 const u8 *dot11 = acx_bitpos2ratebyte;
2591 FN_ENTER;
2593 while (ocfg) {
2594 if (ocfg & 1) {
2595 *supp = *dot11;
2596 if (bcfg & 1) {
2597 *supp |= 0x80;
2599 supp++;
2601 dot11++;
2602 ocfg >>= 1;
2603 bcfg >>= 1;
2605 adev->rate_supported_len = supp - adev->rate_supported;
2606 if (acx_debug & L_ASSOC) {
2607 printk("new ratevector: ");
2608 acx_dump_bytes(adev->rate_supported, adev->rate_supported_len);
2610 FN_EXIT0;
2613 /***********************************************************************
2614 ** acx_i_timer
2616 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2618 ** Obvious
2620 void acx_i_timer(unsigned long address)
2622 unsigned long flags;
2623 acx_device_t *adev = (acx_device_t *) address;
2625 FN_ENTER;
2627 acx_lock(adev, flags);
2629 FIXME();
2630 /* We need calibration and stats gather tasks to perform here */
2632 acx_unlock(adev, flags);
2634 FN_EXIT0;
2638 /***********************************************************************
2639 ** acx_set_timer
2641 ** Sets the 802.11 state management timer's timeout.
2643 ** Linux derived
2645 void acx_set_timer(acx_device_t * adev, int timeout_us)
2647 FN_ENTER;
2649 log(L_DEBUG | L_IRQ, "%s(%u ms)\n", __func__, timeout_us / 1000);
2650 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2651 printk("attempt to set the timer "
2652 "when the card interface is not up!\n");
2653 goto end;
2656 /* first check if the timer was already initialized, THEN modify it */
2657 if (adev->mgmt_timer.function) {
2658 mod_timer(&adev->mgmt_timer,
2659 jiffies + (timeout_us * HZ / 1000000));
2661 end:
2662 FN_EXIT0;
2665 /** acx_plcp_get_bitrate_cck
2667 ** Obvious
2669 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2671 switch (plcp) {
2672 case 0x0A:
2673 return ACX_CCK_RATE_1MB;
2674 case 0x14:
2675 return ACX_CCK_RATE_2MB;
2676 case 0x37:
2677 return ACX_CCK_RATE_5MB;
2678 case 0x6E:
2679 return ACX_CCK_RATE_11MB;
2681 return 0;
2684 /* Extract the bitrate out of an OFDM PLCP header. */
2685 /** Obvious **/
2686 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2688 switch (plcp & 0xF) {
2689 case 0xB:
2690 return ACX_OFDM_RATE_6MB;
2691 case 0xF:
2692 return ACX_OFDM_RATE_9MB;
2693 case 0xA:
2694 return ACX_OFDM_RATE_12MB;
2695 case 0xE:
2696 return ACX_OFDM_RATE_18MB;
2697 case 0x9:
2698 return ACX_OFDM_RATE_24MB;
2699 case 0xD:
2700 return ACX_OFDM_RATE_36MB;
2701 case 0x8:
2702 return ACX_OFDM_RATE_48MB;
2703 case 0xC:
2704 return ACX_OFDM_RATE_54MB;
2706 return 0;
2710 /***********************************************************************
2711 ** acx_l_rx
2713 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2714 ** buffer and feeds it to the network stack via netif_rx().
2716 ** Look to bcm43xx or p54
2718 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2721 struct ieee80211_rx_status* status = &adev->rx_status;
2722 struct ieee80211_hdr *w_hdr;
2723 int buflen;
2724 FN_ENTER;
2726 if (likely(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2727 struct sk_buff *skb;
2728 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2729 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2730 skb = dev_alloc_skb(buflen + 2);
2731 skb_reserve(skb, 2);
2732 skb_put(skb, buflen);
2733 memcpy(skb->data, w_hdr, buflen);
2735 // memset(&status, 0, sizeof(status));
2737 if (likely(skb)) {
2738 adev->acx_stats.last_rx = jiffies;
2739 status->mactime = rxbuf->time;
2740 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2741 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr);
2742 status->flag = 0;
2743 status->rate = rxbuf->phy_plcp_signal;
2744 status->antenna = 1;
2746 #ifndef OLD_QUALITY
2747 qual = acx_signal_determine_quality(adev->wstats.qual.level,
2748 adev->wstats.qual.noise);
2749 #else
2750 qual = (adev->wstats.qual.noise <= 100) ?
2751 100 - adev->wstats.qual.noise : 0;
2752 #endif
2753 adev->wstats.qual.qual = qual;
2754 adev->wstats.qual.updated = 7; *//* all 3 indicators updated */
2756 #ifdef FROM_SCAN_SOURCE_ONLY
2758 #endif
2760 if (rxbuf->phy_stat_baseband & (1 << 3)) /* Uses OFDM */
2762 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2763 } else
2765 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2767 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2768 adev->stats.rx_packets++;
2769 adev->stats.rx_bytes += skb->len;
2772 FN_EXIT0;
2777 /***********************************************************************
2778 ** acx_s_read_fw
2780 ** Loads a firmware image
2782 ** Returns:
2783 ** 0 unable to load file
2784 ** pointer to firmware success
2786 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2787 u32 * size)
2789 firmware_image_t *res;
2790 const struct firmware *fw_entry;
2792 res = NULL;
2793 log(L_INIT, "requesting firmware image '%s'\n", file);
2794 if (!request_firmware(&fw_entry, file, dev)) {
2795 *size = 8;
2796 if (fw_entry->size >= 8)
2797 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2798 if (fw_entry->size != *size) {
2799 printk("acx: firmware size does not match "
2800 "firmware header: %d != %d, "
2801 "aborting fw upload\n",
2802 (int)fw_entry->size, (int)*size);
2803 goto release_ret;
2805 res = vmalloc(*size);
2806 if (!res) {
2807 printk("acx: no memory for firmware "
2808 "(%u bytes)\n", *size);
2809 goto release_ret;
2811 memcpy(res, fw_entry->data, fw_entry->size);
2812 release_ret:
2813 release_firmware(fw_entry);
2814 return res;
2816 printk("acx: firmware image '%s' was not provided. "
2817 "Check your hotplug scripts\n", file);
2819 /* checksum will be verified in write_fw, so don't bother here */
2820 return res;
2824 /***********************************************************************
2825 ** acx_s_set_wepkey
2827 static void acx100_s_set_wepkey(acx_device_t * adev)
2829 ie_dot11WEPDefaultKey_t dk;
2830 int i;
2832 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2833 if (adev->wep_keys[i].size != 0) {
2834 log(L_INIT, "setting WEP key: %d with "
2835 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2836 dk.action = 1;
2837 dk.keySize = adev->wep_keys[i].size;
2838 dk.defaultKeyNum = i;
2839 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2840 acx_s_configure(adev, &dk,
2841 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
2846 static void acx111_s_set_wepkey(acx_device_t * adev)
2848 acx111WEPDefaultKey_t dk;
2849 int i;
2851 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2852 if (adev->wep_keys[i].size != 0) {
2853 log(L_INIT, "setting WEP key: %d with "
2854 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2855 memset(&dk, 0, sizeof(dk));
2856 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2857 dk.keySize = adev->wep_keys[i].size;
2859 /* are these two lines necessary? */
2860 dk.type = 0; /* default WEP key */
2861 dk.index = 0; /* ignored when setting default key */
2863 dk.defaultKeyNum = i;
2864 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2865 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2866 sizeof(dk));
2870 /* Obvious */
2871 static void acx_s_set_wepkey(acx_device_t * adev)
2873 if (IS_ACX111(adev))
2874 acx111_s_set_wepkey(adev);
2875 else
2876 acx100_s_set_wepkey(adev);
2880 /***********************************************************************
2881 ** acx100_s_init_wep
2883 ** FIXME: this should probably be moved into the new card settings
2884 ** management, but since we're also modifying the memory map layout here
2885 ** due to the WEP key space we want, we should take care...
2887 static int acx100_s_init_wep(acx_device_t * adev)
2889 acx100_ie_wep_options_t options;
2890 ie_dot11WEPDefaultKeyID_t dk;
2891 acx_ie_memmap_t pt;
2892 int res = NOT_OK;
2894 FN_ENTER;
2896 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2897 goto fail;
2900 log(L_DEBUG, "CodeEnd:%X\n", pt.CodeEnd);
2902 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2903 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2905 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2906 goto fail;
2909 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2910 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2911 options.WEPOption = 0x00;
2913 log(L_ASSOC, "writing WEP options\n");
2914 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
2916 acx100_s_set_wepkey(adev);
2918 if (adev->wep_keys[adev->wep_current_index].size != 0) {
2919 log(L_ASSOC, "setting active default WEP key number: %d\n",
2920 adev->wep_current_index);
2921 dk.KeyID = adev->wep_current_index;
2922 acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
2924 /* FIXME!!! wep_key_struct is filled nowhere! But adev
2925 * is initialized to 0, and we don't REALLY need those keys either */
2926 /* for (i = 0; i < 10; i++) {
2927 if (adev->wep_key_struct[i].len != 0) {
2928 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
2929 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
2930 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
2931 wep_mgmt.Action = cpu_to_le16(1);
2932 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
2933 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
2934 adev->wep_key_struct[i].index = i;
2940 /* now retrieve the updated WEPCacheEnd pointer... */
2941 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2942 printk("%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
2943 wiphy_name(adev->ieee->wiphy));
2944 goto fail;
2946 /* ...and tell it to start allocating templates at that location */
2947 /* (no endianness conversion needed) */
2948 pt.PacketTemplateStart = pt.WEPCacheEnd;
2950 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2951 printk("%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
2952 wiphy_name(adev->ieee->wiphy));
2953 goto fail;
2955 res = OK;
2957 fail:
2958 FN_EXIT1(res);
2959 return res;
2963 static int
2964 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
2965 unsigned int cmd)
2967 int res;
2968 union {
2969 acx_template_nullframe_t null;
2970 acx_template_beacon_t b;
2971 acx_template_tim_t tim;
2972 acx_template_probereq_t preq;
2973 acx_template_proberesp_t presp;
2974 } templ;
2976 memset(&templ, 0, len);
2977 templ.null.size = cpu_to_le16(len - 2);
2978 res = acx_s_issue_cmd(adev, cmd, &templ, len);
2979 return res;
2982 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
2984 return acx_s_init_max_template_generic(adev,
2985 sizeof(acx_template_nullframe_t),
2986 ACX1xx_CMD_CONFIG_NULL_DATA);
2989 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
2991 return acx_s_init_max_template_generic(adev,
2992 sizeof(acx_template_beacon_t),
2993 ACX1xx_CMD_CONFIG_BEACON);
2996 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
2998 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
2999 ACX1xx_CMD_CONFIG_TIM);
3002 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
3004 return acx_s_init_max_template_generic(adev,
3005 sizeof(acx_template_proberesp_t),
3006 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
3009 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
3011 return acx_s_init_max_template_generic(adev,
3012 sizeof(acx_template_probereq_t),
3013 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
3016 /***********************************************************************
3017 ** acx_s_set_tim_template
3019 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
3020 ** by calling this function
3021 ** (it can be done by irq handler on each DTIM irq or by timer...)
3023 [802.11 7.3.2.6] TIM information element:
3024 - 1 EID
3025 - 1 Length
3026 1 1 DTIM Count
3027 indicates how many beacons (including this) appear before next DTIM
3028 (0=this one is a DTIM)
3029 2 1 DTIM Period
3030 number of beacons between successive DTIMs
3031 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
3032 3 1 Bitmap Control
3033 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
3034 set to 1 in TIM elements with a value of 0 in the DTIM Count field
3035 when one or more broadcast or multicast frames are buffered at the AP.
3036 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
3037 4 n Partial Virtual Bitmap
3038 Visible part of traffic-indication bitmap.
3039 Full bitmap consists of 2008 bits (251 octets) such that bit number N
3040 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
3041 in octet number N/8 where the low-order bit of each octet is bit0,
3042 and the high order bit is bit7.
3043 Each set bit in virtual bitmap corresponds to traffic buffered by AP
3044 for a specific station (with corresponding AID?).
3045 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
3046 Bitmap Offset is a number of skipped zero octets (see above).
3047 'Missing' octets at the tail are also assumed to be zero.
3048 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
3049 This means that traffic-indication bitmap is:
3050 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
3051 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
3053 static int acx_s_set_tim_template(acx_device_t * adev)
3055 /* For now, configure smallish test bitmap, all zero ("no pending data") */
3056 enum { bitmap_size = 5 };
3058 acx_template_tim_t t;
3059 int result;
3061 FN_ENTER;
3063 memset(&t, 0, sizeof(t));
3064 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3065 t.tim_eid = WLAN_EID_TIM;
3066 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3067 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3068 FN_EXIT1(result);
3069 return result;
3075 #if POWER_SAVE_80211
3076 /***********************************************************************
3077 ** acx_s_set_null_data_template
3079 static int acx_s_set_null_data_template(acx_device_t * adev)
3081 struct acx_template_nullframe b;
3082 int result;
3084 FN_ENTER;
3086 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3088 b.size = cpu_to_le16(sizeof(b) - 2);
3089 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3090 b.hdr.dur = 0;
3091 MAC_BCAST(b.hdr.a1);
3092 MAC_COPY(b.hdr.a2, adev->dev_addr);
3093 MAC_COPY(b.hdr.a3, adev->bssid);
3094 b.hdr.seq = 0;
3096 result =
3097 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3099 FN_EXIT1(result);
3100 return result;
3102 #endif
3109 /***********************************************************************
3110 ** acx_s_init_packet_templates()
3112 ** NOTE: order is very important here, to have a correct memory layout!
3113 ** init templates: max Probe Request (station mode), max NULL data,
3114 ** max Beacon, max TIM, max Probe Response.
3116 static int acx_s_init_packet_templates(acx_device_t * adev)
3118 acx_ie_memmap_t mm; /* ACX100 only */
3119 int result = NOT_OK;
3121 FN_ENTER;
3123 log(L_DEBUG | L_INIT, "initializing max packet templates\n");
3125 if (OK != acx_s_init_max_probe_request_template(adev))
3126 goto failed;
3128 if (OK != acx_s_init_max_null_data_template(adev))
3129 goto failed;
3131 if (OK != acx_s_init_max_beacon_template(adev))
3132 goto failed;
3134 if (OK != acx_s_init_max_tim_template(adev))
3135 goto failed;
3137 if (OK != acx_s_init_max_probe_response_template(adev))
3138 goto failed;
3140 if (IS_ACX111(adev)) {
3141 /* ACX111 doesn't need the memory map magic below,
3142 * and the other templates will be set later (acx_start) */
3143 result = OK;
3144 goto success;
3147 /* ACX100 will have its TIM template set,
3148 * and we also need to update the memory map */
3150 if (OK != acx_s_set_tim_template(adev))
3151 goto failed_acx100;
3153 log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3155 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3156 goto failed_acx100;
3158 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3159 if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3160 goto failed_acx100;
3162 result = OK;
3163 goto success;
3165 failed_acx100:
3166 log(L_DEBUG | L_INIT,
3167 /* "cb=0x%X\n" */
3168 "ACXMemoryMap:\n"
3169 ".CodeStart=0x%X\n"
3170 ".CodeEnd=0x%X\n"
3171 ".WEPCacheStart=0x%X\n"
3172 ".WEPCacheEnd=0x%X\n"
3173 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3174 /* len, */
3175 le32_to_cpu(mm.CodeStart),
3176 le32_to_cpu(mm.CodeEnd),
3177 le32_to_cpu(mm.WEPCacheStart),
3178 le32_to_cpu(mm.WEPCacheEnd),
3179 le32_to_cpu(mm.PacketTemplateStart),
3180 le32_to_cpu(mm.PacketTemplateEnd));
3182 failed:
3183 printk("%s: %s() FAILED\n", wiphy_name(adev->ieee->wiphy), __func__);
3185 success:
3186 FN_EXIT1(result);
3187 return result;
3192 /***********************************************************************
3193 ** acx_s_init_mac
3195 int acx_s_init_mac(acx_device_t * adev)
3197 int result = NOT_OK;
3199 FN_ENTER;
3201 if (IS_ACX111(adev)) {
3202 adev->ie_len = acx111_ie_len;
3203 adev->ie_len_dot11 = acx111_ie_len_dot11;
3204 } else {
3205 adev->ie_len = acx100_ie_len;
3206 adev->ie_len_dot11 = acx100_ie_len_dot11;
3209 if (IS_PCI(adev)) {
3210 adev->memblocksize = 256; /* 256 is default */
3211 /* try to load radio for both ACX100 and ACX111, since both
3212 * chips have at least some firmware versions making use of an
3213 * external radio module */
3214 acxpci_s_upload_radio(adev);
3215 } else {
3216 adev->memblocksize = 128;
3219 if (IS_ACX111(adev)) {
3220 /* for ACX111, the order is different from ACX100
3221 1. init packet templates
3222 2. create station context and create dma regions
3223 3. init wep default keys
3225 if (OK != acx_s_init_packet_templates(adev))
3226 goto fail;
3227 if (OK != acx111_s_create_dma_regions(adev)) {
3228 printk("%s: acx111_create_dma_regions FAILED\n",
3229 wiphy_name(adev->ieee->wiphy));
3230 goto fail;
3232 } else {
3233 if (OK != acx100_s_init_wep(adev))
3234 goto fail;
3235 if (OK != acx_s_init_packet_templates(adev))
3236 goto fail;
3237 if (OK != acx100_s_create_dma_regions(adev)) {
3238 printk("%s: acx100_create_dma_regions FAILED\n",
3239 wiphy_name(adev->ieee->wiphy));
3240 goto fail;
3244 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3245 result = OK;
3247 fail:
3248 if (result)
3249 printk("acx: init_mac() FAILED\n");
3250 FN_EXIT1(result);
3251 return result;
3256 #if POWER_SAVE_80211
3257 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3259 /* merge both structs in a union to be able to have common code */
3260 union {
3261 acx111_ie_powersave_t acx111;
3262 acx100_ie_powersave_t acx100;
3263 } pm;
3265 /* change 802.11 power save mode settings */
3266 log(L_INIT, "updating 802.11 power save mode settings: "
3267 "wakeup_cfg 0x%02X, listen interval %u, "
3268 "options 0x%02X, hangover period %u, "
3269 "enhanced_ps_transition_time %u\n",
3270 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3271 adev->ps_options, adev->ps_hangover_period,
3272 adev->ps_enhanced_transition_time);
3273 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3274 log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, "
3275 "listen interval %u, options 0x%02X, "
3276 "hangover period %u, "
3277 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3278 pm.acx111.wakeup_cfg,
3279 pm.acx111.listen_interval,
3280 pm.acx111.options,
3281 pm.acx111.hangover_period,
3282 IS_ACX111(adev) ?
3283 pm.acx111.enhanced_ps_transition_time
3284 : pm.acx100.enhanced_ps_transition_time,
3285 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3286 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3287 pm.acx111.listen_interval = adev->ps_listen_interval;
3288 pm.acx111.options = adev->ps_options;
3289 pm.acx111.hangover_period = adev->ps_hangover_period;
3290 if (IS_ACX111(adev)) {
3291 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3292 pm.acx111.enhanced_ps_transition_time =
3293 cpu_to_le32(adev->ps_enhanced_transition_time);
3294 } else {
3295 pm.acx100.enhanced_ps_transition_time =
3296 cpu_to_le16(adev->ps_enhanced_transition_time);
3298 acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT);
3299 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3300 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3301 acx_s_mdelay(40);
3302 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3303 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3304 log(L_INIT, "power save mode change %s\n",
3305 (pm.acx111.
3306 wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful");
3307 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3308 * that power save mode change was successful. */
3309 /* FIXME: we shouldn't trigger a scan immediately after
3310 * fiddling with power save mode (since the firmware is sending
3311 * a NULL frame then). */
3313 #endif
3316 /***********************************************************************
3317 ** acx_s_update_card_settings
3319 ** Applies accumulated changes in various adev->xxxx members
3320 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3321 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3323 void acx_s_set_sane_reg_domain(acx_device_t * adev, int do_set)
3326 FIXME();
3327 if (do_set) {
3328 acx_ie_generic_t dom;
3329 dom.m.bytes[0] = adev->reg_dom_id;
3330 acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3335 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3337 u32 feature1, feature2;
3339 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3340 printk("%s: invalid sensitivity setting (1..3), "
3341 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3342 adev->sensitivity = 1;
3344 acx111_s_get_feature_config(adev, &feature1, &feature2);
3345 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3346 if (adev->sensitivity > 1)
3347 SET_BIT(feature1, FEATURE1_LOW_RX);
3348 if (adev->sensitivity > 2)
3349 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3350 acx111_s_feature_set(adev, feature1, feature2);
3354 void acx_s_update_card_settings(acx_device_t * adev)
3356 unsigned long flags;
3357 unsigned int start_scan = 0;
3358 int i;
3360 FN_ENTER;
3362 log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3363 adev->get_mask, adev->set_mask);
3365 /* Track dependencies betweed various settings */
3367 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3368 log(L_INIT, "important setting has been changed. "
3369 "Need to update packet templates, too\n");
3370 SET_BIT(adev->set_mask, SET_TEMPLATES);
3372 if (adev->set_mask & GETSET_CHANNEL) {
3373 /* This will actually tune RX/TX to the channel */
3374 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3375 switch (adev->mode) {
3376 case ACX_MODE_0_ADHOC:
3377 case ACX_MODE_3_AP:
3378 /* Beacons contain channel# - update them */
3379 SET_BIT(adev->set_mask, SET_TEMPLATES);
3382 switch (adev->mode) {
3383 case ACX_MODE_0_ADHOC:
3384 case ACX_MODE_2_STA:
3385 start_scan = 1;
3389 /* Apply settings */
3392 if (adev->get_mask & GETSET_STATION_ID) {
3393 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3394 const u8 *paddr;
3396 acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3397 paddr = &stationID[4];
3398 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3399 for (i = 0; i < ETH_ALEN; i++) {
3400 /* we copy the MAC address (reversed in
3401 * the card) to the netdevice's MAC
3402 * address, and on ifup it will be
3403 * copied into iwadev->dev_addr */
3404 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3406 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3407 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3410 if (adev->get_mask & GETSET_SENSITIVITY) {
3411 if ((RADIO_RFMD_11 == adev->radio_type)
3412 || (RADIO_MAXIM_0D == adev->radio_type)
3413 || (RADIO_RALINK_15 == adev->radio_type)) {
3414 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3415 } else {
3416 log(L_INIT, "don't know how to get sensitivity "
3417 "for radio type 0x%02X\n", adev->radio_type);
3418 adev->sensitivity = 0;
3420 log(L_INIT, "got sensitivity value %u\n", adev->sensitivity);
3422 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3425 if (adev->get_mask & GETSET_ANTENNA) {
3426 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3428 memset(antenna, 0, sizeof(antenna));
3429 acx_s_interrogate(adev, antenna,
3430 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3431 adev->antenna = antenna[4];
3432 log(L_INIT, "got antenna value 0x%02X\n", adev->antenna);
3433 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3436 if (adev->get_mask & GETSET_ED_THRESH) {
3437 if (IS_ACX100(adev)) {
3438 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3440 memset(ed_threshold, 0, sizeof(ed_threshold));
3441 acx_s_interrogate(adev, ed_threshold,
3442 ACX100_IE_DOT11_ED_THRESHOLD);
3443 adev->ed_threshold = ed_threshold[4];
3444 } else {
3445 log(L_INIT, "acx111 doesn't support ED\n");
3446 adev->ed_threshold = 0;
3448 log(L_INIT, "got Energy Detect (ED) threshold %u\n",
3449 adev->ed_threshold);
3450 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3453 if (adev->get_mask & GETSET_CCA) {
3454 if (IS_ACX100(adev)) {
3455 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3457 memset(cca, 0, sizeof(adev->cca));
3458 acx_s_interrogate(adev, cca,
3459 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3460 adev->cca = cca[4];
3461 } else {
3462 log(L_INIT, "acx111 doesn't support CCA\n");
3463 adev->cca = 0;
3465 log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n",
3466 adev->cca);
3467 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3470 if (adev->get_mask & GETSET_REG_DOMAIN) {
3471 acx_ie_generic_t dom;
3473 acx_s_interrogate(adev, &dom,
3474 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3475 adev->reg_dom_id = dom.m.bytes[0];
3476 acx_s_set_sane_reg_domain(adev, 0);
3477 log(L_INIT, "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3478 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3481 if (adev->set_mask & GETSET_STATION_ID) {
3482 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3483 u8 *paddr;
3485 paddr = &stationID[4];
3486 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3487 for (i = 0; i < ETH_ALEN; i++) {
3488 /* copy the MAC address we obtained when we noticed
3489 * that the ethernet iface's MAC changed
3490 * to the card (reversed in
3491 * the card!) */
3492 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3494 acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3495 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3498 if (adev->set_mask & SET_STA_LIST) {
3499 acx_lock(adev, flags);
3500 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3501 acx_unlock(adev, flags);
3503 if (adev->set_mask & SET_RATE_FALLBACK) {
3504 u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
3506 /* configure to not do fallbacks when not in auto rate mode */
3507 rate[4] =
3508 (adev->
3509 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3510 log(L_INIT, "updating Tx fallback to %u retries\n", rate[4]);
3511 acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK);
3512 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3514 if (adev->set_mask & GETSET_TXPOWER) {
3515 log(L_INIT, "updating transmit power: %u dBm\n",
3516 adev->tx_level_dbm);
3517 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3518 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3521 if (adev->set_mask & GETSET_SENSITIVITY) {
3522 log(L_INIT, "updating sensitivity value: %u\n",
3523 adev->sensitivity);
3524 switch (adev->radio_type) {
3525 case RADIO_RFMD_11:
3526 case RADIO_MAXIM_0D:
3527 case RADIO_RALINK_15:
3528 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3529 break;
3530 case RADIO_RADIA_16:
3531 case RADIO_UNKNOWN_17:
3532 acx111_s_sens_radio_16_17(adev);
3533 break;
3534 default:
3535 log(L_INIT, "don't know how to modify sensitivity "
3536 "for radio type 0x%02X\n", adev->radio_type);
3538 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3541 if (adev->set_mask & GETSET_ANTENNA) {
3542 /* antenna */
3543 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3545 memset(antenna, 0, sizeof(antenna));
3546 antenna[4] = adev->antenna;
3547 log(L_INIT, "updating antenna value: 0x%02X\n", adev->antenna);
3548 acx_s_configure(adev, &antenna,
3549 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3550 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3553 if (adev->set_mask & GETSET_ED_THRESH) {
3554 /* ed_threshold */
3555 log(L_INIT, "updating Energy Detect (ED) threshold: %u\n",
3556 adev->ed_threshold);
3557 if (IS_ACX100(adev)) {
3558 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3560 memset(ed_threshold, 0, sizeof(ed_threshold));
3561 ed_threshold[4] = adev->ed_threshold;
3562 acx_s_configure(adev, &ed_threshold,
3563 ACX100_IE_DOT11_ED_THRESHOLD);
3564 } else
3565 log(L_INIT, "acx111 doesn't support ED!\n");
3566 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3569 if (adev->set_mask & GETSET_CCA) {
3570 /* CCA value */
3571 log(L_INIT, "updating Channel Clear Assessment "
3572 "(CCA) value: 0x%02X\n", adev->cca);
3573 if (IS_ACX100(adev)) {
3574 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3576 memset(cca, 0, sizeof(cca));
3577 cca[4] = adev->cca;
3578 acx_s_configure(adev, &cca,
3579 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3580 } else
3581 log(L_INIT, "acx111 doesn't support CCA!\n");
3582 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3585 if (adev->set_mask & GETSET_LED_POWER) {
3586 /* Enable Tx */
3587 log(L_INIT, "updating power LED status: %u\n", adev->led_power);
3589 acx_lock(adev, flags);
3590 if (IS_PCI(adev))
3591 acxpci_l_power_led(adev, adev->led_power);
3592 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3593 acx_unlock(adev, flags);
3596 if (adev->set_mask & GETSET_POWER_80211) {
3597 #if POWER_SAVE_80211
3598 acx_s_update_80211_powersave_mode(adev);
3599 #endif
3600 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3603 if (adev->set_mask & GETSET_CHANNEL) {
3604 /* channel */
3605 log(L_INIT, "updating channel to: %u\n", adev->channel);
3606 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3609 if (adev->set_mask & GETSET_TX) {
3610 /* set Tx */
3611 log(L_INIT, "updating: %s Tx\n",
3612 adev->tx_disabled ? "disable" : "enable");
3613 if (adev->tx_disabled)
3614 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3615 else {
3616 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3617 &adev->channel, 1);
3618 FIXME();
3619 /* This needs to be keyed on WEP? */
3620 // acx111_s_feature_on(adev, 0,
3621 // FEATURE2_NO_TXCRYPT |
3622 // FEATURE2_SNIFFER);
3624 CLEAR_BIT(adev->set_mask, GETSET_TX);
3627 if (adev->set_mask & GETSET_RX) {
3628 /* Enable Rx */
3629 log(L_INIT, "updating: enable Rx on channel: %u\n",
3630 adev->channel);
3631 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3632 CLEAR_BIT(adev->set_mask, GETSET_RX);
3635 if (adev->set_mask & GETSET_RETRY) {
3636 u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
3637 u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
3639 log(L_INIT,
3640 "updating short retry limit: %u, long retry limit: %u\n",
3641 adev->short_retry, adev->long_retry);
3642 short_retry[0x4] = adev->short_retry;
3643 long_retry[0x4] = adev->long_retry;
3644 acx_s_configure(adev, &short_retry,
3645 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
3646 acx_s_configure(adev, &long_retry,
3647 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
3648 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3651 if (adev->set_mask & SET_MSDU_LIFETIME) {
3652 u8 xmt_msdu_lifetime[4 +
3653 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3655 log(L_INIT, "updating tx MSDU lifetime: %u\n",
3656 adev->msdu_lifetime);
3657 *(u32 *) & xmt_msdu_lifetime[4] =
3658 cpu_to_le32((u32) adev->msdu_lifetime);
3659 acx_s_configure(adev, &xmt_msdu_lifetime,
3660 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
3661 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3664 if (adev->set_mask & GETSET_REG_DOMAIN) {
3665 log(L_INIT, "updating regulatory domain: 0x%02X\n",
3666 adev->reg_dom_id);
3667 acx_s_set_sane_reg_domain(adev, 1);
3668 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3670 if (adev->set_mask & GETSET_MODE ) {
3671 acx111_s_feature_on(adev, 0,
3672 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3673 switch (adev->mode) {
3674 case ACX_MODE_3_AP:
3675 adev->aid = 0;
3676 //acx111_s_feature_off(adev, 0,
3677 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3678 MAC_COPY(adev->bssid,adev->dev_addr);
3679 acx_s_cmd_join_bssid(adev,adev->dev_addr);
3680 break;
3681 case ACX_MODE_MONITOR:
3682 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3683 break;
3684 case ACX_MODE_0_ADHOC:
3685 case ACX_MODE_2_STA:
3686 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3687 break;
3688 default:
3689 break;
3691 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3693 if (adev->set_mask & SET_TEMPLATES) {
3694 switch (adev->mode)
3696 case ACX_MODE_3_AP:
3697 acx_s_set_tim_template(adev);
3698 break;
3699 default:
3700 break;
3702 if (adev->beacon_cache)
3704 acx_s_set_beacon_template(adev, adev->beacon_cache);
3705 dev_kfree_skb(adev->beacon_cache);
3706 adev->beacon_cache = NULL;
3708 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3711 if (adev->set_mask & SET_RXCONFIG) {
3712 acx_s_initialize_rx_config(adev);
3713 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3716 if (adev->set_mask & GETSET_RESCAN) {
3717 /* switch (adev->mode) {
3718 case ACX_MODE_0_ADHOC:
3719 case ACX_MODE_2_STA:
3720 start_scan = 1;
3721 break;
3723 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3726 if (adev->set_mask & GETSET_WEP) {
3727 /* encode */
3729 ie_dot11WEPDefaultKeyID_t dkey;
3730 #ifdef DEBUG_WEP
3731 struct {
3732 u16 type;
3733 u16 len;
3734 u8 val;
3735 } ACX_PACKED keyindic;
3736 #endif
3737 log(L_INIT, "updating WEP key settings\n");
3739 acx_s_set_wepkey(adev);
3740 if (adev->wep_enabled) {
3741 dkey.KeyID = adev->wep_current_index;
3742 log(L_INIT, "setting WEP key %u as default\n",
3743 dkey.KeyID);
3744 acx_s_configure(adev, &dkey,
3745 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
3746 #ifdef DEBUG_WEP
3747 keyindic.val = 3;
3748 acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
3749 #endif
3752 // start_scan = 1;
3753 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3756 if (adev->set_mask & SET_WEP_OPTIONS) {
3757 acx100_ie_wep_options_t options;
3759 if (IS_ACX111(adev)) {
3760 log(L_DEBUG,
3761 "setting WEP Options for acx111 is not supported\n");
3762 } else {
3763 log(L_INIT, "setting WEP Options\n");
3765 /* let's choose maximum setting: 4 default keys,
3766 * plus 10 other keys: */
3767 options.NumKeys =
3768 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3769 /* don't decrypt default key only,
3770 * don't override decryption: */
3771 options.WEPOption = 0;
3772 if (adev->mode == ACX_MODE_3_AP) {
3773 /* don't decrypt default key only,
3774 * override decryption mechanism: */
3775 options.WEPOption = 2;
3778 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3780 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3784 /* debug, rate, and nick don't need any handling */
3785 /* what about sniffing mode?? */
3787 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3788 adev->get_mask, adev->set_mask);
3790 /* end: */
3791 FN_EXIT0;
3794 #if 0
3795 /***********************************************************************
3796 ** acx_e_after_interrupt_task
3798 static int acx_s_recalib_radio(acx_device_t * adev)
3800 if (IS_ACX111(adev)) {
3801 acx111_cmd_radiocalib_t cal;
3803 /* automatic recalibration, choose all methods: */
3804 cal.methods = cpu_to_le32(0x8000000f);
3805 /* automatic recalibration every 60 seconds (value in TUs)
3806 * I wonder what the firmware default here is? */
3807 cal.interval = cpu_to_le32(58594);
3808 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3809 &cal, sizeof(cal),
3810 CMD_TIMEOUT_MS(100));
3811 } else {
3812 /* On ACX100, we need to recalibrate the radio
3813 * by issuing a GETSET_TX|GETSET_RX */
3814 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3815 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3816 (OK ==
3817 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3818 &adev->channel, 1))
3819 && (OK ==
3820 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3821 &adev->channel, 1)))
3822 return OK;
3823 return NOT_OK;
3826 #endif // if 0
3827 #if 0
3828 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3830 int res;
3832 /* this helps with ACX100 at least;
3833 * hopefully ACX111 also does a
3834 * recalibration here */
3836 /* clear flag beforehand, since we want to make sure
3837 * it's cleared; then only set it again on specific circumstances */
3838 CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3840 /* better wait a bit between recalibrations to
3841 * prevent overheating due to torturing the card
3842 * into working too long despite high temperature
3843 * (just a safety measure) */
3844 if (adev->recalib_time_last_success
3845 && time_before(jiffies, adev->recalib_time_last_success
3846 + RECALIB_PAUSE * 60 * HZ)) {
3847 if (adev->recalib_msg_ratelimit <= 4) {
3848 printk("%s: less than " STRING(RECALIB_PAUSE)
3849 " minutes since last radio recalibration, "
3850 "not recalibrating (maybe card is too hot?)\n",
3851 wiphy_name(adev->ieee->wiphy));
3852 adev->recalib_msg_ratelimit++;
3853 if (adev->recalib_msg_ratelimit == 5)
3854 printk("disabling above message until next recalib\n");
3856 return;
3859 adev->recalib_msg_ratelimit = 0;
3861 /* note that commands sometimes fail (card busy),
3862 * so only clear flag if we were fully successful */
3863 res = acx_s_recalib_radio(adev);
3864 if (res == OK) {
3865 printk("%s: successfully recalibrated radio\n",
3866 wiphy_name(adev->ieee->wiphy));
3867 adev->recalib_time_last_success = jiffies;
3868 adev->recalib_failure_count = 0;
3869 } else {
3870 /* failed: resubmit, but only limited
3871 * amount of times within some time range
3872 * to prevent endless loop */
3874 adev->recalib_time_last_success = 0; /* we failed */
3876 /* if some time passed between last
3877 * attempts, then reset failure retry counter
3878 * to be able to do next recalib attempt */
3879 if (time_after
3880 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3881 adev->recalib_failure_count = 0;
3883 if (adev->recalib_failure_count < 5) {
3884 /* increment inside only, for speedup of outside path */
3885 adev->recalib_failure_count++;
3886 adev->recalib_time_last_attempt = jiffies;
3887 acx_schedule_task(adev,
3888 ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3892 #endif // if 0
3894 void acx_e_after_interrupt_task(struct work_struct *work)
3896 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
3897 unsigned int flags;
3898 FN_ENTER;
3899 acx_lock(adev, flags);
3900 if (!adev->after_interrupt_jobs || !adev->initialized)
3901 goto end; /* no jobs to do */
3903 /* we see lotsa tx errors */
3904 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) {
3905 // acx_s_after_interrupt_recalib(adev);
3908 /* a poor interrupt code wanted to do update_card_settings() */
3909 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) {
3910 if (ACX_STATE_IFACE_UP & adev->dev_state_mask)
3911 acx_s_update_card_settings(adev);
3912 CLEAR_BIT(adev->after_interrupt_jobs,
3913 ACX_AFTER_IRQ_UPDATE_CARD_CFG);
3915 /* 1) we detected that no Scan_Complete IRQ came from fw, or
3916 ** 2) we found too many STAs */
3917 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) {
3918 log(L_IRQ, "sending a stop scan cmd...\n");
3919 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
3920 /* HACK: set the IRQ bit, since we won't get a
3921 * scan complete IRQ any more on ACX111 (works on ACX100!),
3922 * since _we_, not a fw, have stopped the scan */
3923 SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
3924 CLEAR_BIT(adev->after_interrupt_jobs,
3925 ACX_AFTER_IRQ_CMD_STOP_SCAN);
3928 /* either fw sent Scan_Complete or we detected that
3929 ** no Scan_Complete IRQ came from fw. Finish scanning,
3930 ** pick join partner if any */
3931 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) {
3932 /* + scan kills current join status - restore it
3933 ** (do we need it for STA?) */
3934 /* + does it happen only with active scans?
3935 ** active and passive scans? ALL scans including
3936 ** background one? */
3937 /* + was not verified that everything is restored
3938 ** (but at least we start to emit beacons again) */
3939 CLEAR_BIT(adev->after_interrupt_jobs,
3940 ACX_AFTER_IRQ_COMPLETE_SCAN);
3943 /* STA auth or assoc timed out, start over again */
3945 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) {
3946 log(L_IRQ, "sending a start_scan cmd...\n");
3947 CLEAR_BIT(adev->after_interrupt_jobs,
3948 ACX_AFTER_IRQ_RESTART_SCAN);
3951 /* whee, we got positive assoc response! 8) */
3952 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) {
3953 CLEAR_BIT(adev->after_interrupt_jobs,
3954 ACX_AFTER_IRQ_CMD_ASSOCIATE);
3956 end:
3957 if(adev->after_interrupt_jobs)
3959 printk("Jobs still to be run: %x\n",adev->after_interrupt_jobs);
3960 adev->after_interrupt_jobs = 0;
3962 acx_unlock(adev, flags);
3963 // acx_sem_unlock(adev);
3964 FN_EXIT0;
3968 /***********************************************************************
3969 ** acx_schedule_task
3971 ** Schedule the call of the after_interrupt method after leaving
3972 ** the interrupt context.
3974 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
3976 if (!adev->after_interrupt_jobs)
3978 SET_BIT(adev->after_interrupt_jobs, set_flag);
3979 schedule_work(&adev->after_interrupt_task);
3984 /***********************************************************************
3986 void acx_init_task_scheduler(acx_device_t * adev)
3988 /* configure task scheduler */
3989 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
3993 /***********************************************************************
3994 ** acx_s_start
3996 void acx_s_start(acx_device_t * adev)
3998 FN_ENTER;
4001 * Ok, now we do everything that can possibly be done with ioctl
4002 * calls to make sure that when it was called before the card
4003 * was up we get the changes asked for
4006 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4007 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4008 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4009 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4011 log(L_INIT, "updating initial settings on iface activation\n");
4012 acx_s_update_card_settings(adev);
4014 FN_EXIT0;
4018 /***********************************************************************
4019 ** acx_update_capabilities
4020 *//*
4021 void acx_update_capabilities(acx_device_t * adev)
4023 u16 cap = 0;
4025 switch (adev->mode) {
4026 case ACX_MODE_3_AP:
4027 SET_BIT(cap, WF_MGMT_CAP_ESS);
4028 break;
4029 case ACX_MODE_0_ADHOC:
4030 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4031 break;
4032 */ /* other types of stations do not emit beacons */
4033 /* }
4035 if (adev->wep_restricted) {
4036 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4038 if (adev->cfgopt_dot11ShortPreambleOption) {
4039 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4041 if (adev->cfgopt_dot11PBCCOption) {
4042 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4044 if (adev->cfgopt_dot11ChannelAgility) {
4045 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4047 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4048 adev->capabilities, cap);
4049 adev->capabilities = cap;
4053 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4056 static void acx_select_opmode(acx_device_t * adev)
4058 FN_ENTER;
4060 int changed = 0;
4061 if (adev->interface.operating) {
4062 switch (adev->interface.type) {
4063 case IEEE80211_IF_TYPE_AP:
4064 if (adev->mode != ACX_MODE_3_AP)
4066 adev->mode = ACX_MODE_3_AP;
4067 changed = 1;
4069 break;
4070 case IEEE80211_IF_TYPE_IBSS:
4071 if (adev->mode != ACX_MODE_0_ADHOC)
4073 adev->mode = ACX_MODE_0_ADHOC;
4074 changed = 1;
4076 break;
4077 case IEEE80211_IF_TYPE_STA:
4078 if (adev->mode != ACX_MODE_2_STA)
4080 adev->mode = ACX_MODE_2_STA;
4081 changed = 1;
4083 break;
4084 case IEEE80211_IF_TYPE_WDS:
4085 default:
4086 if (adev->mode != ACX_MODE_OFF)
4088 adev->mode = ACX_MODE_OFF;
4089 changed = 1;
4091 break;
4093 } else {
4094 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4096 if (adev->mode != ACX_MODE_MONITOR)
4098 adev->mode = ACX_MODE_MONITOR;
4099 changed = 1;
4102 else
4104 if (adev->mode != ACX_MODE_OFF)
4106 adev->mode = ACX_MODE_OFF;
4107 changed = 1;
4111 if (changed)
4113 SET_BIT(adev->set_mask, GETSET_MODE);
4114 acx_s_update_card_settings(adev);
4115 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4120 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4124 int acx_add_interface(struct ieee80211_hw *ieee,
4125 struct ieee80211_if_init_conf *conf)
4127 acx_device_t *adev = ieee2adev(ieee);
4128 unsigned long flags;
4129 int err = -EOPNOTSUPP;
4131 FN_ENTER;
4132 acx_lock(adev, flags);
4134 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4135 adev->interface.monitor++;
4136 } else {
4137 if (adev->interface.operating)
4138 goto out_unlock;
4139 adev->interface.operating = 1;
4140 adev->interface.if_id = conf->if_id;
4141 adev->interface.mac_addr = conf->mac_addr;
4142 adev->interface.type = conf->type;
4144 // adev->mode = conf->type;
4145 if (adev->initialized)
4146 acx_select_opmode(adev);
4147 err = 0;
4149 printk(KERN_INFO "Virtual interface added "
4150 "(type: 0x%08X, ID: %d, MAC: "
4151 MAC_FMT ")\n",
4152 conf->type, conf->if_id, MAC_ARG(conf->mac_addr));
4154 out_unlock:
4155 acx_unlock(adev, flags);
4157 FN_EXIT0;
4158 return err;
4161 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4165 void acx_remove_interface(struct ieee80211_hw *hw,
4166 struct ieee80211_if_init_conf *conf)
4168 acx_device_t *adev = ieee2adev(hw);
4169 unsigned long flags;
4170 FN_ENTER;
4172 acx_lock(adev, flags);
4173 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4174 adev->interface.monitor--;
4175 // assert(bcm->interface.monitor >= 0);
4176 } else
4177 adev->interface.operating = 0;
4178 printk("Removing interface: %d %d\n", adev->interface.operating, conf->type);
4179 if (adev->initialized)
4180 acx_select_opmode(adev);
4181 flush_scheduled_work();
4182 acx_unlock(adev, flags);
4184 printk(KERN_INFO "Virtual interface removed "
4185 "(type: 0x%08X, ID: %d, MAC: "
4186 MAC_FMT ")\n",
4187 conf->type, conf->if_id, MAC_ARG(conf->mac_addr));
4188 FN_EXIT0;
4191 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4195 int acx_net_reset(struct ieee80211_hw *ieee)
4197 acx_device_t *adev = ieee2adev(ieee);
4198 FN_ENTER;
4199 if (IS_PCI(adev))
4200 acxpci_s_reset_dev(adev);
4201 else
4202 TODO();
4204 FN_EXIT0;
4205 return 0;
4209 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4212 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4214 int result;
4216 FN_ENTER;
4218 acx_sem_lock(adev);
4219 adev->rx_status.channel = channel;
4220 adev->rx_status.freq = freq;
4222 adev->channel = channel;
4223 /* hmm, the following code part is strange, but this is how
4224 * it was being done before... */
4225 log(L_IOCTL, "Changing to channel %d\n", channel);
4226 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4227 result = -EINPROGRESS; /* need to call commit handler */
4229 acx_sem_unlock(adev);
4230 FN_EXIT1(result);
4231 return result;
4235 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4238 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4240 acx_device_t *adev = ieee2adev(hw);
4241 unsigned long flags;
4242 #if 0
4243 int change = 0;
4244 #endif
4245 FN_ENTER;
4247 acx_lock(adev, flags);
4248 //FIXME();
4249 if (!adev->initialized) {
4250 acx_unlock(adev,flags);
4251 return 0;
4253 if (conf->beacon_int != adev->beacon_interval)
4254 adev->beacon_interval = conf->beacon_int;
4255 if (conf->channel != adev->channel) {
4256 acx_selectchannel(adev, conf->channel,conf->freq);
4257 /* acx_schedule_task(adev,
4258 ACX_AFTER_IRQ_UPDATE_CARD_CFG
4259 */ /*+ ACX_AFTER_IRQ_RESTART_SCAN */ /*);*/
4262 if (conf->short_slot_time != adev->short_slot) {
4263 // assert(phy->type == BCM43xx_PHYTYPE_G);
4264 if (conf->short_slot_time)
4265 acx_short_slot_timing_enable(adev);
4266 else
4267 acx_short_slot_timing_disable(adev);
4268 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4271 adev->tx_disabled = !conf->radio_enabled;
4272 if (conf->power_level != 0 && adev->tx_level_dbm > 15){
4273 adev->tx_level_dbm = conf->power_level;
4274 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4275 //acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4278 //FIXME: This does not seem to wake up:
4279 #if 0
4280 if (conf->power_level == 0) {
4281 if (radio->enabled)
4282 bcm43xx_radio_turn_off(bcm);
4283 } else {
4284 if (!radio->enabled)
4285 bcm43xx_radio_turn_on(bcm);
4287 #endif
4289 //TODO: phymode
4290 //TODO: antennas
4291 if (adev->set_mask > 0)
4292 acx_s_update_card_settings(adev);
4293 acx_unlock(adev, flags);
4295 FN_EXIT0;
4296 return 0;
4300 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4304 int acx_config_interface(struct ieee80211_hw *ieee, int if_id,
4305 struct ieee80211_if_conf *conf)
4307 acx_device_t *adev = ieee2adev(ieee);
4308 unsigned long flags;
4309 int err = -ENODEV;
4310 FN_ENTER;
4311 if (!adev->interface.operating)
4312 goto err_out;
4313 acx_lock(adev, flags);
4315 if (adev->initialized)
4316 acx_select_opmode(adev);
4318 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4319 && (adev->interface.if_id == if_id)) {
4320 if (conf->bssid)
4322 adev->interface.bssid = conf->bssid;
4323 MAC_COPY(adev->bssid,conf->bssid);
4326 if ((conf->type == IEEE80211_IF_TYPE_AP)
4327 && (adev->interface.if_id == if_id)) {
4328 if ((conf->ssid_len > 0) && conf->ssid)
4330 adev->essid_len = conf->ssid_len;
4331 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4332 SET_BIT(adev->set_mask, SET_TEMPLATES);
4335 if (conf->beacon != 0)
4337 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4338 adev->beacon_cache = conf->beacon;
4339 SET_BIT(adev->set_mask, SET_TEMPLATES);
4341 if (adev->set_mask != 0)
4342 acx_s_update_card_settings(adev);
4343 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4344 acx_unlock(adev, flags);
4345 err = 0;
4346 err_out:
4347 FN_EXIT1(err);
4348 return err;
4352 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4356 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4357 struct ieee80211_tx_queue_stats *stats)
4359 // acx_device_t *adev = ndev2adev(net_dev);
4360 struct ieee80211_tx_queue_stats_data *data;
4361 int err = -ENODEV;
4363 FN_ENTER;
4365 // acx_lock(adev, flags);
4366 data = &(stats->data[0]);
4367 data->len = 0;
4368 data->limit = TX_CNT;
4369 data->count = 0;
4370 // acx_unlock(adev, flags);
4372 FN_EXIT0;
4373 return err;
4376 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4380 int acx_net_conf_tx(struct ieee80211_hw *hw,
4381 int queue, const struct ieee80211_tx_queue_params *params)
4383 FN_ENTER;
4384 // TODO();
4385 FN_EXIT0;
4386 return 0;
4389 static void keymac_write(acx_device_t * adev, u8 index, const u32 * addr)
4391 /* for keys 0-3 there is no associated mac address */
4392 if (index < 4)
4393 return;
4395 index -= 4;
4396 if (1) {
4397 TODO();
4399 bcm43xx_shm_write32(bcm,
4400 BCM43xx_SHM_HWMAC,
4401 index * 2,
4402 cpu_to_be32(*addr));
4403 bcm43xx_shm_write16(bcm,
4404 BCM43xx_SHM_HWMAC,
4405 (index * 2) + 1,
4406 cpu_to_be16(*((u16 *)(addr + 1))));
4408 } else {
4409 if (index < 8) {
4410 TODO(); /* Put them in the macaddress filter */
4411 } else {
4412 TODO();
4413 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4414 Keep in mind to update the count of keymacs in 0x003 */
4420 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4424 int acx_clear_keys(acx_device_t * adev)
4426 static const u32 zero_mac[2] = { 0 };
4427 unsigned int i, j, nr_keys = 54;
4428 u16 offset;
4430 /* FixMe:Check for Number of Keys available */
4432 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4434 for (i = 0; i < nr_keys; i++) {
4435 adev->key[i].enabled = 0;
4436 /* returns for i < 4 immediately */
4437 keymac_write(adev, i, zero_mac);
4439 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4440 0x100 + (i * 2), 0x0000);
4442 for (j = 0; j < 8; j++) {
4443 offset =
4444 adev->security_offset + (j * 4) +
4445 (i * ACX_SEC_KEYSIZE);
4447 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4448 offset, 0x0000);
4452 return 1;
4456 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4460 int acx_key_write(acx_device_t * adev,
4461 u8 index,
4462 u8 algorithm,
4463 const u8 * _key, int key_len, const u8 * mac_addr)
4465 // struct iw_point *dwrq = &wrqu->encoding;
4466 // acx_device_t *adev = ndev2adev(ndev);
4467 int result;
4469 FN_ENTER;
4471 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4472 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4474 acx_sem_lock(adev);
4476 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4477 if (key_len > 0) {
4478 /* if index is 0 or invalid, use default key */
4479 if (index > 3)
4480 index = (int)adev->wep_current_index;
4481 if ((algorithm == ACX_SEC_ALGO_WEP)
4482 || (algorithm == ACX_SEC_ALGO_WEP104)) {
4483 if (key_len > 29)
4484 key_len = 29; /* restrict it */
4486 if (key_len > 13) {
4487 /* 29*8 == 232, WEP256 */
4488 adev->wep_keys[index].size = 29;
4489 } else if (key_len > 5) {
4490 /* 13*8 == 104bit, WEP128 */
4491 adev->wep_keys[index].size = 13;
4492 } else if (key_len > 0) {
4493 /* 5*8 == 40bit, WEP64 */
4494 adev->wep_keys[index].size = 5;
4495 } else {
4496 /* disable key */
4497 adev->wep_keys[index].size = 0;
4500 memset(adev->wep_keys[index].key, 0,
4501 sizeof(adev->wep_keys[index].key));
4502 memcpy(adev->wep_keys[index].key, _key, key_len);
4504 } else {
4505 /* set transmit key */
4506 if (index <= 3)
4507 adev->wep_current_index = index;
4508 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4509 /* complain if we were not just setting
4510 * the key mode */
4511 // result = -EINVAL;
4512 // goto end_unlock;
4513 // }
4516 adev->wep_enabled = (algorithm == ALG_WEP);
4518 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4520 if (algorithm & IW_ENCODE_OPEN) {
4521 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4522 adev->wep_restricted = 0;
4524 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4525 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4526 adev->wep_restricted = 1;
4529 // adev->auth_alg = algorithm;
4530 /* set flag to make sure the card WEP settings get updated */
4531 if (adev->wep_enabled) {
4532 SET_BIT(adev->set_mask, GETSET_WEP);
4533 acx_s_update_card_settings(adev);
4534 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4537 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4538 dwrq->length, extra, dwrq->flags);
4539 for (index = 0; index <= 3; index++) {
4540 if (adev->wep_keys[index].size) {
4541 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4542 adev->wep_keys[index].index,
4543 (int) adev->wep_keys[index].size,
4544 adev->wep_keys[index].key);
4548 result = -EINPROGRESS;
4549 acx_sem_unlock(adev);
4551 FN_EXIT1(result);
4552 return result;
4558 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4562 int acx_net_set_key(struct ieee80211_hw *ieee,
4563 set_key_cmd cmd,
4564 u8 * addr, struct ieee80211_key_conf *key, int aid)
4566 // return 0;
4567 struct acx_device *adev = ieee2adev(ieee);
4568 unsigned long flags;
4569 u8 algorithm;
4570 u8 index;
4571 int err = -EINVAL;
4572 FN_ENTER;
4573 // TODO();
4574 switch (key->alg) {
4575 default:
4576 /* case ALG_NONE:
4577 case ALG_NULL:
4578 algorithm = ACX_SEC_ALGO_NONE;
4579 break;
4580 */ case ALG_WEP:
4581 if (key->keylen == 5)
4582 algorithm = ACX_SEC_ALGO_WEP;
4583 else
4584 algorithm = ACX_SEC_ALGO_WEP104;
4585 break;
4586 case ALG_TKIP:
4587 algorithm = ACX_SEC_ALGO_TKIP;
4588 break;
4589 case ALG_CCMP:
4590 algorithm = ACX_SEC_ALGO_AES;
4591 break;
4594 index = (u8) (key->keyidx);
4595 if (index >= ARRAY_SIZE(adev->key))
4596 goto out;
4597 acx_lock(adev, flags);
4598 switch (cmd) {
4599 case SET_KEY:
4600 err = acx_key_write(adev, index, algorithm,
4601 key->key, key->keylen, addr);
4602 if (err)
4603 goto out_unlock;
4604 key->hw_key_idx = index;
4605 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4606 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4607 adev->default_key_idx = index;*/
4608 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4609 adev->key[index].enabled = 1;
4610 break;
4611 case DISABLE_KEY:
4612 adev->key[index].enabled = 0;
4613 err = 0;
4614 break;
4615 /* case REMOVE_ALL_KEYS:
4616 acx_clear_keys(adev);
4617 err = 0;
4618 break;
4619 */ /* case ENABLE_COMPRESSION:
4620 case DISABLE_COMPRESSION:
4621 err = 0;
4622 break; */
4624 out_unlock:
4625 acx_unlock(adev, flags);
4626 out:
4627 FN_EXIT0;
4628 return err;
4633 /***********************************************************************
4634 ** Common function to parse ALL configoption struct formats
4635 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4636 ** FIXME: logging should be removed here and added to a /proc file instead
4638 ** Look into bcm43xx
4640 void
4641 acx_s_parse_configoption(acx_device_t * adev,
4642 const acx111_ie_configoption_t * pcfg)
4644 const u8 *pEle;
4645 int i;
4646 int is_acx111 = IS_ACX111(adev);
4648 if (acx_debug & L_DEBUG) {
4649 printk("configoption struct content:\n");
4650 acx_dump_bytes(pcfg, sizeof(*pcfg));
4653 if ((is_acx111 && (adev->eeprom_version == 5))
4654 || (!is_acx111 && (adev->eeprom_version == 4))
4655 || (!is_acx111 && (adev->eeprom_version == 5))) {
4656 /* these versions are known to be supported */
4657 } else {
4658 printk("unknown chip and EEPROM version combination (%s, v%d), "
4659 "don't know how to parse config options yet. "
4660 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4661 adev->eeprom_version);
4662 return;
4665 /* first custom-parse the first part which has chip-specific layout */
4667 pEle = (const u8 *)pcfg;
4669 pEle += 4; /* skip (type,len) header */
4671 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4672 pEle += sizeof(adev->cfgopt_NVSv);
4674 if (is_acx111) {
4675 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4676 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4678 adev->cfgopt_probe_delay = 200; /* good default value? */
4679 pEle += 2; /* FIXME: unknown, value 0x0001 */
4680 } else {
4681 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4682 pEle += sizeof(adev->cfgopt_MAC);
4684 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4685 pEle += sizeof(adev->cfgopt_probe_delay);
4686 if ((adev->cfgopt_probe_delay < 100)
4687 || (adev->cfgopt_probe_delay > 500)) {
4688 printk("strange probe_delay value %d, "
4689 "tweaking to 200\n", adev->cfgopt_probe_delay);
4690 adev->cfgopt_probe_delay = 200;
4694 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4695 pEle += sizeof(adev->cfgopt_eof_memory);
4697 printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n",
4698 adev->cfgopt_NVS_vendor_offs,
4699 adev->cfgopt_probe_delay, adev->cfgopt_eof_memory);
4701 adev->cfgopt_dot11CCAModes = *pEle++;
4702 adev->cfgopt_dot11Diversity = *pEle++;
4703 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4704 adev->cfgopt_dot11PBCCOption = *pEle++;
4705 adev->cfgopt_dot11ChannelAgility = *pEle++;
4706 adev->cfgopt_dot11PhyType = *pEle++;
4707 adev->cfgopt_dot11TempType = *pEle++;
4708 printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4709 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4710 adev->cfgopt_dot11CCAModes,
4711 adev->cfgopt_dot11Diversity,
4712 adev->cfgopt_dot11ShortPreambleOption,
4713 adev->cfgopt_dot11PBCCOption,
4714 adev->cfgopt_dot11ChannelAgility,
4715 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4717 /* then use common parsing for next part which has common layout */
4719 pEle++; /* skip table_count (6) */
4721 adev->cfgopt_antennas.type = pEle[0];
4722 adev->cfgopt_antennas.len = pEle[1];
4723 printk("AntennaID:%02X Len:%02X Data:",
4724 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4725 for (i = 0; i < pEle[1]; i++) {
4726 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4727 printk("%02X ", pEle[i + 2]);
4729 printk("\n");
4731 pEle += pEle[1] + 2;
4732 adev->cfgopt_power_levels.type = pEle[0];
4733 adev->cfgopt_power_levels.len = pEle[1];
4734 printk("PowerLevelID:%02X Len:%02X Data:",
4735 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4736 for (i = 0; i < pEle[1]; i++) {
4737 adev->cfgopt_power_levels.list[i] =
4738 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4739 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4741 printk("\n");
4743 pEle += pEle[1] * 2 + 2;
4744 adev->cfgopt_data_rates.type = pEle[0];
4745 adev->cfgopt_data_rates.len = pEle[1];
4746 printk("DataRatesID:%02X Len:%02X Data:",
4747 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4748 for (i = 0; i < pEle[1]; i++) {
4749 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4750 printk("%02X ", pEle[i + 2]);
4752 printk("\n");
4754 pEle += pEle[1] + 2;
4755 adev->cfgopt_domains.type = pEle[0];
4756 adev->cfgopt_domains.len = pEle[1];
4757 printk("DomainID:%02X Len:%02X Data:",
4758 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4759 for (i = 0; i < pEle[1]; i++) {
4760 adev->cfgopt_domains.list[i] = pEle[i + 2];
4761 printk("%02X ", pEle[i + 2]);
4763 printk("\n");
4765 pEle += pEle[1] + 2;
4766 adev->cfgopt_product_id.type = pEle[0];
4767 adev->cfgopt_product_id.len = pEle[1];
4768 for (i = 0; i < pEle[1]; i++) {
4769 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4771 printk("ProductID:%02X Len:%02X Data:%.*s\n",
4772 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4773 adev->cfgopt_product_id.len,
4774 (char *)adev->cfgopt_product_id.list);
4776 pEle += pEle[1] + 2;
4777 adev->cfgopt_manufacturer.type = pEle[0];
4778 adev->cfgopt_manufacturer.len = pEle[1];
4779 for (i = 0; i < pEle[1]; i++) {
4780 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4782 printk("ManufacturerID:%02X Len:%02X Data:%.*s\n",
4783 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4784 adev->cfgopt_manufacturer.len,
4785 (char *)adev->cfgopt_manufacturer.list);
4787 printk("EEPROM part:\n");
4788 for (i=0; i<58; i++) {
4789 printk("%02X =======> 0x%02X\n",
4790 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4796 /***********************************************************************
4797 ** Linux Kernel Specific
4799 static int __init acx_e_init_module(void)
4801 int r1, r2;
4803 acx_struct_size_check();
4805 printk("acx: this driver is still EXPERIMENTAL\n"
4806 "acx: reading README file and/or Craig's HOWTO is "
4807 "recommended, visit http://acx100.sourceforge.net/wiki in case "
4808 "of further questions/discussion\n");
4810 #if defined(CONFIG_ACX_MAC80211_PCI)
4811 r1 = acxpci_e_init_module();
4812 #else
4813 r1 = -EINVAL;
4814 #endif
4815 #if defined(CONFIG_ACX_MAC80211_USB)
4816 r2 = acxusb_e_init_module();
4817 #else
4818 r2 = -EINVAL;
4819 #endif
4820 if (r2 && r1) /* both failed! */
4821 return r2 ? r2 : r1;
4822 /* return success if at least one succeeded */
4823 return 0;
4826 static void __exit acx_e_cleanup_module(void)
4828 #if defined(CONFIG_ACX_MAC80211_PCI)
4829 acxpci_e_cleanup_module();
4830 #endif
4831 #if defined(CONFIG_ACX_MAC80211_USB)
4832 acxusb_e_cleanup_module();
4833 #endif
4836 module_init(acx_e_init_module)
4837 module_exit(acx_e_cleanup_module)