fixed bug - counter was checked wrong
[acx-mac80211.git] / common.c
bloba095138e0980a777f771552642a7f91b26aefd99
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 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1708 unsigned short netflags, int mc_count)
1709 #else
1710 unsigned int changed_flags,
1711 unsigned int *total_flags,
1712 int mc_count, struct dev_addr_list *mc_list)
1713 #endif
1715 acx_device_t *adev = ieee2adev(hw);
1716 unsigned long flags;
1718 FN_ENTER;
1720 acx_lock(adev, flags);
1722 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
1723 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI);
1724 if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1725 return;
1726 #endif
1728 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1729 if (netflags & (IFF_PROMISC | IFF_ALLMULTI)) {
1730 #else
1731 if (*total_flags) {
1732 #endif
1733 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1734 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1735 SET_BIT(adev->set_mask, SET_RXCONFIG);
1736 /* let kernel know in case *we* needed to set promiscuous */
1737 } else {
1738 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1739 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1740 SET_BIT(adev->set_mask, SET_RXCONFIG);
1743 /* cannot update card settings directly here, atomic context */
1744 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
1746 acx_unlock(adev, flags);
1748 FN_EXIT0;
1751 /***********************************************************************
1752 ** acx111 feature config
1754 ** Obvious
1756 static int
1757 acx111_s_get_feature_config(acx_device_t * adev,
1758 u32 * feature_options, u32 * data_flow_options)
1760 struct acx111_ie_feature_config feat;
1762 FN_ENTER;
1764 if (!IS_ACX111(adev)) {
1765 return NOT_OK;
1768 memset(&feat, 0, sizeof(feat));
1770 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1771 FN_EXIT1(NOT_OK);
1772 return NOT_OK;
1774 log(L_DEBUG,
1775 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1776 feat.feature_options, feat.data_flow_options);
1778 if (feature_options)
1779 *feature_options = le32_to_cpu(feat.feature_options);
1780 if (data_flow_options)
1781 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1783 FN_EXIT0;
1784 return OK;
1788 static int
1789 acx111_s_set_feature_config(acx_device_t * adev,
1790 u32 feature_options, u32 data_flow_options,
1791 unsigned int mode
1792 /* 0 == remove, 1 == add, 2 == set */ )
1794 struct acx111_ie_feature_config feat;
1796 FN_ENTER;
1798 if (!IS_ACX111(adev)) {
1799 FN_EXIT1(NOT_OK);
1800 return NOT_OK;
1803 if ((mode < 0) || (mode > 2)) {
1804 FN_EXIT1(NOT_OK);
1805 return NOT_OK;
1808 if (mode != 2)
1809 /* need to modify old data */
1810 acx111_s_get_feature_config(adev, &feat.feature_options,
1811 &feat.data_flow_options);
1812 else {
1813 /* need to set a completely new value */
1814 feat.feature_options = 0;
1815 feat.data_flow_options = 0;
1818 if (mode == 0) { /* remove */
1819 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1820 CLEAR_BIT(feat.data_flow_options,
1821 cpu_to_le32(data_flow_options));
1822 } else { /* add or set */
1823 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1824 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1827 log(L_DEBUG,
1828 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1829 "new: feature 0x%08X dataflow 0x%08X\n",
1830 feature_options, data_flow_options, mode,
1831 le32_to_cpu(feat.feature_options),
1832 le32_to_cpu(feat.data_flow_options));
1834 if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1835 FN_EXIT1(NOT_OK);
1836 return NOT_OK;
1839 FN_EXIT0;
1840 return OK;
1843 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1845 return acx111_s_set_feature_config(adev, f, d, 0);
1847 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1849 return acx111_s_set_feature_config(adev, f, d, 1);
1851 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1853 return acx111_s_set_feature_config(adev, f, d, 2);
1857 /***********************************************************************
1858 ** acx100_s_init_memory_pools
1860 static int
1861 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1863 acx100_ie_memblocksize_t MemoryBlockSize;
1864 acx100_ie_memconfigoption_t MemoryConfigOption;
1865 int TotalMemoryBlocks;
1866 int RxBlockNum;
1867 int TotalRxBlockSize;
1868 int TxBlockNum;
1869 int TotalTxBlockSize;
1871 FN_ENTER;
1873 /* Let's see if we can follow this:
1874 first we select our memory block size (which I think is
1875 completely arbitrary) */
1876 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1878 /* Then we alert the card to our decision of block size */
1879 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
1880 goto bad;
1883 /* We figure out how many total blocks we can create, using
1884 the block size we chose, and the beginning and ending
1885 memory pointers, i.e.: end-start/size */
1886 TotalMemoryBlocks =
1887 (le32_to_cpu(mmt->PoolEnd) -
1888 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1890 log(L_DEBUG, "TotalMemoryBlocks=%u (%u bytes)\n",
1891 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1893 /* MemoryConfigOption.DMA_config bitmask:
1894 access to ACX memory is to be done:
1895 0x00080000 using PCI conf space?!
1896 0x00040000 using IO instructions?
1897 0x00000000 using memory access instructions
1898 0x00020000 using local memory block linked list (else what?)
1899 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1901 if (IS_PCI(adev)) {
1902 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1903 /* Declare start of the Rx host pool */
1904 MemoryConfigOption.pRxHostDesc =
1905 cpu2acx(adev->rxhostdesc_startphy);
1906 log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
1907 acx2cpu(MemoryConfigOption.pRxHostDesc),
1908 (long)adev->rxhostdesc_startphy);
1909 } else {
1910 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1913 /* 50% of the allotment of memory blocks go to tx descriptors */
1914 TxBlockNum = TotalMemoryBlocks / 2;
1915 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1917 /* and 50% go to the rx descriptors */
1918 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1919 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1921 /* size of the tx and rx descriptor queues */
1922 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1923 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1924 log(L_DEBUG, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u "
1925 "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum,
1926 TotalTxBlockSize, TotalRxBlockSize);
1929 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1930 MemoryConfigOption.rx_mem =
1931 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1933 /* align the rx descriptor queue to units of 0x20
1934 * and offset it by the tx descriptor queue */
1935 MemoryConfigOption.tx_mem =
1936 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
1937 0x1f) & ~0x1f);
1938 log(L_DEBUG, "rx_mem %08X rx_mem %08X\n", MemoryConfigOption.tx_mem,
1939 MemoryConfigOption.rx_mem);
1941 /* alert the device to our decision */
1942 if (OK !=
1943 acx_s_configure(adev, &MemoryConfigOption,
1944 ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
1945 goto bad;
1948 /* and tell the device to kick it into gear */
1949 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
1950 goto bad;
1952 FN_EXIT1(OK);
1953 return OK;
1954 bad:
1955 FN_EXIT1(NOT_OK);
1956 return NOT_OK;
1960 /***********************************************************************
1961 ** acx100_s_create_dma_regions
1963 ** Note that this fn messes up heavily with hardware, but we cannot
1964 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1966 static int acx100_s_create_dma_regions(acx_device_t * adev)
1968 acx100_ie_queueconfig_t queueconf;
1969 acx_ie_memmap_t memmap;
1970 int res = NOT_OK;
1971 u32 tx_queue_start, rx_queue_start;
1973 FN_ENTER;
1975 /* read out the acx100 physical start address for the queues */
1976 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1977 goto fail;
1980 tx_queue_start = le32_to_cpu(memmap.QueueStart);
1981 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
1983 log(L_DEBUG, "initializing Queue Indicator\n");
1985 memset(&queueconf, 0, sizeof(queueconf));
1987 /* Not needed for PCI, so we can avoid setting them altogether */
1988 if (IS_USB(adev)) {
1989 queueconf.NumTxDesc = USB_TX_CNT;
1990 queueconf.NumRxDesc = USB_RX_CNT;
1993 /* calculate size of queues */
1994 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
1995 RX_CNT * sizeof(rxdesc_t) + 8);
1996 queueconf.NumTxQueues = 1; /* number of tx queues */
1997 /* sets the beginning of the tx descriptor queue */
1998 queueconf.TxQueueStart = memmap.QueueStart;
1999 /* done by memset: queueconf.TxQueuePri = 0; */
2000 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
2001 queueconf.QueueOptions = 1; /* auto reset descriptor */
2002 /* sets the end of the rx descriptor queue */
2003 queueconf.QueueEnd =
2004 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
2006 /* sets the beginning of the next queue */
2007 queueconf.HostQueueEnd =
2008 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
2009 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
2010 goto fail;
2013 if (IS_PCI(adev)) {
2014 /* sets the beginning of the rx descriptor queue, after the tx descrs */
2015 if (OK != acxpci_s_create_hostdesc_queues(adev))
2016 goto fail;
2017 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2020 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2021 goto fail;
2024 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
2025 0x1f) & ~0x1f);
2027 if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2028 goto fail;
2031 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
2032 goto fail;
2035 res = OK;
2036 goto end;
2038 fail:
2039 acx_s_mdelay(1000); /* ? */
2040 if (IS_PCI(adev))
2041 acxpci_free_desc_queues(adev);
2042 end:
2043 FN_EXIT1(res);
2044 return res;
2048 /***********************************************************************
2049 ** acx111_s_create_dma_regions
2051 ** Note that this fn messes heavily with hardware, but we cannot
2052 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2054 #define ACX111_PERCENT(percent) ((percent)/5)
2056 static int acx111_s_create_dma_regions(acx_device_t * adev)
2058 struct acx111_ie_memoryconfig memconf;
2059 struct acx111_ie_queueconfig queueconf;
2060 u32 tx_queue_start, rx_queue_start;
2062 FN_ENTER;
2064 /* Calculate memory positions and queue sizes */
2066 /* Set up our host descriptor pool + data pool */
2067 if (IS_PCI(adev)) {
2068 if (OK != acxpci_s_create_hostdesc_queues(adev))
2069 goto fail;
2072 memset(&memconf, 0, sizeof(memconf));
2073 /* the number of STAs (STA contexts) to support
2074 ** NB: was set to 1 and everything seemed to work nevertheless... */
2075 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
2076 /* specify the memory block size. Default is 256 */
2077 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
2078 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
2079 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
2080 /* set the count of our queues
2081 ** NB: struct acx111_ie_memoryconfig shall be modified
2082 ** if we ever will switch to more than one rx and/or tx queue */
2083 memconf.count_rx_queues = 1;
2084 memconf.count_tx_queues = 1;
2085 /* 0 == Busmaster Indirect Memory Organization, which is what we want
2086 * (using linked host descs with their allocated mem).
2087 * 2 == Generic Bus Slave */
2088 /* done by memset: memconf.options = 0; */
2089 /* let's use 25% for fragmentations and 75% for frame transfers
2090 * (specified in units of 5%) */
2091 memconf.fragmentation = ACX111_PERCENT(75);
2092 /* Rx descriptor queue config */
2093 memconf.rx_queue1_count_descs = RX_CNT;
2094 memconf.rx_queue1_type = 7; /* must be set to 7 */
2095 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2096 if (IS_PCI(adev)) {
2097 memconf.rx_queue1_host_rx_start =
2098 cpu2acx(adev->rxhostdesc_startphy);
2100 /* Tx descriptor queue config */
2101 memconf.tx_queue1_count_descs = TX_CNT;
2102 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2104 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
2105 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2106 ** But it is actually correct wrt IE numbers.
2107 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
2108 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2109 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2110 if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
2111 goto fail;
2114 acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
2116 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2117 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2119 log(L_INIT, "dump queue head (from card):\n"
2120 "len: %u\n"
2121 "tx_memory_block_address: %X\n"
2122 "rx_memory_block_address: %X\n"
2123 "tx1_queue address: %X\n"
2124 "rx1_queue address: %X\n",
2125 le16_to_cpu(queueconf.len),
2126 le32_to_cpu(queueconf.tx_memory_block_address),
2127 le32_to_cpu(queueconf.rx_memory_block_address),
2128 tx_queue_start, rx_queue_start);
2130 if (IS_PCI(adev))
2131 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2133 FN_EXIT1(OK);
2134 return OK;
2135 fail:
2136 if (IS_PCI(adev))
2137 acxpci_free_desc_queues(adev);
2139 FN_EXIT1(NOT_OK);
2140 return NOT_OK;
2144 /***********************************************************************
2146 static void acx_s_initialize_rx_config(acx_device_t * adev)
2148 struct {
2149 u16 id;
2150 u16 len;
2151 u16 rx_cfg1;
2152 u16 rx_cfg2;
2153 } ACX_PACKED cfg;
2154 switch (adev->mode) {
2155 case ACX_MODE_MONITOR:
2156 adev->rx_config_1 = (u16) (0
2157 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2158 /* | RX_CFG1_FILTER_SSID */
2159 /* | RX_CFG1_FILTER_BCAST */
2160 /* | RX_CFG1_RCV_MC_ADDR1 */
2161 /* | RX_CFG1_RCV_MC_ADDR0 */
2162 /* | RX_CFG1_FILTER_ALL_MULTI */
2163 /* | RX_CFG1_FILTER_BSSID */
2164 /* | RX_CFG1_FILTER_MAC */
2165 | RX_CFG1_RCV_PROMISCUOUS
2166 | RX_CFG1_INCLUDE_FCS
2167 /* | RX_CFG1_INCLUDE_PHY_HDR */
2169 adev->rx_config_2 = (u16) (0
2170 | RX_CFG2_RCV_ASSOC_REQ
2171 | RX_CFG2_RCV_AUTH_FRAMES
2172 | RX_CFG2_RCV_BEACON_FRAMES
2173 | RX_CFG2_RCV_CONTENTION_FREE
2174 | RX_CFG2_RCV_CTRL_FRAMES
2175 | RX_CFG2_RCV_DATA_FRAMES
2176 | RX_CFG2_RCV_BROKEN_FRAMES
2177 | RX_CFG2_RCV_MGMT_FRAMES
2178 | RX_CFG2_RCV_PROBE_REQ
2179 | RX_CFG2_RCV_PROBE_RESP
2180 | RX_CFG2_RCV_ACK_FRAMES
2181 | RX_CFG2_RCV_OTHER);
2182 break;
2183 default:
2184 adev->rx_config_1 = (u16) (0
2185 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2186 /* | RX_CFG1_FILTER_SSID */
2187 /* | RX_CFG1_FILTER_BCAST */
2188 /* | RX_CFG1_RCV_MC_ADDR1 */
2189 /* | RX_CFG1_RCV_MC_ADDR0 */
2190 /* | RX_CFG1_FILTER_ALL_MULTI */
2191 /* | RX_CFG1_FILTER_BSSID */
2192 /* | RX_CFG1_FILTER_MAC */
2193 | RX_CFG1_RCV_PROMISCUOUS
2194 /* | RX_CFG1_INCLUDE_FCS */
2195 /* | RX_CFG1_INCLUDE_PHY_HDR */
2197 adev->rx_config_2 = (u16) (0
2198 | RX_CFG2_RCV_ASSOC_REQ
2199 | RX_CFG2_RCV_AUTH_FRAMES
2200 | RX_CFG2_RCV_BEACON_FRAMES
2201 | RX_CFG2_RCV_CONTENTION_FREE
2202 | RX_CFG2_RCV_CTRL_FRAMES
2203 | RX_CFG2_RCV_DATA_FRAMES
2204 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2205 | RX_CFG2_RCV_MGMT_FRAMES
2206 | RX_CFG2_RCV_PROBE_REQ
2207 | RX_CFG2_RCV_PROBE_RESP
2208 | RX_CFG2_RCV_ACK_FRAMES
2209 | RX_CFG2_RCV_OTHER);
2210 break;
2212 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2214 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2215 || (adev->firmware_numver >= 0x02000000))
2216 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2217 else
2218 adev->phy_header_len = 0;
2220 log(L_INIT, "setting RXconfig to %04X:%04X\n",
2221 adev->rx_config_1, adev->rx_config_2);
2222 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2223 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2224 acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
2228 /***********************************************************************
2229 ** acx_s_set_defaults
2231 void acx_s_set_defaults(acx_device_t * adev)
2233 unsigned long flags;
2235 FN_ENTER;
2237 acx_lock(adev, flags);
2238 /* do it before getting settings, prevent bogus channel 0 warning */
2239 adev->channel = 1;
2241 /* query some settings from the card.
2242 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2243 * query is REQUIRED, otherwise the card won't work correctly! */
2244 adev->get_mask =
2245 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2246 GETSET_REG_DOMAIN;
2247 /* Only ACX100 supports ED and CCA */
2248 if (IS_ACX100(adev))
2249 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2251 acx_s_update_card_settings(adev);
2254 /* set our global interrupt mask */
2255 if (IS_PCI(adev))
2256 acxpci_set_interrupt_mask(adev);
2258 adev->led_power = 1; /* LED is active on startup */
2259 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2260 adev->brange_time_last_state_change = jiffies;
2262 /* copy the MAC address we just got from the card
2263 * into our MAC address used during current 802.11 session */
2264 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
2265 MAC_BCAST(adev->ap);
2267 adev->essid_len =
2268 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2269 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2270 adev->essid_active = 1;
2272 /* we have a nick field to waste, so why not abuse it
2273 * to announce the driver version? ;-) */
2274 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2276 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2277 /* first regulatory domain entry in EEPROM == default reg. domain */
2278 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2281 /* 0xffff would be better, but then we won't get a "scan complete"
2282 * interrupt, so our current infrastructure will fail: */
2283 adev->scan_count = 1;
2284 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2285 adev->scan_duration = 100;
2286 adev->scan_probe_delay = 200;
2287 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2288 adev->scan_rate = ACX_SCAN_RATE_1;
2291 adev->mode = ACX_MODE_2_STA;
2292 adev->listen_interval = 100;
2293 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2294 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2296 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2298 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2299 adev->frag_threshold = 2346;
2301 /* use standard default values for retry limits */
2302 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2303 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2305 adev->preamble_mode = 2; /* auto */
2306 adev->fallback_threshold = 3;
2307 adev->stepup_threshold = 10;
2308 adev->rate_bcast = RATE111_1;
2309 adev->rate_bcast100 = RATE100_1;
2310 adev->rate_basic = RATE111_1 | RATE111_2;
2311 adev->rate_auto = 1;
2312 if (IS_ACX111(adev)) {
2313 adev->rate_oper = RATE111_ALL;
2314 } else {
2315 adev->rate_oper = RATE111_ACX100_COMPAT;
2318 /* Supported Rates element - the rates here are given in units of
2319 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2320 acx_l_update_ratevector(adev);
2322 /* set some more defaults */
2323 if (IS_ACX111(adev)) {
2324 /* 30mW (15dBm) is default, at least in my acx111 card: */
2325 adev->tx_level_dbm = 15;
2326 } else {
2327 /* don't use max. level, since it might be dangerous
2328 * (e.g. WRT54G people experience
2329 * excessive Tx power damage!) */
2330 adev->tx_level_dbm = 18;
2332 /* adev->tx_level_auto = 1; */
2333 if (IS_ACX111(adev)) {
2334 /* start with sensitivity level 1 out of 3: */
2335 adev->sensitivity = 1;
2338 /* #define ENABLE_POWER_SAVE */
2339 #ifdef ENABLE_POWER_SAVE
2340 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2341 adev->ps_listen_interval = 1;
2342 adev->ps_options =
2343 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2344 adev->ps_hangover_period = 30;
2345 adev->ps_enhanced_transition_time = 0;
2346 #else
2347 adev->ps_wakeup_cfg = 0;
2348 adev->ps_listen_interval = 0;
2349 adev->ps_options = 0;
2350 adev->ps_hangover_period = 0;
2351 adev->ps_enhanced_transition_time = 0;
2352 #endif
2354 /* These settings will be set in fw on ifup */
2355 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2356 /* configure card to do rate fallback when in auto rate mode */
2357 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2358 /* better re-init the antenna value we got above */
2359 | GETSET_ANTENNA
2360 #if POWER_SAVE_80211
2361 | GETSET_POWER_80211
2362 #endif
2365 acx_unlock(adev, flags);
2366 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2368 acx_s_initialize_rx_config(adev);
2370 FN_EXIT0;
2374 /***********************************************************************
2375 ** FIXME: this should be solved in a general way for all radio types
2376 ** by decoding the radio firmware module,
2377 ** since it probably has some standard structure describing how to
2378 ** set the power level of the radio module which it controls.
2379 ** Or maybe not, since the radio module probably has a function interface
2380 ** instead which then manages Tx level programming :-\
2382 ** Obvious
2384 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2386 struct acx111_ie_tx_level tx_level;
2388 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2389 * 1 (30mW) [15dBm]
2390 * 2 (10mW) [10dBm]
2391 * For now, just assume all other acx111 cards have the same.
2392 * FIXME: Ideally we would query it here, but we first need a
2393 * standard way to query individual configoptions easily.
2394 * Well, now we have proper cfgopt txpower variables, but this still
2395 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2396 if (level_dbm <= 12) {
2397 tx_level.level = 2; /* 10 dBm */
2398 adev->tx_level_dbm = 10;
2399 } else {
2400 tx_level.level = 1; /* 15 dBm */
2401 adev->tx_level_dbm = 15;
2403 /* if (level_dbm != adev->tx_level_dbm)
2404 log(L_INIT, "acx111 firmware has specific "
2405 "power levels only: adjusted %d dBm to %d dBm!\n",
2406 level_dbm, adev->tx_level_dbm);
2408 return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
2411 static int acx_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2413 if (IS_ACX111(adev)) {
2414 return acx111_s_set_tx_level(adev, level_dbm);
2416 if (IS_PCI(adev)) {
2417 return acx100pci_s_set_tx_level(adev, level_dbm);
2419 return OK;
2422 /***********************************************************************
2423 ** acx_l_process_rxbuf
2425 ** NB: used by USB code also
2427 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2429 struct ieee80211_hdr *hdr;
2430 u16 fc, buf_len;
2431 hdr = acx_get_wlan_hdr(adev, rxbuf);
2432 fc = le16_to_cpu(hdr->frame_control);
2433 /* length of frame from control field to first byte of FCS */
2434 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2436 if (unlikely(acx_debug & L_DATA)) {
2437 printk("rx: 802.11 buf[%u]: ", buf_len);
2438 acx_dump_bytes(hdr, buf_len);
2442 acx_l_rx(adev, rxbuf);
2443 /* Now check Rx quality level, AFTER processing packet.
2444 * I tried to figure out how to map these levels to dBm
2445 * values, but for the life of me I really didn't
2446 * manage to get it. Either these values are not meant to
2447 * be expressed in dBm, or it's some pretty complicated
2448 * calculation. */
2450 #ifdef FROM_SCAN_SOURCE_ONLY
2451 /* only consider packets originating from the MAC
2452 * address of the device that's managing our BSSID.
2453 * Disable it for now, since it removes information (levels
2454 * from different peers) and slows the Rx path. *//*
2455 if (adev->ap_client && mac_is_equal(hdr->a2, adev->ap_client->address)) {
2457 #endif
2461 /***********************************************************************
2462 ** acx_l_handle_txrate_auto
2464 ** Theory of operation:
2465 ** client->rate_cap is a bitmask of rates client is capable of.
2466 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2467 ** It is set as a result of iwconfig rate N [auto]
2468 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2469 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2470 ** auto (0x00ff == 18Mbit or any lower value),
2471 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2473 ** client->rate_cur is a value for rate111 field in tx descriptor.
2474 ** It is always set to txrate_cfg sans zero or more most significant
2475 ** bits. This routine handles selection of new rate_cur value depending on
2476 ** outcome of last tx event.
2478 ** client->rate_100 is a precalculated rate value for acx100
2479 ** (we can do without it, but will need to calculate it on each tx).
2481 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2482 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2483 ** In theory you can implement it, but so far it is considered not worth doing.
2485 ** 22Mbit, of course, is PBCC always. */
2487 /* maps acx100 tx descr rate field to acx111 one */
2489 static u16 rate100to111(u8 r)
2491 switch (r) {
2492 case RATE100_1:
2493 return RATE111_1;
2494 case RATE100_2:
2495 return RATE111_2;
2496 case RATE100_5:
2497 case (RATE100_5 | RATE100_PBCC511):
2498 return RATE111_5;
2499 case RATE100_11:
2500 case (RATE100_11 | RATE100_PBCC511):
2501 return RATE111_11;
2502 case RATE100_22:
2503 return RATE111_22;
2504 default:
2505 printk("acx: unexpected acx100 txrate: %u! "
2506 "Please report\n", r);
2507 return RATE111_1;
2514 acx_i_start_xmit(struct ieee80211_hw *hw,
2515 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2517 acx_device_t *adev = ieee2adev(hw);
2518 tx_t *tx;
2519 void *txbuf;
2520 unsigned long flags;
2522 int txresult = NOT_OK;
2524 FN_ENTER;
2526 if (unlikely(!skb)) {
2527 /* indicate success */
2528 txresult = OK;
2529 goto end_no_unlock;
2532 if (unlikely(!adev)) {
2533 goto end_no_unlock;
2537 acx_lock(adev, flags);
2539 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2540 goto end;
2542 if (unlikely(!adev->initialized)) {
2543 goto end;
2546 tx = acx_l_alloc_tx(adev);
2548 if (unlikely(!tx)) {
2549 printk_ratelimited("%s: start_xmit: txdesc ring is full, "
2550 "dropping tx\n", wiphy_name(adev->ieee->wiphy));
2551 txresult = NOT_OK;
2552 goto end;
2555 txbuf = acx_l_get_txbuf(adev, tx);
2557 if (unlikely(!txbuf)) {
2558 /* Card was removed */
2559 txresult = NOT_OK;
2560 acx_l_dealloc_tx(adev, tx);
2561 goto end;
2563 memcpy(txbuf, skb->data, skb->len);
2565 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2567 txresult = OK;
2568 adev->stats.tx_packets++;
2569 adev->stats.tx_bytes += skb->len;
2571 end:
2572 acx_unlock(adev, flags);
2574 end_no_unlock:
2576 FN_EXIT1(txresult);
2577 return txresult;
2579 /***********************************************************************
2580 ** acx_l_update_ratevector
2582 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2584 const u8 acx_bitpos2ratebyte[] = {
2585 DOT11RATEBYTE_1,
2586 DOT11RATEBYTE_2,
2587 DOT11RATEBYTE_5_5,
2588 DOT11RATEBYTE_6_G,
2589 DOT11RATEBYTE_9_G,
2590 DOT11RATEBYTE_11,
2591 DOT11RATEBYTE_12_G,
2592 DOT11RATEBYTE_18_G,
2593 DOT11RATEBYTE_22,
2594 DOT11RATEBYTE_24_G,
2595 DOT11RATEBYTE_36_G,
2596 DOT11RATEBYTE_48_G,
2597 DOT11RATEBYTE_54_G,
2600 void acx_l_update_ratevector(acx_device_t * adev)
2602 u16 bcfg = adev->rate_basic;
2603 u16 ocfg = adev->rate_oper;
2604 u8 *supp = adev->rate_supported;
2605 const u8 *dot11 = acx_bitpos2ratebyte;
2607 FN_ENTER;
2609 while (ocfg) {
2610 if (ocfg & 1) {
2611 *supp = *dot11;
2612 if (bcfg & 1) {
2613 *supp |= 0x80;
2615 supp++;
2617 dot11++;
2618 ocfg >>= 1;
2619 bcfg >>= 1;
2621 adev->rate_supported_len = supp - adev->rate_supported;
2622 if (acx_debug & L_ASSOC) {
2623 printk("new ratevector: ");
2624 acx_dump_bytes(adev->rate_supported, adev->rate_supported_len);
2626 FN_EXIT0;
2629 /***********************************************************************
2630 ** acx_i_timer
2632 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2634 ** Obvious
2636 void acx_i_timer(unsigned long address)
2638 unsigned long flags;
2639 acx_device_t *adev = (acx_device_t *) address;
2641 FN_ENTER;
2643 acx_lock(adev, flags);
2645 FIXME();
2646 /* We need calibration and stats gather tasks to perform here */
2648 acx_unlock(adev, flags);
2650 FN_EXIT0;
2654 /***********************************************************************
2655 ** acx_set_timer
2657 ** Sets the 802.11 state management timer's timeout.
2659 ** Linux derived
2661 void acx_set_timer(acx_device_t * adev, int timeout_us)
2663 FN_ENTER;
2665 log(L_DEBUG | L_IRQ, "%s(%u ms)\n", __func__, timeout_us / 1000);
2666 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2667 printk("attempt to set the timer "
2668 "when the card interface is not up!\n");
2669 goto end;
2672 /* first check if the timer was already initialized, THEN modify it */
2673 if (adev->mgmt_timer.function) {
2674 mod_timer(&adev->mgmt_timer,
2675 jiffies + (timeout_us * HZ / 1000000));
2677 end:
2678 FN_EXIT0;
2681 /** acx_plcp_get_bitrate_cck
2683 ** Obvious
2685 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2687 switch (plcp) {
2688 case 0x0A:
2689 return ACX_CCK_RATE_1MB;
2690 case 0x14:
2691 return ACX_CCK_RATE_2MB;
2692 case 0x37:
2693 return ACX_CCK_RATE_5MB;
2694 case 0x6E:
2695 return ACX_CCK_RATE_11MB;
2697 return 0;
2700 /* Extract the bitrate out of an OFDM PLCP header. */
2701 /** Obvious **/
2702 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2704 switch (plcp & 0xF) {
2705 case 0xB:
2706 return ACX_OFDM_RATE_6MB;
2707 case 0xF:
2708 return ACX_OFDM_RATE_9MB;
2709 case 0xA:
2710 return ACX_OFDM_RATE_12MB;
2711 case 0xE:
2712 return ACX_OFDM_RATE_18MB;
2713 case 0x9:
2714 return ACX_OFDM_RATE_24MB;
2715 case 0xD:
2716 return ACX_OFDM_RATE_36MB;
2717 case 0x8:
2718 return ACX_OFDM_RATE_48MB;
2719 case 0xC:
2720 return ACX_OFDM_RATE_54MB;
2722 return 0;
2726 /***********************************************************************
2727 ** acx_l_rx
2729 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2730 ** buffer and feeds it to the network stack via netif_rx().
2732 ** Look to bcm43xx or p54
2734 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2737 struct ieee80211_rx_status* status = &adev->rx_status;
2738 struct ieee80211_hdr *w_hdr;
2739 int buflen;
2740 FN_ENTER;
2742 if (likely(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2743 struct sk_buff *skb;
2744 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2745 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2746 skb = dev_alloc_skb(buflen + 2);
2747 skb_reserve(skb, 2);
2748 skb_put(skb, buflen);
2749 memcpy(skb->data, w_hdr, buflen);
2751 // memset(&status, 0, sizeof(status));
2753 if (likely(skb)) {
2754 adev->acx_stats.last_rx = jiffies;
2755 status->mactime = rxbuf->time;
2756 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2757 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr);
2758 status->flag = 0;
2759 status->rate = rxbuf->phy_plcp_signal;
2760 status->antenna = 1;
2762 #ifndef OLD_QUALITY
2763 qual = acx_signal_determine_quality(adev->wstats.qual.level,
2764 adev->wstats.qual.noise);
2765 #else
2766 qual = (adev->wstats.qual.noise <= 100) ?
2767 100 - adev->wstats.qual.noise : 0;
2768 #endif
2769 adev->wstats.qual.qual = qual;
2770 adev->wstats.qual.updated = 7; *//* all 3 indicators updated */
2772 #ifdef FROM_SCAN_SOURCE_ONLY
2774 #endif
2776 if (rxbuf->phy_stat_baseband & (1 << 3)) /* Uses OFDM */
2778 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2779 } else
2781 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2783 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2784 adev->stats.rx_packets++;
2785 adev->stats.rx_bytes += skb->len;
2788 FN_EXIT0;
2793 /***********************************************************************
2794 ** acx_s_read_fw
2796 ** Loads a firmware image
2798 ** Returns:
2799 ** 0 unable to load file
2800 ** pointer to firmware success
2802 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2803 u32 * size)
2805 firmware_image_t *res;
2806 const struct firmware *fw_entry;
2808 res = NULL;
2809 log(L_INIT, "requesting firmware image '%s'\n", file);
2810 if (!request_firmware(&fw_entry, file, dev)) {
2811 *size = 8;
2812 if (fw_entry->size >= 8)
2813 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2814 if (fw_entry->size != *size) {
2815 printk("acx: firmware size does not match "
2816 "firmware header: %d != %d, "
2817 "aborting fw upload\n",
2818 (int)fw_entry->size, (int)*size);
2819 goto release_ret;
2821 res = vmalloc(*size);
2822 if (!res) {
2823 printk("acx: no memory for firmware "
2824 "(%u bytes)\n", *size);
2825 goto release_ret;
2827 memcpy(res, fw_entry->data, fw_entry->size);
2828 release_ret:
2829 release_firmware(fw_entry);
2830 return res;
2832 printk("acx: firmware image '%s' was not provided. "
2833 "Check your hotplug scripts\n", file);
2835 /* checksum will be verified in write_fw, so don't bother here */
2836 return res;
2840 /***********************************************************************
2841 ** acx_s_set_wepkey
2843 static void acx100_s_set_wepkey(acx_device_t * adev)
2845 ie_dot11WEPDefaultKey_t dk;
2846 int i;
2848 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2849 if (adev->wep_keys[i].size != 0) {
2850 log(L_INIT, "setting WEP key: %d with "
2851 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2852 dk.action = 1;
2853 dk.keySize = adev->wep_keys[i].size;
2854 dk.defaultKeyNum = i;
2855 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2856 acx_s_configure(adev, &dk,
2857 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
2862 static void acx111_s_set_wepkey(acx_device_t * adev)
2864 acx111WEPDefaultKey_t dk;
2865 int i;
2867 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2868 if (adev->wep_keys[i].size != 0) {
2869 log(L_INIT, "setting WEP key: %d with "
2870 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2871 memset(&dk, 0, sizeof(dk));
2872 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2873 dk.keySize = adev->wep_keys[i].size;
2875 /* are these two lines necessary? */
2876 dk.type = 0; /* default WEP key */
2877 dk.index = 0; /* ignored when setting default key */
2879 dk.defaultKeyNum = i;
2880 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2881 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2882 sizeof(dk));
2886 /* Obvious */
2887 static void acx_s_set_wepkey(acx_device_t * adev)
2889 if (IS_ACX111(adev))
2890 acx111_s_set_wepkey(adev);
2891 else
2892 acx100_s_set_wepkey(adev);
2896 /***********************************************************************
2897 ** acx100_s_init_wep
2899 ** FIXME: this should probably be moved into the new card settings
2900 ** management, but since we're also modifying the memory map layout here
2901 ** due to the WEP key space we want, we should take care...
2903 static int acx100_s_init_wep(acx_device_t * adev)
2905 acx100_ie_wep_options_t options;
2906 ie_dot11WEPDefaultKeyID_t dk;
2907 acx_ie_memmap_t pt;
2908 int res = NOT_OK;
2910 FN_ENTER;
2912 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2913 goto fail;
2916 log(L_DEBUG, "CodeEnd:%X\n", pt.CodeEnd);
2918 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2919 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2921 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2922 goto fail;
2925 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2926 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2927 options.WEPOption = 0x00;
2929 log(L_ASSOC, "writing WEP options\n");
2930 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
2932 acx100_s_set_wepkey(adev);
2934 if (adev->wep_keys[adev->wep_current_index].size != 0) {
2935 log(L_ASSOC, "setting active default WEP key number: %d\n",
2936 adev->wep_current_index);
2937 dk.KeyID = adev->wep_current_index;
2938 acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
2940 /* FIXME!!! wep_key_struct is filled nowhere! But adev
2941 * is initialized to 0, and we don't REALLY need those keys either */
2942 /* for (i = 0; i < 10; i++) {
2943 if (adev->wep_key_struct[i].len != 0) {
2944 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
2945 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
2946 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
2947 wep_mgmt.Action = cpu_to_le16(1);
2948 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
2949 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
2950 adev->wep_key_struct[i].index = i;
2956 /* now retrieve the updated WEPCacheEnd pointer... */
2957 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2958 printk("%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
2959 wiphy_name(adev->ieee->wiphy));
2960 goto fail;
2962 /* ...and tell it to start allocating templates at that location */
2963 /* (no endianness conversion needed) */
2964 pt.PacketTemplateStart = pt.WEPCacheEnd;
2966 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2967 printk("%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
2968 wiphy_name(adev->ieee->wiphy));
2969 goto fail;
2971 res = OK;
2973 fail:
2974 FN_EXIT1(res);
2975 return res;
2979 static int
2980 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
2981 unsigned int cmd)
2983 int res;
2984 union {
2985 acx_template_nullframe_t null;
2986 acx_template_beacon_t b;
2987 acx_template_tim_t tim;
2988 acx_template_probereq_t preq;
2989 acx_template_proberesp_t presp;
2990 } templ;
2992 memset(&templ, 0, len);
2993 templ.null.size = cpu_to_le16(len - 2);
2994 res = acx_s_issue_cmd(adev, cmd, &templ, len);
2995 return res;
2998 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
3000 return acx_s_init_max_template_generic(adev,
3001 sizeof(acx_template_nullframe_t),
3002 ACX1xx_CMD_CONFIG_NULL_DATA);
3005 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
3007 return acx_s_init_max_template_generic(adev,
3008 sizeof(acx_template_beacon_t),
3009 ACX1xx_CMD_CONFIG_BEACON);
3012 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
3014 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
3015 ACX1xx_CMD_CONFIG_TIM);
3018 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
3020 return acx_s_init_max_template_generic(adev,
3021 sizeof(acx_template_proberesp_t),
3022 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
3025 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
3027 return acx_s_init_max_template_generic(adev,
3028 sizeof(acx_template_probereq_t),
3029 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
3032 /***********************************************************************
3033 ** acx_s_set_tim_template
3035 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
3036 ** by calling this function
3037 ** (it can be done by irq handler on each DTIM irq or by timer...)
3039 [802.11 7.3.2.6] TIM information element:
3040 - 1 EID
3041 - 1 Length
3042 1 1 DTIM Count
3043 indicates how many beacons (including this) appear before next DTIM
3044 (0=this one is a DTIM)
3045 2 1 DTIM Period
3046 number of beacons between successive DTIMs
3047 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
3048 3 1 Bitmap Control
3049 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
3050 set to 1 in TIM elements with a value of 0 in the DTIM Count field
3051 when one or more broadcast or multicast frames are buffered at the AP.
3052 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
3053 4 n Partial Virtual Bitmap
3054 Visible part of traffic-indication bitmap.
3055 Full bitmap consists of 2008 bits (251 octets) such that bit number N
3056 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
3057 in octet number N/8 where the low-order bit of each octet is bit0,
3058 and the high order bit is bit7.
3059 Each set bit in virtual bitmap corresponds to traffic buffered by AP
3060 for a specific station (with corresponding AID?).
3061 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
3062 Bitmap Offset is a number of skipped zero octets (see above).
3063 'Missing' octets at the tail are also assumed to be zero.
3064 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
3065 This means that traffic-indication bitmap is:
3066 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
3067 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
3069 static int acx_s_set_tim_template(acx_device_t * adev)
3071 /* For now, configure smallish test bitmap, all zero ("no pending data") */
3072 enum { bitmap_size = 5 };
3074 acx_template_tim_t t;
3075 int result;
3077 FN_ENTER;
3079 memset(&t, 0, sizeof(t));
3080 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3081 t.tim_eid = WLAN_EID_TIM;
3082 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3083 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3084 FN_EXIT1(result);
3085 return result;
3091 #if POWER_SAVE_80211
3092 /***********************************************************************
3093 ** acx_s_set_null_data_template
3095 static int acx_s_set_null_data_template(acx_device_t * adev)
3097 struct acx_template_nullframe b;
3098 int result;
3100 FN_ENTER;
3102 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3104 b.size = cpu_to_le16(sizeof(b) - 2);
3105 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3106 b.hdr.dur = 0;
3107 MAC_BCAST(b.hdr.a1);
3108 MAC_COPY(b.hdr.a2, adev->dev_addr);
3109 MAC_COPY(b.hdr.a3, adev->bssid);
3110 b.hdr.seq = 0;
3112 result =
3113 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3115 FN_EXIT1(result);
3116 return result;
3118 #endif
3125 /***********************************************************************
3126 ** acx_s_init_packet_templates()
3128 ** NOTE: order is very important here, to have a correct memory layout!
3129 ** init templates: max Probe Request (station mode), max NULL data,
3130 ** max Beacon, max TIM, max Probe Response.
3132 static int acx_s_init_packet_templates(acx_device_t * adev)
3134 acx_ie_memmap_t mm; /* ACX100 only */
3135 int result = NOT_OK;
3137 FN_ENTER;
3139 log(L_DEBUG | L_INIT, "initializing max packet templates\n");
3141 if (OK != acx_s_init_max_probe_request_template(adev))
3142 goto failed;
3144 if (OK != acx_s_init_max_null_data_template(adev))
3145 goto failed;
3147 if (OK != acx_s_init_max_beacon_template(adev))
3148 goto failed;
3150 if (OK != acx_s_init_max_tim_template(adev))
3151 goto failed;
3153 if (OK != acx_s_init_max_probe_response_template(adev))
3154 goto failed;
3156 if (IS_ACX111(adev)) {
3157 /* ACX111 doesn't need the memory map magic below,
3158 * and the other templates will be set later (acx_start) */
3159 result = OK;
3160 goto success;
3163 /* ACX100 will have its TIM template set,
3164 * and we also need to update the memory map */
3166 if (OK != acx_s_set_tim_template(adev))
3167 goto failed_acx100;
3169 log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3171 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3172 goto failed_acx100;
3174 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3175 if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3176 goto failed_acx100;
3178 result = OK;
3179 goto success;
3181 failed_acx100:
3182 log(L_DEBUG | L_INIT,
3183 /* "cb=0x%X\n" */
3184 "ACXMemoryMap:\n"
3185 ".CodeStart=0x%X\n"
3186 ".CodeEnd=0x%X\n"
3187 ".WEPCacheStart=0x%X\n"
3188 ".WEPCacheEnd=0x%X\n"
3189 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3190 /* len, */
3191 le32_to_cpu(mm.CodeStart),
3192 le32_to_cpu(mm.CodeEnd),
3193 le32_to_cpu(mm.WEPCacheStart),
3194 le32_to_cpu(mm.WEPCacheEnd),
3195 le32_to_cpu(mm.PacketTemplateStart),
3196 le32_to_cpu(mm.PacketTemplateEnd));
3198 failed:
3199 printk("%s: %s() FAILED\n", wiphy_name(adev->ieee->wiphy), __func__);
3201 success:
3202 FN_EXIT1(result);
3203 return result;
3208 /***********************************************************************
3209 ** acx_s_init_mac
3211 int acx_s_init_mac(acx_device_t * adev)
3213 int result = NOT_OK;
3215 FN_ENTER;
3217 if (IS_ACX111(adev)) {
3218 adev->ie_len = acx111_ie_len;
3219 adev->ie_len_dot11 = acx111_ie_len_dot11;
3220 } else {
3221 adev->ie_len = acx100_ie_len;
3222 adev->ie_len_dot11 = acx100_ie_len_dot11;
3225 if (IS_PCI(adev)) {
3226 adev->memblocksize = 256; /* 256 is default */
3227 /* try to load radio for both ACX100 and ACX111, since both
3228 * chips have at least some firmware versions making use of an
3229 * external radio module */
3230 acxpci_s_upload_radio(adev);
3231 } else {
3232 adev->memblocksize = 128;
3235 if (IS_ACX111(adev)) {
3236 /* for ACX111, the order is different from ACX100
3237 1. init packet templates
3238 2. create station context and create dma regions
3239 3. init wep default keys
3241 if (OK != acx_s_init_packet_templates(adev))
3242 goto fail;
3243 if (OK != acx111_s_create_dma_regions(adev)) {
3244 printk("%s: acx111_create_dma_regions FAILED\n",
3245 wiphy_name(adev->ieee->wiphy));
3246 goto fail;
3248 } else {
3249 if (OK != acx100_s_init_wep(adev))
3250 goto fail;
3251 if (OK != acx_s_init_packet_templates(adev))
3252 goto fail;
3253 if (OK != acx100_s_create_dma_regions(adev)) {
3254 printk("%s: acx100_create_dma_regions FAILED\n",
3255 wiphy_name(adev->ieee->wiphy));
3256 goto fail;
3260 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3261 result = OK;
3263 fail:
3264 if (result)
3265 printk("acx: init_mac() FAILED\n");
3266 FN_EXIT1(result);
3267 return result;
3272 #if POWER_SAVE_80211
3273 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3275 /* merge both structs in a union to be able to have common code */
3276 union {
3277 acx111_ie_powersave_t acx111;
3278 acx100_ie_powersave_t acx100;
3279 } pm;
3281 /* change 802.11 power save mode settings */
3282 log(L_INIT, "updating 802.11 power save mode settings: "
3283 "wakeup_cfg 0x%02X, listen interval %u, "
3284 "options 0x%02X, hangover period %u, "
3285 "enhanced_ps_transition_time %u\n",
3286 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3287 adev->ps_options, adev->ps_hangover_period,
3288 adev->ps_enhanced_transition_time);
3289 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3290 log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, "
3291 "listen interval %u, options 0x%02X, "
3292 "hangover period %u, "
3293 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3294 pm.acx111.wakeup_cfg,
3295 pm.acx111.listen_interval,
3296 pm.acx111.options,
3297 pm.acx111.hangover_period,
3298 IS_ACX111(adev) ?
3299 pm.acx111.enhanced_ps_transition_time
3300 : pm.acx100.enhanced_ps_transition_time,
3301 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3302 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3303 pm.acx111.listen_interval = adev->ps_listen_interval;
3304 pm.acx111.options = adev->ps_options;
3305 pm.acx111.hangover_period = adev->ps_hangover_period;
3306 if (IS_ACX111(adev)) {
3307 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3308 pm.acx111.enhanced_ps_transition_time =
3309 cpu_to_le32(adev->ps_enhanced_transition_time);
3310 } else {
3311 pm.acx100.enhanced_ps_transition_time =
3312 cpu_to_le16(adev->ps_enhanced_transition_time);
3314 acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT);
3315 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3316 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3317 acx_s_mdelay(40);
3318 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3319 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3320 log(L_INIT, "power save mode change %s\n",
3321 (pm.acx111.
3322 wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful");
3323 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3324 * that power save mode change was successful. */
3325 /* FIXME: we shouldn't trigger a scan immediately after
3326 * fiddling with power save mode (since the firmware is sending
3327 * a NULL frame then). */
3329 #endif
3332 /***********************************************************************
3333 ** acx_s_update_card_settings
3335 ** Applies accumulated changes in various adev->xxxx members
3336 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3337 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3339 void acx_s_set_sane_reg_domain(acx_device_t * adev, int do_set)
3342 FIXME();
3343 if (do_set) {
3344 acx_ie_generic_t dom;
3345 dom.m.bytes[0] = adev->reg_dom_id;
3346 acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3351 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3353 u32 feature1, feature2;
3355 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3356 printk("%s: invalid sensitivity setting (1..3), "
3357 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3358 adev->sensitivity = 1;
3360 acx111_s_get_feature_config(adev, &feature1, &feature2);
3361 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3362 if (adev->sensitivity > 1)
3363 SET_BIT(feature1, FEATURE1_LOW_RX);
3364 if (adev->sensitivity > 2)
3365 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3366 acx111_s_feature_set(adev, feature1, feature2);
3370 void acx_s_update_card_settings(acx_device_t * adev)
3372 unsigned long flags;
3373 unsigned int start_scan = 0;
3374 int i;
3376 FN_ENTER;
3378 log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3379 adev->get_mask, adev->set_mask);
3381 /* Track dependencies betweed various settings */
3383 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3384 log(L_INIT, "important setting has been changed. "
3385 "Need to update packet templates, too\n");
3386 SET_BIT(adev->set_mask, SET_TEMPLATES);
3388 if (adev->set_mask & GETSET_CHANNEL) {
3389 /* This will actually tune RX/TX to the channel */
3390 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3391 switch (adev->mode) {
3392 case ACX_MODE_0_ADHOC:
3393 case ACX_MODE_3_AP:
3394 /* Beacons contain channel# - update them */
3395 SET_BIT(adev->set_mask, SET_TEMPLATES);
3398 switch (adev->mode) {
3399 case ACX_MODE_0_ADHOC:
3400 case ACX_MODE_2_STA:
3401 start_scan = 1;
3405 /* Apply settings */
3408 if (adev->get_mask & GETSET_STATION_ID) {
3409 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3410 const u8 *paddr;
3412 acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3413 paddr = &stationID[4];
3414 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3415 for (i = 0; i < ETH_ALEN; i++) {
3416 /* we copy the MAC address (reversed in
3417 * the card) to the netdevice's MAC
3418 * address, and on ifup it will be
3419 * copied into iwadev->dev_addr */
3420 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3422 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3423 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3426 if (adev->get_mask & GETSET_SENSITIVITY) {
3427 if ((RADIO_RFMD_11 == adev->radio_type)
3428 || (RADIO_MAXIM_0D == adev->radio_type)
3429 || (RADIO_RALINK_15 == adev->radio_type)) {
3430 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3431 } else {
3432 log(L_INIT, "don't know how to get sensitivity "
3433 "for radio type 0x%02X\n", adev->radio_type);
3434 adev->sensitivity = 0;
3436 log(L_INIT, "got sensitivity value %u\n", adev->sensitivity);
3438 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3441 if (adev->get_mask & GETSET_ANTENNA) {
3442 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3444 memset(antenna, 0, sizeof(antenna));
3445 acx_s_interrogate(adev, antenna,
3446 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3447 adev->antenna = antenna[4];
3448 log(L_INIT, "got antenna value 0x%02X\n", adev->antenna);
3449 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3452 if (adev->get_mask & GETSET_ED_THRESH) {
3453 if (IS_ACX100(adev)) {
3454 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3456 memset(ed_threshold, 0, sizeof(ed_threshold));
3457 acx_s_interrogate(adev, ed_threshold,
3458 ACX100_IE_DOT11_ED_THRESHOLD);
3459 adev->ed_threshold = ed_threshold[4];
3460 } else {
3461 log(L_INIT, "acx111 doesn't support ED\n");
3462 adev->ed_threshold = 0;
3464 log(L_INIT, "got Energy Detect (ED) threshold %u\n",
3465 adev->ed_threshold);
3466 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3469 if (adev->get_mask & GETSET_CCA) {
3470 if (IS_ACX100(adev)) {
3471 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3473 memset(cca, 0, sizeof(adev->cca));
3474 acx_s_interrogate(adev, cca,
3475 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3476 adev->cca = cca[4];
3477 } else {
3478 log(L_INIT, "acx111 doesn't support CCA\n");
3479 adev->cca = 0;
3481 log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n",
3482 adev->cca);
3483 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3486 if (adev->get_mask & GETSET_REG_DOMAIN) {
3487 acx_ie_generic_t dom;
3489 acx_s_interrogate(adev, &dom,
3490 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3491 adev->reg_dom_id = dom.m.bytes[0];
3492 acx_s_set_sane_reg_domain(adev, 0);
3493 log(L_INIT, "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3494 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3497 if (adev->set_mask & GETSET_STATION_ID) {
3498 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3499 u8 *paddr;
3501 paddr = &stationID[4];
3502 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3503 for (i = 0; i < ETH_ALEN; i++) {
3504 /* copy the MAC address we obtained when we noticed
3505 * that the ethernet iface's MAC changed
3506 * to the card (reversed in
3507 * the card!) */
3508 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3510 acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3511 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3514 if (adev->set_mask & SET_STA_LIST) {
3515 acx_lock(adev, flags);
3516 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3517 acx_unlock(adev, flags);
3519 if (adev->set_mask & SET_RATE_FALLBACK) {
3520 u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
3522 /* configure to not do fallbacks when not in auto rate mode */
3523 rate[4] =
3524 (adev->
3525 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3526 log(L_INIT, "updating Tx fallback to %u retries\n", rate[4]);
3527 acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK);
3528 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3530 if (adev->set_mask & GETSET_TXPOWER) {
3531 log(L_INIT, "updating transmit power: %u dBm\n",
3532 adev->tx_level_dbm);
3533 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3534 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3537 if (adev->set_mask & GETSET_SENSITIVITY) {
3538 log(L_INIT, "updating sensitivity value: %u\n",
3539 adev->sensitivity);
3540 switch (adev->radio_type) {
3541 case RADIO_RFMD_11:
3542 case RADIO_MAXIM_0D:
3543 case RADIO_RALINK_15:
3544 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3545 break;
3546 case RADIO_RADIA_16:
3547 case RADIO_UNKNOWN_17:
3548 acx111_s_sens_radio_16_17(adev);
3549 break;
3550 default:
3551 log(L_INIT, "don't know how to modify sensitivity "
3552 "for radio type 0x%02X\n", adev->radio_type);
3554 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3557 if (adev->set_mask & GETSET_ANTENNA) {
3558 /* antenna */
3559 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3561 memset(antenna, 0, sizeof(antenna));
3562 antenna[4] = adev->antenna;
3563 log(L_INIT, "updating antenna value: 0x%02X\n", adev->antenna);
3564 acx_s_configure(adev, &antenna,
3565 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3566 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3569 if (adev->set_mask & GETSET_ED_THRESH) {
3570 /* ed_threshold */
3571 log(L_INIT, "updating Energy Detect (ED) threshold: %u\n",
3572 adev->ed_threshold);
3573 if (IS_ACX100(adev)) {
3574 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3576 memset(ed_threshold, 0, sizeof(ed_threshold));
3577 ed_threshold[4] = adev->ed_threshold;
3578 acx_s_configure(adev, &ed_threshold,
3579 ACX100_IE_DOT11_ED_THRESHOLD);
3580 } else
3581 log(L_INIT, "acx111 doesn't support ED!\n");
3582 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3585 if (adev->set_mask & GETSET_CCA) {
3586 /* CCA value */
3587 log(L_INIT, "updating Channel Clear Assessment "
3588 "(CCA) value: 0x%02X\n", adev->cca);
3589 if (IS_ACX100(adev)) {
3590 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3592 memset(cca, 0, sizeof(cca));
3593 cca[4] = adev->cca;
3594 acx_s_configure(adev, &cca,
3595 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3596 } else
3597 log(L_INIT, "acx111 doesn't support CCA!\n");
3598 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3601 if (adev->set_mask & GETSET_LED_POWER) {
3602 /* Enable Tx */
3603 log(L_INIT, "updating power LED status: %u\n", adev->led_power);
3605 acx_lock(adev, flags);
3606 if (IS_PCI(adev))
3607 acxpci_l_power_led(adev, adev->led_power);
3608 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3609 acx_unlock(adev, flags);
3612 if (adev->set_mask & GETSET_POWER_80211) {
3613 #if POWER_SAVE_80211
3614 acx_s_update_80211_powersave_mode(adev);
3615 #endif
3616 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3619 if (adev->set_mask & GETSET_CHANNEL) {
3620 /* channel */
3621 log(L_INIT, "updating channel to: %u\n", adev->channel);
3622 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3625 if (adev->set_mask & GETSET_TX) {
3626 /* set Tx */
3627 log(L_INIT, "updating: %s Tx\n",
3628 adev->tx_disabled ? "disable" : "enable");
3629 if (adev->tx_disabled)
3630 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3631 else {
3632 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3633 &adev->channel, 1);
3634 FIXME();
3635 /* This needs to be keyed on WEP? */
3636 // acx111_s_feature_on(adev, 0,
3637 // FEATURE2_NO_TXCRYPT |
3638 // FEATURE2_SNIFFER);
3640 CLEAR_BIT(adev->set_mask, GETSET_TX);
3643 if (adev->set_mask & GETSET_RX) {
3644 /* Enable Rx */
3645 log(L_INIT, "updating: enable Rx on channel: %u\n",
3646 adev->channel);
3647 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3648 CLEAR_BIT(adev->set_mask, GETSET_RX);
3651 if (adev->set_mask & GETSET_RETRY) {
3652 u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
3653 u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
3655 log(L_INIT,
3656 "updating short retry limit: %u, long retry limit: %u\n",
3657 adev->short_retry, adev->long_retry);
3658 short_retry[0x4] = adev->short_retry;
3659 long_retry[0x4] = adev->long_retry;
3660 acx_s_configure(adev, &short_retry,
3661 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
3662 acx_s_configure(adev, &long_retry,
3663 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
3664 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3667 if (adev->set_mask & SET_MSDU_LIFETIME) {
3668 u8 xmt_msdu_lifetime[4 +
3669 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3671 log(L_INIT, "updating tx MSDU lifetime: %u\n",
3672 adev->msdu_lifetime);
3673 *(u32 *) & xmt_msdu_lifetime[4] =
3674 cpu_to_le32((u32) adev->msdu_lifetime);
3675 acx_s_configure(adev, &xmt_msdu_lifetime,
3676 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
3677 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3680 if (adev->set_mask & GETSET_REG_DOMAIN) {
3681 log(L_INIT, "updating regulatory domain: 0x%02X\n",
3682 adev->reg_dom_id);
3683 acx_s_set_sane_reg_domain(adev, 1);
3684 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3686 if (adev->set_mask & GETSET_MODE ) {
3687 acx111_s_feature_on(adev, 0,
3688 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3689 switch (adev->mode) {
3690 case ACX_MODE_3_AP:
3691 adev->aid = 0;
3692 //acx111_s_feature_off(adev, 0,
3693 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3694 MAC_COPY(adev->bssid,adev->dev_addr);
3695 acx_s_cmd_join_bssid(adev,adev->dev_addr);
3696 break;
3697 case ACX_MODE_MONITOR:
3698 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3699 break;
3700 case ACX_MODE_0_ADHOC:
3701 case ACX_MODE_2_STA:
3702 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3703 break;
3704 default:
3705 break;
3707 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3709 if (adev->set_mask & SET_TEMPLATES) {
3710 switch (adev->mode)
3712 case ACX_MODE_3_AP:
3713 acx_s_set_tim_template(adev);
3714 break;
3715 default:
3716 break;
3718 if (adev->beacon_cache)
3720 acx_s_set_beacon_template(adev, adev->beacon_cache);
3721 dev_kfree_skb(adev->beacon_cache);
3722 adev->beacon_cache = NULL;
3724 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3727 if (adev->set_mask & SET_RXCONFIG) {
3728 acx_s_initialize_rx_config(adev);
3729 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3732 if (adev->set_mask & GETSET_RESCAN) {
3733 /* switch (adev->mode) {
3734 case ACX_MODE_0_ADHOC:
3735 case ACX_MODE_2_STA:
3736 start_scan = 1;
3737 break;
3739 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3742 if (adev->set_mask & GETSET_WEP) {
3743 /* encode */
3745 ie_dot11WEPDefaultKeyID_t dkey;
3746 #ifdef DEBUG_WEP
3747 struct {
3748 u16 type;
3749 u16 len;
3750 u8 val;
3751 } ACX_PACKED keyindic;
3752 #endif
3753 log(L_INIT, "updating WEP key settings\n");
3755 acx_s_set_wepkey(adev);
3756 if (adev->wep_enabled) {
3757 dkey.KeyID = adev->wep_current_index;
3758 log(L_INIT, "setting WEP key %u as default\n",
3759 dkey.KeyID);
3760 acx_s_configure(adev, &dkey,
3761 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
3762 #ifdef DEBUG_WEP
3763 keyindic.val = 3;
3764 acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
3765 #endif
3768 // start_scan = 1;
3769 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3772 if (adev->set_mask & SET_WEP_OPTIONS) {
3773 acx100_ie_wep_options_t options;
3775 if (IS_ACX111(adev)) {
3776 log(L_DEBUG,
3777 "setting WEP Options for acx111 is not supported\n");
3778 } else {
3779 log(L_INIT, "setting WEP Options\n");
3781 /* let's choose maximum setting: 4 default keys,
3782 * plus 10 other keys: */
3783 options.NumKeys =
3784 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3785 /* don't decrypt default key only,
3786 * don't override decryption: */
3787 options.WEPOption = 0;
3788 if (adev->mode == ACX_MODE_3_AP) {
3789 /* don't decrypt default key only,
3790 * override decryption mechanism: */
3791 options.WEPOption = 2;
3794 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3796 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3800 /* debug, rate, and nick don't need any handling */
3801 /* what about sniffing mode?? */
3803 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3804 adev->get_mask, adev->set_mask);
3806 /* end: */
3807 FN_EXIT0;
3810 #if 0
3811 /***********************************************************************
3812 ** acx_e_after_interrupt_task
3814 static int acx_s_recalib_radio(acx_device_t * adev)
3816 if (IS_ACX111(adev)) {
3817 acx111_cmd_radiocalib_t cal;
3819 /* automatic recalibration, choose all methods: */
3820 cal.methods = cpu_to_le32(0x8000000f);
3821 /* automatic recalibration every 60 seconds (value in TUs)
3822 * I wonder what the firmware default here is? */
3823 cal.interval = cpu_to_le32(58594);
3824 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3825 &cal, sizeof(cal),
3826 CMD_TIMEOUT_MS(100));
3827 } else {
3828 /* On ACX100, we need to recalibrate the radio
3829 * by issuing a GETSET_TX|GETSET_RX */
3830 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3831 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3832 (OK ==
3833 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3834 &adev->channel, 1))
3835 && (OK ==
3836 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3837 &adev->channel, 1)))
3838 return OK;
3839 return NOT_OK;
3842 #endif // if 0
3843 #if 0
3844 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3846 int res;
3848 /* this helps with ACX100 at least;
3849 * hopefully ACX111 also does a
3850 * recalibration here */
3852 /* clear flag beforehand, since we want to make sure
3853 * it's cleared; then only set it again on specific circumstances */
3854 CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3856 /* better wait a bit between recalibrations to
3857 * prevent overheating due to torturing the card
3858 * into working too long despite high temperature
3859 * (just a safety measure) */
3860 if (adev->recalib_time_last_success
3861 && time_before(jiffies, adev->recalib_time_last_success
3862 + RECALIB_PAUSE * 60 * HZ)) {
3863 if (adev->recalib_msg_ratelimit <= 4) {
3864 printk("%s: less than " STRING(RECALIB_PAUSE)
3865 " minutes since last radio recalibration, "
3866 "not recalibrating (maybe card is too hot?)\n",
3867 wiphy_name(adev->ieee->wiphy));
3868 adev->recalib_msg_ratelimit++;
3869 if (adev->recalib_msg_ratelimit == 5)
3870 printk("disabling above message until next recalib\n");
3872 return;
3875 adev->recalib_msg_ratelimit = 0;
3877 /* note that commands sometimes fail (card busy),
3878 * so only clear flag if we were fully successful */
3879 res = acx_s_recalib_radio(adev);
3880 if (res == OK) {
3881 printk("%s: successfully recalibrated radio\n",
3882 wiphy_name(adev->ieee->wiphy));
3883 adev->recalib_time_last_success = jiffies;
3884 adev->recalib_failure_count = 0;
3885 } else {
3886 /* failed: resubmit, but only limited
3887 * amount of times within some time range
3888 * to prevent endless loop */
3890 adev->recalib_time_last_success = 0; /* we failed */
3892 /* if some time passed between last
3893 * attempts, then reset failure retry counter
3894 * to be able to do next recalib attempt */
3895 if (time_after
3896 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3897 adev->recalib_failure_count = 0;
3899 if (adev->recalib_failure_count < 5) {
3900 /* increment inside only, for speedup of outside path */
3901 adev->recalib_failure_count++;
3902 adev->recalib_time_last_attempt = jiffies;
3903 acx_schedule_task(adev,
3904 ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3908 #endif // if 0
3910 void acx_e_after_interrupt_task(struct work_struct *work)
3912 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
3913 unsigned int flags;
3914 FN_ENTER;
3915 acx_lock(adev, flags);
3916 if (!adev->after_interrupt_jobs || !adev->initialized)
3917 goto end; /* no jobs to do */
3919 /* we see lotsa tx errors */
3920 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) {
3921 // acx_s_after_interrupt_recalib(adev);
3924 /* a poor interrupt code wanted to do update_card_settings() */
3925 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) {
3926 if (ACX_STATE_IFACE_UP & adev->dev_state_mask)
3927 acx_s_update_card_settings(adev);
3928 CLEAR_BIT(adev->after_interrupt_jobs,
3929 ACX_AFTER_IRQ_UPDATE_CARD_CFG);
3931 /* 1) we detected that no Scan_Complete IRQ came from fw, or
3932 ** 2) we found too many STAs */
3933 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) {
3934 log(L_IRQ, "sending a stop scan cmd...\n");
3935 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
3936 /* HACK: set the IRQ bit, since we won't get a
3937 * scan complete IRQ any more on ACX111 (works on ACX100!),
3938 * since _we_, not a fw, have stopped the scan */
3939 SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
3940 CLEAR_BIT(adev->after_interrupt_jobs,
3941 ACX_AFTER_IRQ_CMD_STOP_SCAN);
3944 /* either fw sent Scan_Complete or we detected that
3945 ** no Scan_Complete IRQ came from fw. Finish scanning,
3946 ** pick join partner if any */
3947 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) {
3948 /* + scan kills current join status - restore it
3949 ** (do we need it for STA?) */
3950 /* + does it happen only with active scans?
3951 ** active and passive scans? ALL scans including
3952 ** background one? */
3953 /* + was not verified that everything is restored
3954 ** (but at least we start to emit beacons again) */
3955 CLEAR_BIT(adev->after_interrupt_jobs,
3956 ACX_AFTER_IRQ_COMPLETE_SCAN);
3959 /* STA auth or assoc timed out, start over again */
3961 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) {
3962 log(L_IRQ, "sending a start_scan cmd...\n");
3963 CLEAR_BIT(adev->after_interrupt_jobs,
3964 ACX_AFTER_IRQ_RESTART_SCAN);
3967 /* whee, we got positive assoc response! 8) */
3968 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) {
3969 CLEAR_BIT(adev->after_interrupt_jobs,
3970 ACX_AFTER_IRQ_CMD_ASSOCIATE);
3972 end:
3973 if(adev->after_interrupt_jobs)
3975 printk("Jobs still to be run: %x\n",adev->after_interrupt_jobs);
3976 adev->after_interrupt_jobs = 0;
3978 acx_unlock(adev, flags);
3979 // acx_sem_unlock(adev);
3980 FN_EXIT0;
3984 /***********************************************************************
3985 ** acx_schedule_task
3987 ** Schedule the call of the after_interrupt method after leaving
3988 ** the interrupt context.
3990 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
3992 if (!adev->after_interrupt_jobs)
3994 SET_BIT(adev->after_interrupt_jobs, set_flag);
3995 schedule_work(&adev->after_interrupt_task);
4000 /***********************************************************************
4002 void acx_init_task_scheduler(acx_device_t * adev)
4004 /* configure task scheduler */
4005 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4009 /***********************************************************************
4010 ** acx_s_start
4012 void acx_s_start(acx_device_t * adev)
4014 FN_ENTER;
4017 * Ok, now we do everything that can possibly be done with ioctl
4018 * calls to make sure that when it was called before the card
4019 * was up we get the changes asked for
4022 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4023 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4024 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4025 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4027 log(L_INIT, "updating initial settings on iface activation\n");
4028 acx_s_update_card_settings(adev);
4030 FN_EXIT0;
4034 /***********************************************************************
4035 ** acx_update_capabilities
4036 *//*
4037 void acx_update_capabilities(acx_device_t * adev)
4039 u16 cap = 0;
4041 switch (adev->mode) {
4042 case ACX_MODE_3_AP:
4043 SET_BIT(cap, WF_MGMT_CAP_ESS);
4044 break;
4045 case ACX_MODE_0_ADHOC:
4046 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4047 break;
4048 */ /* other types of stations do not emit beacons */
4049 /* }
4051 if (adev->wep_restricted) {
4052 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4054 if (adev->cfgopt_dot11ShortPreambleOption) {
4055 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4057 if (adev->cfgopt_dot11PBCCOption) {
4058 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4060 if (adev->cfgopt_dot11ChannelAgility) {
4061 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4063 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4064 adev->capabilities, cap);
4065 adev->capabilities = cap;
4069 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4072 static void acx_select_opmode(acx_device_t * adev)
4074 int changed = 0;
4076 FN_ENTER;
4078 if (adev->interface.operating) {
4079 switch (adev->interface.type) {
4080 case IEEE80211_IF_TYPE_AP:
4081 if (adev->mode != ACX_MODE_3_AP)
4083 adev->mode = ACX_MODE_3_AP;
4084 changed = 1;
4086 break;
4087 case IEEE80211_IF_TYPE_IBSS:
4088 if (adev->mode != ACX_MODE_0_ADHOC)
4090 adev->mode = ACX_MODE_0_ADHOC;
4091 changed = 1;
4093 break;
4094 case IEEE80211_IF_TYPE_STA:
4095 if (adev->mode != ACX_MODE_2_STA)
4097 adev->mode = ACX_MODE_2_STA;
4098 changed = 1;
4100 break;
4101 case IEEE80211_IF_TYPE_WDS:
4102 default:
4103 if (adev->mode != ACX_MODE_OFF)
4105 adev->mode = ACX_MODE_OFF;
4106 changed = 1;
4108 break;
4110 } else {
4111 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4113 if (adev->mode != ACX_MODE_MONITOR)
4115 adev->mode = ACX_MODE_MONITOR;
4116 changed = 1;
4119 else
4121 if (adev->mode != ACX_MODE_OFF)
4123 adev->mode = ACX_MODE_OFF;
4124 changed = 1;
4128 if (changed)
4130 SET_BIT(adev->set_mask, GETSET_MODE);
4131 acx_s_update_card_settings(adev);
4132 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4137 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4141 int acx_add_interface(struct ieee80211_hw *ieee,
4142 struct ieee80211_if_init_conf *conf)
4144 acx_device_t *adev = ieee2adev(ieee);
4145 unsigned long flags;
4146 int err = -EOPNOTSUPP;
4148 FN_ENTER;
4149 acx_lock(adev, flags);
4151 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4152 adev->interface.monitor++;
4153 } else {
4154 if (adev->interface.operating)
4155 goto out_unlock;
4156 adev->interface.operating = 1;
4157 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4158 adev->interface.if_id = conf->if_id;
4159 #endif
4160 adev->interface.mac_addr = conf->mac_addr;
4161 adev->interface.type = conf->type;
4163 // adev->mode = conf->type;
4164 if (adev->initialized)
4165 acx_select_opmode(adev);
4166 err = 0;
4168 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4169 printk(KERN_INFO "Virtual interface added "
4170 "(type: 0x%08X, ID: %d, MAC: "
4171 MAC_FMT ")\n",
4172 conf->type,
4173 conf->if_id,
4174 MAC_ARG(conf->mac_addr));
4175 #else
4176 printk(KERN_INFO "Virtual interface added "
4177 "(type: 0x%08X)\n",
4178 conf->type);
4179 #endif
4181 out_unlock:
4182 acx_unlock(adev, flags);
4184 FN_EXIT0;
4185 return err;
4188 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4192 void acx_remove_interface(struct ieee80211_hw *hw,
4193 struct ieee80211_if_init_conf *conf)
4195 acx_device_t *adev = ieee2adev(hw);
4196 unsigned long flags;
4197 FN_ENTER;
4199 acx_lock(adev, flags);
4200 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4201 adev->interface.monitor--;
4202 // assert(bcm->interface.monitor >= 0);
4203 } else
4204 adev->interface.operating = 0;
4205 printk("Removing interface: %d %d\n", adev->interface.operating, conf->type);
4206 if (adev->initialized)
4207 acx_select_opmode(adev);
4208 flush_scheduled_work();
4209 acx_unlock(adev, flags);
4211 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4212 printk(KERN_INFO "Virtual interface removed "
4213 "(type: 0x%08X, ID: %d, MAC: "
4214 MAC_FMT ")\n",
4215 conf->type, conf->if_id, MAC_ARG(conf->mac_addr));
4216 #else
4217 printk(KERN_INFO "Virtual interface removed "
4218 "(type: 0x%08X)\n",
4219 conf->type);
4220 #endif
4221 FN_EXIT0;
4224 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4228 int acx_net_reset(struct ieee80211_hw *ieee)
4230 acx_device_t *adev = ieee2adev(ieee);
4231 FN_ENTER;
4232 if (IS_PCI(adev))
4233 acxpci_s_reset_dev(adev);
4234 else
4235 TODO();
4237 FN_EXIT0;
4238 return 0;
4242 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4245 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4247 int result;
4249 FN_ENTER;
4251 acx_sem_lock(adev);
4252 adev->rx_status.channel = channel;
4253 adev->rx_status.freq = freq;
4255 adev->channel = channel;
4256 /* hmm, the following code part is strange, but this is how
4257 * it was being done before... */
4258 log(L_IOCTL, "Changing to channel %d\n", channel);
4259 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4260 result = -EINPROGRESS; /* need to call commit handler */
4262 acx_sem_unlock(adev);
4263 FN_EXIT1(result);
4264 return result;
4268 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4271 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4273 acx_device_t *adev = ieee2adev(hw);
4274 unsigned long flags;
4275 #if 0
4276 int change = 0;
4277 #endif
4278 FN_ENTER;
4280 acx_lock(adev, flags);
4281 //FIXME();
4282 if (!adev->initialized) {
4283 acx_unlock(adev,flags);
4284 return 0;
4286 if (conf->beacon_int != adev->beacon_interval)
4287 adev->beacon_interval = conf->beacon_int;
4288 if (conf->channel != adev->channel) {
4289 acx_selectchannel(adev, conf->channel,conf->freq);
4290 /* acx_schedule_task(adev,
4291 ACX_AFTER_IRQ_UPDATE_CARD_CFG
4292 */ /*+ ACX_AFTER_IRQ_RESTART_SCAN */ /*);*/
4295 if (conf->short_slot_time != adev->short_slot) {
4296 // assert(phy->type == BCM43xx_PHYTYPE_G);
4297 if (conf->short_slot_time)
4298 acx_short_slot_timing_enable(adev);
4299 else
4300 acx_short_slot_timing_disable(adev);
4301 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4304 adev->tx_disabled = !conf->radio_enabled;
4305 if (conf->power_level != 0 && adev->tx_level_dbm > 15){
4306 adev->tx_level_dbm = conf->power_level;
4307 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4308 //acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4311 //FIXME: This does not seem to wake up:
4312 #if 0
4313 if (conf->power_level == 0) {
4314 if (radio->enabled)
4315 bcm43xx_radio_turn_off(bcm);
4316 } else {
4317 if (!radio->enabled)
4318 bcm43xx_radio_turn_on(bcm);
4320 #endif
4322 //TODO: phymode
4323 //TODO: antennas
4324 if (adev->set_mask > 0)
4325 acx_s_update_card_settings(adev);
4326 acx_unlock(adev, flags);
4328 FN_EXIT0;
4329 return 0;
4333 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4337 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4338 int acx_config_interface(struct ieee80211_hw* ieee, int if_id,
4339 struct ieee80211_if_conf *conf)
4340 #else
4341 void acx_config_interface(struct ieee80211_hw* ieee, int if_id,
4342 struct ieee80211_if_conf *conf)
4343 #endif
4345 acx_device_t *adev = ieee2adev(ieee);
4346 unsigned long flags;
4347 int err = -ENODEV;
4348 FN_ENTER;
4349 if (!adev->interface.operating)
4350 goto err_out;
4351 acx_lock(adev, flags);
4353 if (adev->initialized)
4354 acx_select_opmode(adev);
4356 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4357 && (adev->interface.if_id == if_id)) {
4358 if (conf->bssid)
4360 adev->interface.bssid = conf->bssid;
4361 MAC_COPY(adev->bssid,conf->bssid);
4364 if ((conf->type == IEEE80211_IF_TYPE_AP)
4365 && (adev->interface.if_id == if_id)) {
4366 if ((conf->ssid_len > 0) && conf->ssid)
4368 adev->essid_len = conf->ssid_len;
4369 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4370 SET_BIT(adev->set_mask, SET_TEMPLATES);
4373 if (conf->beacon != 0)
4375 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4376 adev->beacon_cache = conf->beacon;
4377 SET_BIT(adev->set_mask, SET_TEMPLATES);
4379 if (adev->set_mask != 0)
4380 acx_s_update_card_settings(adev);
4381 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4382 acx_unlock(adev, flags);
4383 err = 0;
4384 err_out:
4385 FN_EXIT1(err);
4386 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4387 return err;
4388 #else
4389 #endif
4393 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4397 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4398 struct ieee80211_tx_queue_stats *stats)
4400 // acx_device_t *adev = ndev2adev(net_dev);
4401 struct ieee80211_tx_queue_stats_data *data;
4402 int err = -ENODEV;
4404 FN_ENTER;
4406 // acx_lock(adev, flags);
4407 data = &(stats->data[0]);
4408 data->len = 0;
4409 data->limit = TX_CNT;
4410 data->count = 0;
4411 // acx_unlock(adev, flags);
4413 FN_EXIT0;
4414 return err;
4417 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4421 int acx_net_conf_tx(struct ieee80211_hw *hw,
4422 int queue, const struct ieee80211_tx_queue_params *params)
4424 FN_ENTER;
4425 // TODO();
4426 FN_EXIT0;
4427 return 0;
4430 static void keymac_write(acx_device_t * adev, u8 index, const u32 * addr)
4432 /* for keys 0-3 there is no associated mac address */
4433 if (index < 4)
4434 return;
4436 index -= 4;
4437 if (1) {
4438 TODO();
4440 bcm43xx_shm_write32(bcm,
4441 BCM43xx_SHM_HWMAC,
4442 index * 2,
4443 cpu_to_be32(*addr));
4444 bcm43xx_shm_write16(bcm,
4445 BCM43xx_SHM_HWMAC,
4446 (index * 2) + 1,
4447 cpu_to_be16(*((u16 *)(addr + 1))));
4449 } else {
4450 if (index < 8) {
4451 TODO(); /* Put them in the macaddress filter */
4452 } else {
4453 TODO();
4454 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4455 Keep in mind to update the count of keymacs in 0x003 */
4461 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4465 int acx_clear_keys(acx_device_t * adev)
4467 static const u32 zero_mac[2] = { 0 };
4468 unsigned int i, j, nr_keys = 54;
4469 u16 offset;
4471 /* FixMe:Check for Number of Keys available */
4473 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4475 for (i = 0; i < nr_keys; i++) {
4476 adev->key[i].enabled = 0;
4477 /* returns for i < 4 immediately */
4478 keymac_write(adev, i, zero_mac);
4480 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4481 0x100 + (i * 2), 0x0000);
4483 for (j = 0; j < 8; j++) {
4484 offset =
4485 adev->security_offset + (j * 4) +
4486 (i * ACX_SEC_KEYSIZE);
4488 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4489 offset, 0x0000);
4493 return 1;
4497 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4501 int acx_key_write(acx_device_t * adev,
4502 u8 index,
4503 u8 algorithm,
4504 const u8 * _key, int key_len, const u8 * mac_addr)
4506 // struct iw_point *dwrq = &wrqu->encoding;
4507 // acx_device_t *adev = ndev2adev(ndev);
4508 int result;
4510 FN_ENTER;
4512 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4513 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4515 acx_sem_lock(adev);
4517 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4518 if (key_len > 0) {
4519 /* if index is 0 or invalid, use default key */
4520 if (index > 3)
4521 index = (int)adev->wep_current_index;
4522 if ((algorithm == ACX_SEC_ALGO_WEP)
4523 || (algorithm == ACX_SEC_ALGO_WEP104)) {
4524 if (key_len > 29)
4525 key_len = 29; /* restrict it */
4527 if (key_len > 13) {
4528 /* 29*8 == 232, WEP256 */
4529 adev->wep_keys[index].size = 29;
4530 } else if (key_len > 5) {
4531 /* 13*8 == 104bit, WEP128 */
4532 adev->wep_keys[index].size = 13;
4533 } else if (key_len > 0) {
4534 /* 5*8 == 40bit, WEP64 */
4535 adev->wep_keys[index].size = 5;
4536 } else {
4537 /* disable key */
4538 adev->wep_keys[index].size = 0;
4541 memset(adev->wep_keys[index].key, 0,
4542 sizeof(adev->wep_keys[index].key));
4543 memcpy(adev->wep_keys[index].key, _key, key_len);
4545 } else {
4546 /* set transmit key */
4547 if (index <= 3)
4548 adev->wep_current_index = index;
4549 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4550 /* complain if we were not just setting
4551 * the key mode */
4552 // result = -EINVAL;
4553 // goto end_unlock;
4554 // }
4557 adev->wep_enabled = (algorithm == ALG_WEP);
4559 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4561 if (algorithm & IW_ENCODE_OPEN) {
4562 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4563 adev->wep_restricted = 0;
4565 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4566 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4567 adev->wep_restricted = 1;
4570 // adev->auth_alg = algorithm;
4571 /* set flag to make sure the card WEP settings get updated */
4572 if (adev->wep_enabled) {
4573 SET_BIT(adev->set_mask, GETSET_WEP);
4574 acx_s_update_card_settings(adev);
4575 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4578 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4579 dwrq->length, extra, dwrq->flags);
4580 for (index = 0; index <= 3; index++) {
4581 if (adev->wep_keys[index].size) {
4582 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4583 adev->wep_keys[index].index,
4584 (int) adev->wep_keys[index].size,
4585 adev->wep_keys[index].key);
4589 result = -EINPROGRESS;
4590 acx_sem_unlock(adev);
4592 FN_EXIT1(result);
4593 return result;
4599 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4603 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4604 int acx_net_set_key(struct ieee80211_hw *ieee,
4605 set_key_cmd cmd,
4606 u8 * addr, struct ieee80211_key_conf *key, int aid)
4607 #else
4608 int acx_net_set_key(struct ieee80211_hw *ieee,
4609 enum set_key_cmd cmd, const u8 *local_addr,
4610 const u8 * addr, struct ieee80211_key_conf *key)
4611 #endif
4613 // return 0;
4614 struct acx_device *adev = ieee2adev(ieee);
4615 unsigned long flags;
4616 u8 algorithm;
4617 u8 index;
4618 int err = -EINVAL;
4619 FN_ENTER;
4620 // TODO();
4621 switch (key->alg) {
4622 default:
4623 /* case ALG_NONE:
4624 case ALG_NULL:
4625 algorithm = ACX_SEC_ALGO_NONE;
4626 break;
4627 */ case ALG_WEP:
4628 if (key->keylen == 5)
4629 algorithm = ACX_SEC_ALGO_WEP;
4630 else
4631 algorithm = ACX_SEC_ALGO_WEP104;
4632 break;
4633 case ALG_TKIP:
4634 algorithm = ACX_SEC_ALGO_TKIP;
4635 break;
4636 case ALG_CCMP:
4637 algorithm = ACX_SEC_ALGO_AES;
4638 break;
4641 index = (u8) (key->keyidx);
4642 if (index >= ARRAY_SIZE(adev->key))
4643 goto out;
4644 acx_lock(adev, flags);
4645 switch (cmd) {
4646 case SET_KEY:
4647 err = acx_key_write(adev, index, algorithm,
4648 key->key, key->keylen, addr);
4649 if (err)
4650 goto out_unlock;
4651 key->hw_key_idx = index;
4652 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4653 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4654 adev->default_key_idx = index;*/
4655 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4656 adev->key[index].enabled = 1;
4657 break;
4658 case DISABLE_KEY:
4659 adev->key[index].enabled = 0;
4660 err = 0;
4661 break;
4662 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4663 case REMOVE_ALL_KEYS:
4664 acx_clear_keys(adev);
4665 err = 0;
4666 break;
4667 #else
4668 #endif
4669 /* case ENABLE_COMPRESSION:
4670 case DISABLE_COMPRESSION:
4671 err = 0;
4672 break; */
4674 out_unlock:
4675 acx_unlock(adev, flags);
4676 out:
4677 FN_EXIT0;
4678 return err;
4683 /***********************************************************************
4684 ** Common function to parse ALL configoption struct formats
4685 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4686 ** FIXME: logging should be removed here and added to a /proc file instead
4688 ** Look into bcm43xx
4690 void
4691 acx_s_parse_configoption(acx_device_t * adev,
4692 const acx111_ie_configoption_t * pcfg)
4694 const u8 *pEle;
4695 int i;
4696 int is_acx111 = IS_ACX111(adev);
4698 if (acx_debug & L_DEBUG) {
4699 printk("configoption struct content:\n");
4700 acx_dump_bytes(pcfg, sizeof(*pcfg));
4703 if ((is_acx111 && (adev->eeprom_version == 5))
4704 || (!is_acx111 && (adev->eeprom_version == 4))
4705 || (!is_acx111 && (adev->eeprom_version == 5))) {
4706 /* these versions are known to be supported */
4707 } else {
4708 printk("unknown chip and EEPROM version combination (%s, v%d), "
4709 "don't know how to parse config options yet. "
4710 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4711 adev->eeprom_version);
4712 return;
4715 /* first custom-parse the first part which has chip-specific layout */
4717 pEle = (const u8 *)pcfg;
4719 pEle += 4; /* skip (type,len) header */
4721 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4722 pEle += sizeof(adev->cfgopt_NVSv);
4724 if (is_acx111) {
4725 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4726 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4728 adev->cfgopt_probe_delay = 200; /* good default value? */
4729 pEle += 2; /* FIXME: unknown, value 0x0001 */
4730 } else {
4731 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4732 pEle += sizeof(adev->cfgopt_MAC);
4734 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4735 pEle += sizeof(adev->cfgopt_probe_delay);
4736 if ((adev->cfgopt_probe_delay < 100)
4737 || (adev->cfgopt_probe_delay > 500)) {
4738 printk("strange probe_delay value %d, "
4739 "tweaking to 200\n", adev->cfgopt_probe_delay);
4740 adev->cfgopt_probe_delay = 200;
4744 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4745 pEle += sizeof(adev->cfgopt_eof_memory);
4747 printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n",
4748 adev->cfgopt_NVS_vendor_offs,
4749 adev->cfgopt_probe_delay, adev->cfgopt_eof_memory);
4751 adev->cfgopt_dot11CCAModes = *pEle++;
4752 adev->cfgopt_dot11Diversity = *pEle++;
4753 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4754 adev->cfgopt_dot11PBCCOption = *pEle++;
4755 adev->cfgopt_dot11ChannelAgility = *pEle++;
4756 adev->cfgopt_dot11PhyType = *pEle++;
4757 adev->cfgopt_dot11TempType = *pEle++;
4758 printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4759 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4760 adev->cfgopt_dot11CCAModes,
4761 adev->cfgopt_dot11Diversity,
4762 adev->cfgopt_dot11ShortPreambleOption,
4763 adev->cfgopt_dot11PBCCOption,
4764 adev->cfgopt_dot11ChannelAgility,
4765 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4767 /* then use common parsing for next part which has common layout */
4769 pEle++; /* skip table_count (6) */
4771 adev->cfgopt_antennas.type = pEle[0];
4772 adev->cfgopt_antennas.len = pEle[1];
4773 printk("AntennaID:%02X Len:%02X Data:",
4774 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4775 for (i = 0; i < pEle[1]; i++) {
4776 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4777 printk("%02X ", pEle[i + 2]);
4779 printk("\n");
4781 pEle += pEle[1] + 2;
4782 adev->cfgopt_power_levels.type = pEle[0];
4783 adev->cfgopt_power_levels.len = pEle[1];
4784 printk("PowerLevelID:%02X Len:%02X Data:",
4785 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4786 for (i = 0; i < pEle[1]; i++) {
4787 adev->cfgopt_power_levels.list[i] =
4788 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4789 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4791 printk("\n");
4793 pEle += pEle[1] * 2 + 2;
4794 adev->cfgopt_data_rates.type = pEle[0];
4795 adev->cfgopt_data_rates.len = pEle[1];
4796 printk("DataRatesID:%02X Len:%02X Data:",
4797 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4798 for (i = 0; i < pEle[1]; i++) {
4799 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4800 printk("%02X ", pEle[i + 2]);
4802 printk("\n");
4804 pEle += pEle[1] + 2;
4805 adev->cfgopt_domains.type = pEle[0];
4806 adev->cfgopt_domains.len = pEle[1];
4807 printk("DomainID:%02X Len:%02X Data:",
4808 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4809 for (i = 0; i < pEle[1]; i++) {
4810 adev->cfgopt_domains.list[i] = pEle[i + 2];
4811 printk("%02X ", pEle[i + 2]);
4813 printk("\n");
4815 pEle += pEle[1] + 2;
4816 adev->cfgopt_product_id.type = pEle[0];
4817 adev->cfgopt_product_id.len = pEle[1];
4818 for (i = 0; i < pEle[1]; i++) {
4819 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4821 printk("ProductID:%02X Len:%02X Data:%.*s\n",
4822 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4823 adev->cfgopt_product_id.len,
4824 (char *)adev->cfgopt_product_id.list);
4826 pEle += pEle[1] + 2;
4827 adev->cfgopt_manufacturer.type = pEle[0];
4828 adev->cfgopt_manufacturer.len = pEle[1];
4829 for (i = 0; i < pEle[1]; i++) {
4830 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4832 printk("ManufacturerID:%02X Len:%02X Data:%.*s\n",
4833 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4834 adev->cfgopt_manufacturer.len,
4835 (char *)adev->cfgopt_manufacturer.list);
4837 printk("EEPROM part:\n");
4838 for (i=0; i<58; i++) {
4839 printk("%02X =======> 0x%02X\n",
4840 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4846 /***********************************************************************
4847 ** Linux Kernel Specific
4849 static int __init acx_e_init_module(void)
4851 int r1, r2;
4853 acx_struct_size_check();
4855 printk("acx: this driver is still EXPERIMENTAL\n"
4856 "acx: reading README file and/or Craig's HOWTO is "
4857 "recommended, visit http://acx100.sourceforge.net/wiki in case "
4858 "of further questions/discussion\n");
4860 #if defined(CONFIG_ACX_MAC80211_PCI)
4861 r1 = acxpci_e_init_module();
4862 #else
4863 r1 = -EINVAL;
4864 #endif
4865 #if defined(CONFIG_ACX_MAC80211_USB)
4866 r2 = acxusb_e_init_module();
4867 #else
4868 r2 = -EINVAL;
4869 #endif
4870 if (r2 && r1) /* both failed! */
4871 return r2 ? r2 : r1;
4872 /* return success if at least one succeeded */
4873 return 0;
4876 static void __exit acx_e_cleanup_module(void)
4878 #if defined(CONFIG_ACX_MAC80211_PCI)
4879 acxpci_e_cleanup_module();
4880 #endif
4881 #if defined(CONFIG_ACX_MAC80211_USB)
4882 acxusb_e_cleanup_module();
4883 #endif
4886 module_init(acx_e_init_module)
4887 module_exit(acx_e_cleanup_module)