fix 2.6.24 compilation (I used the git version of 2.6.24 before which differs in...
[acx-mac80211.git] / common.c
blob545878d834b526d63f8c0af88e5c6b66cc5dd724
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)");
58 #ifdef MODULE_VERSION
59 MODULE_VERSION(ACX_RELEASE);
60 #endif
62 /***********************************************************************
64 /* Probably a number of acx's intermediate buffers for USB transfers,
65 ** not to be confused with number of descriptors in tx/rx rings
66 ** (which are not directly accessible to host in USB devices) */
67 #define USB_RX_CNT 10
68 #define USB_TX_CNT 10
71 /***********************************************************************
74 /* minutes to wait until next radio recalibration: */
75 #define RECALIB_PAUSE 5
77 /* Please keep acx_reg_domain_ids_len in sync... */
78 const u8 acx_reg_domain_ids[acx_reg_domain_ids_len] =
79 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 };
80 static const u16 reg_domain_channel_masks[acx_reg_domain_ids_len] =
81 { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc };
82 const char *const
83 acx_reg_domain_strings[] = {
84 /* 0 */ " 1-11 FCC (USA)",
85 /* 1 */ " 1-11 DOC/IC (Canada)",
86 /* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */
87 /* 2 */ " 1-13 ETSI (Europe)",
88 /* 3 */ "10-11 Spain",
89 /* 4 */ "10-13 France",
90 /* 5 */ " 14 MKK (Japan)",
91 /* 6 */ " 1-14 MKK1",
92 /* 7 */ " 3-9 Israel (not all firmware versions)",
93 NULL /* needs to remain as last entry */
98 /***********************************************************************
99 ** Debugging support
101 #ifdef PARANOID_LOCKING
102 static unsigned max_lock_time;
103 static unsigned max_sem_time;
105 /* Obvious or linux kernel specific derived code follows: */
107 void acx_lock_unhold()
109 max_lock_time = 0;
112 void acx_sem_unhold()
114 max_sem_time = 0;
117 static inline const char *sanitize_str(const char *s)
119 const char *t = strrchr(s, '/');
120 if (t)
121 return t + 1;
122 return s;
125 void acx_lock_debug(acx_device_t * adev, const char *where)
127 unsigned int count = 100 * 1000 * 1000;
128 where = sanitize_str(where);
129 while (--count) {
130 if (!spin_is_locked(&adev->lock))
131 break;
132 cpu_relax();
134 if (!count) {
135 printk(KERN_EMERG "LOCKUP: already taken at %s!\n",
136 adev->last_lock);
137 BUG();
139 adev->last_lock = where;
140 rdtscl(adev->lock_time);
142 void acx_unlock_debug(acx_device_t * adev, const char *where)
144 #ifdef SMP
145 if (!spin_is_locked(&adev->lock)) {
146 where = sanitize_str(where);
147 printk(KERN_EMERG "STRAY UNLOCK at %s!\n", where);
148 BUG();
150 #endif
151 if (acx_debug & L_LOCK) {
152 unsigned long diff;
153 rdtscl(diff);
154 diff -= adev->lock_time;
155 if (diff > max_lock_time) {
156 where = sanitize_str(where);
157 printk("max lock hold time %ld CPU ticks from %s "
158 "to %s\n", diff, adev->last_lock, where);
159 max_lock_time = diff;
163 #endif /* PARANOID_LOCKING */
166 /***********************************************************************
168 #if ACX_DEBUG > 1
170 static int acx_debug_func_indent;
171 #define DEBUG_TSC 0
172 #define FUNC_INDENT_INCREMENT 2
174 #if DEBUG_TSC
175 #define TIMESTAMP(d) unsigned long d; rdtscl(d)
176 #else
177 #define TIMESTAMP(d) unsigned long d = jiffies
178 #endif
180 static const char spaces[] = " " " "; /* Nx10 spaces */
182 void log_fn_enter(const char *funcname)
184 int indent;
185 TIMESTAMP(d);
187 indent = acx_debug_func_indent;
188 if (indent >= sizeof(spaces))
189 indent = sizeof(spaces) - 1;
191 printk("%08ld %s==> %s\n",
192 d % 100000000, spaces + (sizeof(spaces) - 1) - indent, funcname);
194 acx_debug_func_indent += FUNC_INDENT_INCREMENT;
196 void log_fn_exit(const char *funcname)
198 int indent;
199 TIMESTAMP(d);
201 acx_debug_func_indent -= FUNC_INDENT_INCREMENT;
203 indent = acx_debug_func_indent;
204 if (indent >= sizeof(spaces))
205 indent = sizeof(spaces) - 1;
207 printk("%08ld %s<== %s\n",
208 d % 100000000, spaces + (sizeof(spaces) - 1) - indent, funcname);
210 void log_fn_exit_v(const char *funcname, int v)
212 int indent;
213 TIMESTAMP(d);
215 acx_debug_func_indent -= FUNC_INDENT_INCREMENT;
217 indent = acx_debug_func_indent;
218 if (indent >= sizeof(spaces))
219 indent = sizeof(spaces) - 1;
221 printk("%08ld %s<== %s: %08X\n",
222 d % 100000000,
223 spaces + (sizeof(spaces) - 1) - indent, funcname, v);
225 #endif /* ACX_DEBUG > 1 */
228 /***********************************************************************
229 ** Basically a mdelay/msleep with logging
231 void acx_s_mwait(int ms)
233 FN_ENTER;
234 #ifdef CONFIG_X86
235 mdelay(ms);
236 #else
237 msleep(ms);
238 #endif
239 FN_EXIT0;
243 /***********************************************************************
244 ** Not inlined: it's larger than it seems
246 void acx_print_mac(const char *head, const u8 * mac, const char *tail)
248 printk("%s" MACSTR "%s", head, MAC(mac), tail);
254 /***********************************************************************
255 ** acx_cmd_status_str
257 const char *acx_cmd_status_str(unsigned int state)
259 static const char *const cmd_error_strings[] = {
260 "Idle",
261 "Success",
262 "Unknown Command",
263 "Invalid Information Element",
264 "Channel rejected",
265 "Channel invalid in current regulatory domain",
266 "MAC invalid",
267 "Command rejected (read-only information element)",
268 "Command rejected",
269 "Already asleep",
270 "TX in progress",
271 "Already awake",
272 "Write only",
273 "RX in progress",
274 "Invalid parameter",
275 "Scan in progress",
276 "Failed"
278 return state < ARRAY_SIZE(cmd_error_strings) ?
279 cmd_error_strings[state] : "?";
282 /***********************************************************************
284 #if ACX_DEBUG
285 void acx_dump_bytes(const void *data, int num)
287 const u8 *ptr = (const u8 *)data;
289 FN_ENTER;
291 if (num <= 0) {
292 printk("\n");
293 return;
296 while (num >= 16) {
297 printk("%02X %02X %02X %02X %02X %02X %02X %02X "
298 "%02X %02X %02X %02X %02X %02X %02X %02X\n",
299 ptr[0], ptr[1], ptr[2], ptr[3],
300 ptr[4], ptr[5], ptr[6], ptr[7],
301 ptr[8], ptr[9], ptr[10], ptr[11],
302 ptr[12], ptr[13], ptr[14], ptr[15]);
303 num -= 16;
304 ptr += 16;
306 if (num > 0) {
307 while (--num > 0)
308 printk("%02X ", *ptr++);
309 printk("%02X\n", *ptr);
312 FN_EXIT0;
315 #endif
318 /***********************************************************************
319 ** acx_s_get_firmware_version
321 ** Obvious
323 void acx_s_get_firmware_version(acx_device_t * adev)
325 fw_ver_t fw;
326 u8 hexarr[4] = { 0, 0, 0, 0 };
327 int hexidx = 0, val = 0;
328 const char *num;
329 char c;
331 FN_ENTER;
333 memset(fw.fw_id, 'E', FW_ID_SIZE);
334 acx_s_interrogate(adev, &fw, ACX1xx_IE_FWREV);
335 memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE);
336 adev->firmware_version[FW_ID_SIZE] = '\0';
338 log(L_DEBUG, "fw_ver: fw_id='%s' hw_id=%08X\n",
339 adev->firmware_version, fw.hw_id);
341 if (strncmp(fw.fw_id, "Rev ", 4) != 0) {
342 printk("acx: strange firmware version string "
343 "'%s', please report\n", adev->firmware_version);
344 adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */
345 } else {
346 num = &fw.fw_id[4];
347 while (1) {
348 c = *num++;
349 if ((c == '.') || (c == '\0')) {
350 hexarr[hexidx++] = val;
351 if ((hexidx > 3) || (c == '\0')) /* end? */
352 break;
353 val = 0;
354 continue;
356 if ((c >= '0') && (c <= '9'))
357 c -= '0';
358 else
359 c = c - 'a' + (char)10;
360 val = val * 16 + c;
363 adev->firmware_numver = (u32) ((hexarr[0] << 24) |
364 (hexarr[1] << 16)
365 | (hexarr[2] << 8) | hexarr[3]);
366 log(L_DEBUG, "firmware_numver 0x%08X\n", adev->firmware_numver);
368 if (IS_ACX111(adev)) {
369 if (adev->firmware_numver == 0x00010011) {
370 /* This one does not survive floodpinging */
371 printk("acx: firmware '%s' is known to be buggy, "
372 "please upgrade\n", adev->firmware_version);
376 adev->firmware_id = le32_to_cpu(fw.hw_id);
378 /* we're able to find out more detailed chip names now */
379 switch (adev->firmware_id & 0xffff0000) {
380 case 0x01010000:
381 case 0x01020000:
382 adev->chip_name = "TNETW1100A";
383 break;
384 case 0x01030000:
385 adev->chip_name = "TNETW1100B";
386 break;
387 case 0x03000000:
388 case 0x03010000:
389 adev->chip_name = "TNETW1130";
390 break;
391 case 0x04030000: /* 0x04030101 is TNETW1450 */
392 adev->chip_name = "TNETW1450";
393 break;
394 default:
395 printk("acx: unknown chip ID 0x%08X, "
396 "please report\n", adev->firmware_id);
397 break;
400 FN_EXIT0;
404 /***********************************************************************
405 ** acx_display_hardware_details
407 ** Displays hw/fw version, radio type etc...
409 ** Obvious
411 void acx_display_hardware_details(acx_device_t * adev)
413 const char *radio_str, *form_str;
415 FN_ENTER;
417 switch (adev->radio_type) {
418 case RADIO_MAXIM_0D:
419 radio_str = "Maxim";
420 break;
421 case RADIO_RFMD_11:
422 radio_str = "RFMD";
423 break;
424 case RADIO_RALINK_15:
425 radio_str = "Ralink";
426 break;
427 case RADIO_RADIA_16:
428 radio_str = "Radia";
429 break;
430 case RADIO_UNKNOWN_17:
431 /* TI seems to have a radio which is
432 * additionally 802.11a capable, too */
433 radio_str = "802.11a/b/g radio?! Please report";
434 break;
435 case RADIO_UNKNOWN_19:
436 radio_str = "A radio used by Safecom cards?! Please report";
437 break;
438 case RADIO_UNKNOWN_1B:
439 radio_str = "An unknown radio used by TNETW1450 USB adapters";
440 break;
441 default:
442 radio_str = "UNKNOWN, please report radio type name!";
443 break;
446 switch (adev->form_factor) {
447 case 0x00:
448 form_str = "unspecified";
449 break;
450 case 0x01:
451 form_str = "(mini-)PCI / CardBus";
452 break;
453 case 0x02:
454 form_str = "USB";
455 break;
456 case 0x03:
457 form_str = "Compact Flash";
458 break;
459 default:
460 form_str = "UNKNOWN, please report";
461 break;
464 printk("acx: chipset %s, radio type 0x%02X (%s), "
465 "form factor 0x%02X (%s), EEPROM version 0x%02X, "
466 "uploaded firmware '%s'\n",
467 adev->chip_name, adev->radio_type, radio_str,
468 adev->form_factor, form_str, adev->eeprom_version,
469 adev->firmware_version);
471 FN_EXIT0;
475 /***********************************************************************
476 ** acx_e_get_stats, acx_e_get_wireless_stats
479 acx_e_get_stats(struct ieee80211_hw *hw,
480 struct ieee80211_low_level_stats *stats)
482 acx_device_t *adev = ieee2adev(hw);
483 unsigned long flags;
484 acx_lock(adev, flags);
485 memcpy(stats, &adev->ieee_stats, sizeof(*stats));
486 acx_unlock(adev, flags);
487 return 0;
491 /***********************************************************************
492 ** maps acx111 tx descr rate field to acx100 one
494 const u8 acx_bitpos2rate100[] = {
495 RATE100_1, /* 0 */
496 RATE100_2, /* 1 */
497 RATE100_5, /* 2 */
498 RATE100_2, /* 3, should not happen */
499 RATE100_2, /* 4, should not happen */
500 RATE100_11, /* 5 */
501 RATE100_2, /* 6, should not happen */
502 RATE100_2, /* 7, should not happen */
503 RATE100_22, /* 8 */
504 RATE100_2, /* 9, should not happen */
505 RATE100_2, /* 10, should not happen */
506 RATE100_2, /* 11, should not happen */
507 RATE100_2, /* 12, should not happen */
508 RATE100_2, /* 13, should not happen */
509 RATE100_2, /* 14, should not happen */
510 RATE100_2, /* 15, should not happen */
513 u8 acx_rate111to100(u16 r)
515 return acx_bitpos2rate100[highest_bit(r)];
519 /***********************************************************************
520 ** Calculate level like the feb 2003 windows driver seems to do
522 static u8 acx_signal_to_winlevel(u8 rawlevel)
524 /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
525 u8 winlevel = ((4 + (rawlevel * 5)) / 8);
527 if (winlevel > 100)
528 winlevel = 100;
529 return winlevel;
532 u8 acx_signal_determine_quality(u8 signal, u8 noise)
534 int qual;
536 qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2;
538 if (qual > 100)
539 return 100;
540 if (qual < 0)
541 return 0;
542 return qual;
546 /***********************************************************************
547 ** Interrogate/configure commands
550 /* FIXME: the lengths given here probably aren't always correct.
551 * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4",
552 * unless the firmware actually expects a different length than the struct length */
553 static const u16 acx100_ie_len[] = {
555 ACX100_IE_ACX_TIMER_LEN,
556 sizeof(acx100_ie_powersave_t) - 4, /* is that 6 or 8??? */
557 ACX1xx_IE_QUEUE_CONFIG_LEN,
558 ACX100_IE_BLOCK_SIZE_LEN,
559 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
560 ACX1xx_IE_RATE_FALLBACK_LEN,
561 ACX100_IE_WEP_OPTIONS_LEN,
562 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
564 ACX1xx_IE_ASSOC_ID_LEN,
566 ACX111_IE_CONFIG_OPTIONS_LEN,
567 ACX1xx_IE_FWREV_LEN,
568 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
569 ACX1xx_IE_MEDIUM_USAGE_LEN,
570 ACX1xx_IE_RXCONFIG_LEN,
573 sizeof(fw_stats_t) - 4,
575 ACX1xx_IE_FEATURE_CONFIG_LEN,
576 ACX111_IE_KEY_CHOOSE_LEN,
577 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
578 ACX1FF_IE_WONE_CONFIG_LEN,
580 ACX1FF_IE_TID_CONFIG_LEN,
584 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
585 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
586 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
587 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
589 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
590 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
591 ACX1FF_IE_CCA_THRESHOLD_LEN,
592 ACX1FF_IE_EVENT_MASK_LEN,
593 ACX1FF_IE_DTIM_PERIOD_LEN,
595 ACX1FF_IE_ACI_CONFIG_SET_LEN,
602 ACX1FF_IE_EEPROM_VER_LEN,
605 static const u16 acx100_ie_len_dot11[] = {
607 ACX1xx_IE_DOT11_STATION_ID_LEN,
609 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
610 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
611 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
612 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
613 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
614 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
616 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
617 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
619 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
620 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
621 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
622 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
628 static const u16 acx111_ie_len[] = {
630 ACX100_IE_ACX_TIMER_LEN,
631 sizeof(acx111_ie_powersave_t) - 4,
632 ACX1xx_IE_QUEUE_CONFIG_LEN,
633 ACX100_IE_BLOCK_SIZE_LEN,
634 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
635 ACX1xx_IE_RATE_FALLBACK_LEN,
636 ACX100_IE_WEP_OPTIONS_LEN,
637 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
639 ACX1xx_IE_ASSOC_ID_LEN,
641 ACX111_IE_CONFIG_OPTIONS_LEN,
642 ACX1xx_IE_FWREV_LEN,
643 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
644 ACX1xx_IE_MEDIUM_USAGE_LEN,
645 ACX1xx_IE_RXCONFIG_LEN,
648 sizeof(fw_stats_t) - 4,
650 ACX1xx_IE_FEATURE_CONFIG_LEN,
651 ACX111_IE_KEY_CHOOSE_LEN,
652 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
653 ACX1FF_IE_WONE_CONFIG_LEN,
655 ACX1FF_IE_TID_CONFIG_LEN,
659 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
660 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
661 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
662 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
664 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
665 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
666 ACX1FF_IE_CCA_THRESHOLD_LEN,
667 ACX1FF_IE_EVENT_MASK_LEN,
668 ACX1FF_IE_DTIM_PERIOD_LEN,
670 ACX1FF_IE_ACI_CONFIG_SET_LEN,
677 ACX1FF_IE_EEPROM_VER_LEN,
680 static const u16 acx111_ie_len_dot11[] = {
682 ACX1xx_IE_DOT11_STATION_ID_LEN,
684 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
685 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
686 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
687 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
688 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
689 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
691 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
692 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
694 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
695 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
696 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
697 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
704 #undef FUNC
705 #define FUNC "configure"
706 #if !ACX_DEBUG
707 int acx_s_configure(acx_device_t * adev, void *pdr, int type)
709 #else
711 acx_s_configure_debug(acx_device_t * adev, void *pdr, int type,
712 const char *typestr)
714 #endif
715 u16 len;
716 int res;
718 if (type < 0x1000)
719 len = adev->ie_len[type];
720 else
721 len = adev->ie_len_dot11[type - 0x1000];
723 log(L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
724 if (unlikely(!len)) {
725 log(L_DEBUG, "zero-length type %s?!\n", typestr);
728 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
729 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
730 res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4);
731 if (unlikely(OK != res)) {
732 #if ACX_DEBUG
733 printk("%s: " FUNC "(type:%s) FAILED\n", wiphy_name(adev->ieee->wiphy),
734 typestr);
735 #else
736 printk("%s: " FUNC "(type:0x%X) FAILED\n", wiphy_name(adev->ieee->wiphy),
737 type);
738 #endif
739 /* dump_stack() is already done in issue_cmd() */
741 return res;
744 #undef FUNC
745 #define FUNC "interrogate"
746 #if !ACX_DEBUG
747 int acx_s_interrogate(acx_device_t * adev, void *pdr, int type)
749 #else
751 acx_s_interrogate_debug(acx_device_t * adev, void *pdr, int type,
752 const char *typestr)
754 #endif
755 u16 len;
756 int res;
758 FN_ENTER;
760 /* FIXME: no check whether this exceeds the array yet.
761 * We should probably remember the number of entries... */
762 if (type < 0x1000)
763 len = adev->ie_len[type];
764 else
765 len = adev->ie_len_dot11[type - 0x1000];
767 log(L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
769 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
770 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
771 res = acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, pdr, len + 4);
772 if (unlikely(OK != res)) {
773 #if ACX_DEBUG
774 printk("%s: " FUNC "(type:%s) FAILED\n", wiphy_name(adev->ieee->wiphy),
775 typestr);
776 #else
777 printk("%s: " FUNC "(type:0x%X) FAILED\n", wiphy_name(adev->ieee->wiphy),
778 type);
779 #endif
780 /* dump_stack() is already done in issue_cmd() */
783 FN_EXIT1(res);
784 return res;
787 #if CMD_DISCOVERY
788 void great_inquisitor(acx_device_t * adev)
790 static struct {
791 u16 type;
792 u16 len;
793 /* 0x200 was too large here: */
794 u8 data[0x100 - 4];
795 } ACX_PACKED ie;
796 u16 type;
798 FN_ENTER;
800 /* 0..0x20, 0x1000..0x1020 */
801 for (type = 0; type <= 0x1020; type++) {
802 if (type == 0x21)
803 type = 0x1000;
804 ie.type = cpu_to_le16(type);
805 ie.len = cpu_to_le16(sizeof(ie) - 4);
806 acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie));
808 FN_EXIT0;
810 #endif
813 #ifdef CONFIG_PROC_FS
814 /***********************************************************************
815 ** /proc files
817 /***********************************************************************
818 ** acx_l_proc_output
819 ** Generate content for our /proc entry
821 ** Arguments:
822 ** buf is a pointer to write output to
823 ** adev is the usual pointer to our private struct acx_device
824 ** Returns:
825 ** number of bytes actually written to buf
826 ** Side effects:
827 ** none
829 static int acx_l_proc_output(char *buf, acx_device_t * adev)
831 char *p = buf;
833 FN_ENTER;
835 p += sprintf(p,
836 "acx driver version:\t\t" ACX_RELEASE "\n"
837 "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n"
838 "chip name:\t\t\t%s (0x%08X)\n"
839 "radio type:\t\t\t0x%02X\n"
840 "form factor:\t\t\t0x%02X\n"
841 "EEPROM version:\t\t\t0x%02X\n"
842 "firmware version:\t\t%s (0x%08X)\n",
843 adev->chip_name, adev->firmware_id,
844 adev->radio_type,
845 adev->form_factor,
846 adev->eeprom_version,
847 adev->firmware_version, adev->firmware_numver);
849 FN_EXIT1(p - buf);
850 return p - buf;
854 /***********************************************************************
856 static int acx_s_proc_diag_output(char *buf, acx_device_t * adev)
858 char *p = buf;
859 unsigned long flags;
860 unsigned int len = 0, partlen;
861 u32 temp1, temp2;
862 u8 *st, *st_end;
863 #ifdef __BIG_ENDIAN
864 u8 *st2;
865 #endif
866 fw_stats_t *fw_stats;
867 char *part_str = NULL;
868 fw_stats_tx_t *tx = NULL;
869 fw_stats_rx_t *rx = NULL;
870 fw_stats_dma_t *dma = NULL;
871 fw_stats_irq_t *irq = NULL;
872 fw_stats_wep_t *wep = NULL;
873 fw_stats_pwr_t *pwr = NULL;
874 fw_stats_mic_t *mic = NULL;
875 fw_stats_aes_t *aes = NULL;
876 fw_stats_event_t *evt = NULL;
878 FN_ENTER;
880 acx_lock(adev, flags);
882 if (IS_PCI(adev))
883 p = acxpci_s_proc_diag_output(p, adev);
885 p += sprintf(p,
886 "\n"
887 "** network status **\n"
888 "dev_state_mask 0x%04X\n"
889 "mode %u, channel %u, "
890 "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
891 adev->dev_state_mask,
892 adev->mode, adev->channel,
893 adev->reg_dom_id, adev->reg_dom_chanmask);
894 p += sprintf(p,
895 "ESSID \"%s\", essid_active %d, essid_len %d, "
896 "essid_for_assoc \"%s\", nick \"%s\"\n"
897 "WEP ena %d, restricted %d, idx %d\n",
898 adev->essid, adev->essid_active, (int)adev->essid_len,
899 adev->essid_for_assoc, adev->nick,
900 adev->wep_enabled, adev->wep_restricted,
901 adev->wep_current_index);
902 p += sprintf(p, "dev_addr " MACSTR "\n", MAC(adev->dev_addr));
903 p += sprintf(p, "bssid " MACSTR "\n", MAC(adev->bssid));
904 p += sprintf(p, "ap_filter " MACSTR "\n", MAC(adev->ap));
906 p += sprintf(p, "\n" "** PHY status **\n"
907 "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
908 "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
909 "rate_basic 0x%04X, rate_oper 0x%04X\n"
910 "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
911 "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
912 adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */
913 adev->sensitivity, adev->antenna, adev->ed_threshold,
914 adev->cca, adev->preamble_mode, adev->rate_basic, adev->rate_oper, adev->rts_threshold,
915 adev->frag_threshold, adev->short_retry, adev->long_retry,
916 adev->msdu_lifetime, adev->listen_interval,
917 adev->beacon_interval);
919 acx_unlock(adev, flags);
921 p += sprintf(p,
922 "\n"
923 "** Firmware **\n"
924 "NOTE: version dependent statistics layout, "
925 "please report if you suspect wrong parsing!\n"
926 "\n" "version \"%s\"\n", adev->firmware_version);
928 /* TODO: may replace kmalloc/memset with kzalloc once
929 * Linux 2.6.14 is widespread */
930 fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL);
931 if (!fw_stats) {
932 FN_EXIT1(0);
933 return 0;
935 memset(fw_stats, 0, sizeof(*fw_stats));
937 st = (u8 *) fw_stats;
939 part_str = "statistics query command";
941 if (OK != acx_s_interrogate(adev, st, ACX1xx_IE_FIRMWARE_STATISTICS))
942 goto fw_stats_end;
944 st += sizeof(u16);
945 len = *(u16 *) st;
947 if (len > sizeof(*fw_stats)) {
948 p += sprintf(p,
949 "firmware version with bigger fw_stats struct detected\n"
950 "(%u vs. %u), please report\n", len,
951 sizeof(fw_stats_t));
952 if (len > sizeof(*fw_stats)) {
953 p += sprintf(p, "struct size exceeded allocation!\n");
954 len = sizeof(*fw_stats);
957 st += sizeof(u16);
958 st_end = st - 2 * sizeof(u16) + len;
960 #ifdef __BIG_ENDIAN
961 /* let's make one bold assumption here:
962 * (hopefully!) *all* statistics fields are u32 only,
963 * thus if we need to make endianness corrections
964 * we can simply do them in one go, in advance */
965 st2 = (u8 *) fw_stats;
966 for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4)
967 *(u32 *) st2 = le32_to_cpu(*(u32 *) st2);
968 #endif
970 part_str = "Rx/Tx";
972 /* directly at end of a struct part? --> no error! */
973 if (st == st_end)
974 goto fw_stats_end;
976 tx = (fw_stats_tx_t *) st;
977 st += sizeof(fw_stats_tx_t);
978 rx = (fw_stats_rx_t *) st;
979 st += sizeof(fw_stats_rx_t);
980 partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t);
982 if (IS_ACX100(adev)) {
983 /* at least ACX100 PCI F/W 1.9.8.b
984 * and ACX100 USB F/W 1.0.7-USB
985 * don't have those two fields... */
986 st -= 2 * sizeof(u32);
988 /* our parsing doesn't quite match this firmware yet,
989 * log failure */
990 if (st > st_end)
991 goto fw_stats_fail;
992 temp1 = temp2 = 999999999;
993 } else {
994 if (st > st_end)
995 goto fw_stats_fail;
996 temp1 = rx->rx_aci_events;
997 temp2 = rx->rx_aci_resets;
1000 p += sprintf(p,
1001 "%s:\n"
1002 " tx_desc_overfl %u\n"
1003 " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
1004 " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n"
1005 " rx_aci_events %u, rx_aci_resets %u\n",
1006 part_str,
1007 tx->tx_desc_of,
1008 rx->rx_oom,
1009 rx->rx_hdr_of,
1010 rx->rx_hw_stuck,
1011 rx->rx_dropped_frame,
1012 rx->rx_frame_ptr_err, rx->rx_xfr_hint_trig, temp1, temp2);
1014 part_str = "DMA";
1016 if (st == st_end)
1017 goto fw_stats_end;
1019 dma = (fw_stats_dma_t *) st;
1020 partlen = sizeof(fw_stats_dma_t);
1021 st += partlen;
1023 if (st > st_end)
1024 goto fw_stats_fail;
1026 p += sprintf(p,
1027 "%s:\n"
1028 " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n",
1029 part_str,
1030 dma->rx_dma_req,
1031 dma->rx_dma_err, dma->tx_dma_req, dma->tx_dma_err);
1033 part_str = "IRQ";
1035 if (st == st_end)
1036 goto fw_stats_end;
1038 irq = (fw_stats_irq_t *) st;
1039 partlen = sizeof(fw_stats_irq_t);
1040 st += partlen;
1042 if (st > st_end)
1043 goto fw_stats_fail;
1045 p += sprintf(p,
1046 "%s:\n"
1047 " cmd_cplt %u, fiq %u\n"
1048 " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
1049 " irqs %u, tx_procs %u, decrypt_done %u\n"
1050 " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
1051 " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
1052 " host_acks %u, pci_pm %u, acm_wakeups %u\n",
1053 part_str,
1054 irq->cmd_cplt,
1055 irq->fiq,
1056 irq->rx_hdrs,
1057 irq->rx_cmplt,
1058 irq->rx_mem_of,
1059 irq->rx_rdys,
1060 irq->irqs,
1061 irq->tx_procs,
1062 irq->decrypt_done,
1063 irq->dma_0_done,
1064 irq->dma_1_done,
1065 irq->tx_exch_complet,
1066 irq->commands,
1067 irq->rx_procs,
1068 irq->hw_pm_mode_changes,
1069 irq->host_acks, irq->pci_pm, irq->acm_wakeups);
1071 part_str = "WEP";
1073 if (st == st_end)
1074 goto fw_stats_end;
1076 wep = (fw_stats_wep_t *) st;
1077 partlen = sizeof(fw_stats_wep_t);
1078 st += partlen;
1080 if ((IS_PCI(adev) && IS_ACX100(adev))
1081 || (IS_USB(adev) && IS_ACX100(adev))
1083 /* at least ACX100 PCI F/W 1.9.8.b
1084 * and ACX100 USB F/W 1.0.7-USB
1085 * don't have those two fields... */
1086 st -= 2 * sizeof(u32);
1087 if (st > st_end)
1088 goto fw_stats_fail;
1089 temp1 = temp2 = 999999999;
1090 } else {
1091 if (st > st_end)
1092 goto fw_stats_fail;
1093 temp1 = wep->wep_pkt_decrypt;
1094 temp2 = wep->wep_decrypt_irqs;
1097 p += sprintf(p,
1098 "%s:\n"
1099 " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
1100 " wep_key_not_found %u, wep_decrypt_fail %u\n"
1101 " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
1102 part_str,
1103 wep->wep_key_count,
1104 wep->wep_default_key_count,
1105 wep->dot11_def_key_mib,
1106 wep->wep_key_not_found,
1107 wep->wep_decrypt_fail, temp1, temp2);
1109 part_str = "power";
1111 if (st == st_end)
1112 goto fw_stats_end;
1114 pwr = (fw_stats_pwr_t *) st;
1115 partlen = sizeof(fw_stats_pwr_t);
1116 st += partlen;
1118 if (st > st_end)
1119 goto fw_stats_fail;
1121 p += sprintf(p,
1122 "%s:\n"
1123 " tx_start_ctr %u, no_ps_tx_too_short %u\n"
1124 " rx_start_ctr %u, no_ps_rx_too_short %u\n"
1125 " lppd_started %u\n"
1126 " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n",
1127 part_str,
1128 pwr->tx_start_ctr,
1129 pwr->no_ps_tx_too_short,
1130 pwr->rx_start_ctr,
1131 pwr->no_ps_rx_too_short,
1132 pwr->lppd_started,
1133 pwr->no_lppd_too_noisy,
1134 pwr->no_lppd_too_short, pwr->no_lppd_matching_frame);
1136 part_str = "MIC";
1138 if (st == st_end)
1139 goto fw_stats_end;
1141 mic = (fw_stats_mic_t *) st;
1142 partlen = sizeof(fw_stats_mic_t);
1143 st += partlen;
1145 if (st > st_end)
1146 goto fw_stats_fail;
1148 p += sprintf(p,
1149 "%s:\n"
1150 " mic_rx_pkts %u, mic_calc_fail %u\n",
1151 part_str, mic->mic_rx_pkts, mic->mic_calc_fail);
1153 part_str = "AES";
1155 if (st == st_end)
1156 goto fw_stats_end;
1158 aes = (fw_stats_aes_t *) st;
1159 partlen = sizeof(fw_stats_aes_t);
1160 st += partlen;
1162 if (st > st_end)
1163 goto fw_stats_fail;
1165 p += sprintf(p,
1166 "%s:\n"
1167 " aes_enc_fail %u, aes_dec_fail %u\n"
1168 " aes_enc_pkts %u, aes_dec_pkts %u\n"
1169 " aes_enc_irq %u, aes_dec_irq %u\n",
1170 part_str,
1171 aes->aes_enc_fail,
1172 aes->aes_dec_fail,
1173 aes->aes_enc_pkts,
1174 aes->aes_dec_pkts, aes->aes_enc_irq, aes->aes_dec_irq);
1176 part_str = "event";
1178 if (st == st_end)
1179 goto fw_stats_end;
1181 evt = (fw_stats_event_t *) st;
1182 partlen = sizeof(fw_stats_event_t);
1183 st += partlen;
1185 if (st > st_end)
1186 goto fw_stats_fail;
1188 p += sprintf(p,
1189 "%s:\n"
1190 " heartbeat %u, calibration %u\n"
1191 " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
1192 " oom_late %u\n"
1193 " phy_tx_err %u, tx_stuck %u\n",
1194 part_str,
1195 evt->heartbeat,
1196 evt->calibration,
1197 evt->rx_mismatch,
1198 evt->rx_mem_empty,
1199 evt->rx_pool,
1200 evt->oom_late, evt->phy_tx_err, evt->tx_stuck);
1202 if (st < st_end)
1203 goto fw_stats_bigger;
1205 goto fw_stats_end;
1207 fw_stats_fail:
1208 st -= partlen;
1209 p += sprintf(p,
1210 "failed at %s part (size %u), offset %u (struct size %u), "
1211 "please report\n", part_str, partlen,
1212 (int)((void *)st - (void *)fw_stats), len);
1214 fw_stats_bigger:
1215 for (; st < st_end; st += 4)
1216 p += sprintf(p,
1217 "UNKN%3d: %u\n",
1218 (int)((void *)st - (void *)fw_stats), *(u32 *) st);
1220 fw_stats_end:
1221 kfree(fw_stats);
1223 FN_EXIT1(p - buf);
1224 return p - buf;
1228 /***********************************************************************
1230 static int acx_s_proc_phy_output(char *buf, acx_device_t * adev)
1232 char *p = buf;
1233 int i;
1235 FN_ENTER;
1238 if (RADIO_RFMD_11 != adev->radio_type) {
1239 printk("sorry, not yet adapted for radio types "
1240 "other than RFMD, please verify "
1241 "PHY size etc. first!\n");
1242 goto end;
1246 /* The PHY area is only 0x80 bytes long; further pages after that
1247 * only have some page number registers with altered value,
1248 * all other registers remain the same. */
1249 for (i = 0; i < 0x80; i++) {
1250 acx_s_read_phy_reg(adev, i, p++);
1253 FN_EXIT1(p - buf);
1254 return p - buf;
1258 /***********************************************************************
1259 ** acx_e_read_proc_XXXX
1260 ** Handle our /proc entry
1262 ** Arguments:
1263 ** standard kernel read_proc interface
1264 ** Returns:
1265 ** number of bytes written to buf
1266 ** Side effects:
1267 ** none
1269 static int
1270 acx_e_read_proc(char *buf, char **start, off_t offset, int count,
1271 int *eof, void *data)
1273 acx_device_t *adev = (acx_device_t *) data;
1274 unsigned long flags;
1275 int length;
1277 FN_ENTER;
1279 acx_sem_lock(adev);
1280 acx_lock(adev, flags);
1281 /* fill buf */
1282 length = acx_l_proc_output(buf, adev);
1283 acx_unlock(adev, flags);
1284 acx_sem_unlock(adev);
1286 /* housekeeping */
1287 if (length <= offset + count)
1288 *eof = 1;
1289 *start = buf + offset;
1290 length -= offset;
1291 if (length > count)
1292 length = count;
1293 if (length < 0)
1294 length = 0;
1295 FN_EXIT1(length);
1296 return length;
1299 static int
1300 acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count,
1301 int *eof, void *data)
1303 acx_device_t *adev = (acx_device_t *) data;
1304 int length;
1306 FN_ENTER;
1308 acx_sem_lock(adev);
1309 /* fill buf */
1310 length = acx_s_proc_diag_output(buf, adev);
1311 acx_sem_unlock(adev);
1313 /* housekeeping */
1314 if (length <= offset + count)
1315 *eof = 1;
1316 *start = buf + offset;
1317 length -= offset;
1318 if (length > count)
1319 length = count;
1320 if (length < 0)
1321 length = 0;
1322 FN_EXIT1(length);
1323 return length;
1326 static int
1327 acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count,
1328 int *eof, void *data)
1330 acx_device_t *adev = (acx_device_t *) data;
1331 int length;
1333 FN_ENTER;
1335 /* fill buf */
1336 length = 0;
1337 if (IS_PCI(adev)) {
1338 acx_sem_lock(adev);
1339 length = acxpci_proc_eeprom_output(buf, adev);
1340 acx_sem_unlock(adev);
1343 /* housekeeping */
1344 if (length <= offset + count)
1345 *eof = 1;
1346 *start = buf + offset;
1347 length -= offset;
1348 if (length > count)
1349 length = count;
1350 if (length < 0)
1351 length = 0;
1352 FN_EXIT1(length);
1353 return length;
1356 static int
1357 acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count,
1358 int *eof, void *data)
1360 acx_device_t *adev = (acx_device_t *) data;
1361 int length;
1363 FN_ENTER;
1365 acx_sem_lock(adev);
1366 /* fill buf */
1367 length = acx_s_proc_phy_output(buf, adev);
1368 acx_sem_unlock(adev);
1370 /* housekeeping */
1371 if (length <= offset + count)
1372 *eof = 1;
1373 *start = buf + offset;
1374 length -= offset;
1375 if (length > count)
1376 length = count;
1377 if (length < 0)
1378 length = 0;
1379 FN_EXIT1(length);
1380 return length;
1384 /***********************************************************************
1385 ** /proc files registration
1387 static const char *const
1388 proc_files[] = { "", "_diag", "_eeprom", "_phy" };
1390 static read_proc_t *const
1391 proc_funcs[] = {
1392 acx_e_read_proc,
1393 acx_e_read_proc_diag,
1394 acx_e_read_proc_eeprom,
1395 acx_e_read_proc_phy
1398 static int manage_proc_entries(struct ieee80211_hw *hw, int remove)
1400 acx_device_t *adev = ieee2adev(hw);
1401 char procbuf[80];
1402 int i;
1404 FN_ENTER;
1406 for (i = 0; i < ARRAY_SIZE(proc_files); i++) {
1407 snprintf(procbuf, sizeof(procbuf),
1408 "driver/acx_%s", proc_files[i]);
1409 log(L_INIT, "%sing /proc entry %s\n",
1410 remove ? "remov" : "creat", procbuf);
1411 if (!remove) {
1412 if (!create_proc_read_entry
1413 (procbuf, 0, NULL, proc_funcs[i], adev)) {
1414 printk("acx: cannot register /proc entry %s\n",
1415 procbuf);
1416 FN_EXIT1(NOT_OK);
1417 return NOT_OK;
1419 } else {
1420 remove_proc_entry(procbuf, NULL);
1423 FN_EXIT0;
1424 return OK;
1427 int acx_proc_register_entries(struct ieee80211_hw *ieee)
1429 return manage_proc_entries(ieee, 0);
1432 int acx_proc_unregister_entries(struct ieee80211_hw *ieee)
1434 return manage_proc_entries(ieee, 1);
1436 #endif /* CONFIG_PROC_FS */
1438 /****
1439 ** Gathered From rt2x00 and bcm43xx_mac80211 projects
1441 void acx_free_modes(acx_device_t * adev)
1444 // kfree(adev->modes);
1445 // adev->modes = NULL;
1448 #define RATETAB_ENT(_rate, _rateid, _flags) \
1450 .rate = (_rate), \
1451 .val = (_rateid), \
1452 .val2 = (_rateid), \
1453 .flags = (_flags), \
1457 static struct ieee80211_rate __acx_ratetable[] = {
1458 RATETAB_ENT(10, RATE111_1, IEEE80211_RATE_CCK),
1459 RATETAB_ENT(20, RATE111_2, IEEE80211_RATE_CCK_2),
1460 RATETAB_ENT(55, RATE111_5, IEEE80211_RATE_CCK_2),
1461 RATETAB_ENT(110, RATE111_11, IEEE80211_RATE_CCK_2),
1462 RATETAB_ENT(60, RATE111_6, IEEE80211_RATE_OFDM),
1463 RATETAB_ENT(90, RATE111_9, IEEE80211_RATE_OFDM),
1464 RATETAB_ENT(120, RATE111_12, IEEE80211_RATE_OFDM),
1465 RATETAB_ENT(180, RATE111_18, IEEE80211_RATE_OFDM),
1466 RATETAB_ENT(240, RATE111_24, IEEE80211_RATE_OFDM),
1467 RATETAB_ENT(360, RATE111_36, IEEE80211_RATE_OFDM),
1468 RATETAB_ENT(480, RATE111_48, IEEE80211_RATE_OFDM),
1469 RATETAB_ENT(540, RATE111_54, IEEE80211_RATE_OFDM),
1472 #define acx_b_ratetable (__acx_ratetable + 0)
1473 #define acx_b_ratetable_size 4
1474 #define acx_g_ratetable (__acx_ratetable + 0)
1475 #define acx_g_ratetable_size 12
1477 #define CHANTAB_ENT(_chanid, _freq) \
1479 .chan = (_chanid), \
1480 .freq = (_freq), \
1481 .val = (_chanid), \
1482 .flag = IEEE80211_CHAN_W_SCAN | \
1483 IEEE80211_CHAN_W_ACTIVE_SCAN | \
1484 IEEE80211_CHAN_W_IBSS, \
1485 .power_level = 0xf, \
1486 .antenna_max = 0xFF, \
1488 static struct ieee80211_channel channels[] = {
1489 CHANTAB_ENT(1, 2412),
1490 CHANTAB_ENT(2, 2417),
1491 CHANTAB_ENT(3, 2422),
1492 CHANTAB_ENT(4, 2427),
1493 CHANTAB_ENT(5, 2432),
1494 CHANTAB_ENT(6, 2437),
1495 CHANTAB_ENT(7, 2442),
1496 CHANTAB_ENT(8, 2447),
1497 CHANTAB_ENT(9, 2452),
1498 CHANTAB_ENT(10, 2457),
1499 CHANTAB_ENT(11, 2462),
1500 CHANTAB_ENT(12, 2467),
1501 CHANTAB_ENT(13, 2472),
1504 #define acx_chantable_size ARRAY_SIZE(channels)
1507 static int acx_setup_modes_bphy(acx_device_t * adev)
1509 int err = 0;
1510 struct ieee80211_hw *hw = adev->ieee;
1511 struct ieee80211_hw_mode *mode;
1513 FN_ENTER;
1515 mode = &adev->modes[0];
1516 mode->mode = MODE_IEEE80211B;
1517 mode->num_channels = acx_chantable_size;
1518 mode->channels = channels;
1519 mode->num_rates = acx_b_ratetable_size;
1520 mode->rates = acx_b_ratetable;
1521 err = ieee80211_register_hwmode(hw,mode);
1523 FN_EXIT1(err);
1524 return err;
1527 static int acx_setup_modes_gphy(acx_device_t * adev)
1529 int err = 0;
1530 struct ieee80211_hw *hw = adev->ieee;
1531 struct ieee80211_hw_mode *mode;
1533 FN_ENTER;
1535 mode = &adev->modes[1];
1536 mode->mode = MODE_IEEE80211G;
1537 mode->num_channels = acx_chantable_size;
1538 mode->channels = channels;
1539 mode->num_rates = acx_g_ratetable_size;
1540 mode->rates = acx_g_ratetable;
1541 err = ieee80211_register_hwmode(hw,mode);
1543 FN_EXIT1(err);
1544 return err;
1548 int acx_setup_modes(acx_device_t * adev)
1550 struct ieee80211_hw *hw = adev->ieee;
1551 struct ieee80211_hw_mode *mode;
1552 int err = -ENOMEM;
1554 FN_ENTER;
1556 if (IS_ACX111(adev)) {
1558 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);
1559 err = acx_setup_modes_gphy(adev);
1561 mode = &adev->modes[1];
1562 mode->mode = MODE_IEEE80211G;
1563 mode->num_channels = acx_chantable_size;
1564 mode->num_rates = acx_g_ratetable_size;
1565 mode->rates = acx_g_ratetable;
1566 } else {
1568 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1569 err = acx_setup_modes_bphy(adev);
1571 mode = &adev->modes[0];
1572 mode->mode = MODE_IEEE80211B;
1573 mode->num_channels = acx_chantable_size;
1574 mode->num_rates = acx_b_ratetable_size;
1575 mode->rates = acx_b_ratetable;
1578 /* if (err && adev->modes)
1579 kfree(adev->modes);*/
1581 mode->channels = channels;
1582 err = ieee80211_register_hwmode(hw,mode);
1584 FN_EXIT1(err);
1585 return err;
1589 /***********************************************************************
1590 ** acx_fill_beacon_or_proberesp_template
1592 ** Origin: derived from rt2x00 project
1594 static int
1595 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1596 struct acx_template_beacon *templ,
1597 struct sk_buff* skb /* in host order! */)
1599 FN_ENTER;
1601 memcpy(templ,skb->data, skb->len);
1602 FN_EXIT1(skb->len);
1603 return skb->len;
1606 /***********************************************************************
1607 ** acx_s_set_beacon_template
1611 static int
1612 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1614 struct acx_template_beacon bcn;
1615 int len, result;
1617 FN_ENTER;
1618 printk("Size of template: %08X, Size of beacon: %08X\n",sizeof(struct acx_template_beacon),skb->len);
1619 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1620 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1622 FN_EXIT1(result);
1623 return result;
1626 /***********************************************************************
1627 ** acx_cmd_join_bssid
1629 ** Common code for both acx100 and acx111.
1631 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1632 static const u8 bitpos2genframe_txrate[] = {
1633 10, /* 0. 1 Mbit/s */
1634 20, /* 1. 2 Mbit/s */
1635 55, /* 2. 5.5 Mbit/s */
1636 0x0B, /* 3. 6 Mbit/s */
1637 0x0F, /* 4. 9 Mbit/s */
1638 110, /* 5. 11 Mbit/s */
1639 0x0A, /* 6. 12 Mbit/s */
1640 0x0E, /* 7. 18 Mbit/s */
1641 220, /* 8. 22 Mbit/s */
1642 0x09, /* 9. 24 Mbit/s */
1643 0x0D, /* 10. 36 Mbit/s */
1644 0x08, /* 11. 48 Mbit/s */
1645 0x0C, /* 12. 54 Mbit/s */
1646 10, /* 13. 1 Mbit/s, should never happen */
1647 10, /* 14. 1 Mbit/s, should never happen */
1648 10, /* 15. 1 Mbit/s, should never happen */
1651 /* Looks scary, eh?
1652 ** Actually, each one compiled into one AND and one SHIFT,
1653 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1654 static inline unsigned int rate111to5bits(unsigned int rate)
1656 return (rate & 0x7)
1657 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1658 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1662 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1664 acx_joinbss_t tmp;
1665 int dtim_interval;
1666 int i;
1668 if (mac_is_zero(bssid))
1669 return;
1671 FN_ENTER;
1673 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1674 1 : adev->dtim_interval;
1676 memset(&tmp, 0, sizeof(tmp));
1678 for (i = 0; i < ETH_ALEN; i++) {
1679 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1682 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1684 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1685 ** are sent with one of these rates */
1686 if (IS_ACX111(adev)) {
1687 /* It was experimentally determined that rates_basic
1688 ** can take 11g rates as well, not only rates
1689 ** defined with JOINBSS_RATES_BASIC111_nnn.
1690 ** Just use RATE111_nnn constants... */
1691 tmp.u.acx111.dtim_interval = dtim_interval;
1692 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1693 log(L_ASSOC, "rates_basic:%04X, rates_supported:%04X\n",
1694 adev->rate_basic, adev->rate_oper);
1695 } else {
1696 tmp.u.acx100.dtim_interval = dtim_interval;
1697 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1698 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1699 log(L_ASSOC, "rates_basic:%04X->%02X, "
1700 "rates_supported:%04X->%02X\n",
1701 adev->rate_basic, tmp.u.acx100.rates_basic,
1702 adev->rate_oper, tmp.u.acx100.rates_supported);
1705 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1706 ** will be sent (rate/modulation/preamble) */
1707 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1708 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1709 /* we can use short pre *if* all peers can understand it */
1710 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1712 /* we switch fw to STA mode in MONITOR mode, it seems to be
1713 ** the only mode where fw does not emit beacons by itself
1714 ** but allows us to send anything (we really want to retain
1715 ** ability to tx arbitrary frames in MONITOR mode)
1717 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1718 tmp.channel = adev->channel;
1719 tmp.essid_len = adev->essid_len;
1721 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1722 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1724 log(L_ASSOC|L_DEBUG, "BSS_Type = %u\n", tmp.macmode);
1725 acxlog_mac(L_ASSOC|L_DEBUG, "JoinBSSID MAC:", adev->bssid, "\n");
1727 /* acx_update_capabilities(adev); */
1728 FN_EXIT0;
1731 /***********************************************************************
1732 ** acxpci_i_set_multicast_list
1733 ** FIXME: most likely needs refinement
1735 void
1736 acx_i_set_multicast_list(struct ieee80211_hw *hw,
1737 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1738 unsigned short netflags, int mc_count)
1739 #else
1740 unsigned int changed_flags,
1741 unsigned int *total_flags,
1742 int mc_count, struct dev_addr_list *mc_list)
1743 #endif
1745 acx_device_t *adev = ieee2adev(hw);
1746 unsigned long flags;
1748 FN_ENTER;
1750 acx_lock(adev, flags);
1752 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
1753 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI);
1754 if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1755 return;
1756 #endif
1758 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1759 if (netflags & (IFF_PROMISC | IFF_ALLMULTI)) {
1760 #else
1761 if (*total_flags) {
1762 #endif
1763 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1764 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1765 SET_BIT(adev->set_mask, SET_RXCONFIG);
1766 /* let kernel know in case *we* needed to set promiscuous */
1767 } else {
1768 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1769 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1770 SET_BIT(adev->set_mask, SET_RXCONFIG);
1773 /* cannot update card settings directly here, atomic context */
1774 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
1776 acx_unlock(adev, flags);
1778 FN_EXIT0;
1781 /***********************************************************************
1782 ** acx111 feature config
1784 ** Obvious
1786 static int
1787 acx111_s_get_feature_config(acx_device_t * adev,
1788 u32 * feature_options, u32 * data_flow_options)
1790 struct acx111_ie_feature_config feat;
1792 FN_ENTER;
1794 if (!IS_ACX111(adev)) {
1795 return NOT_OK;
1798 memset(&feat, 0, sizeof(feat));
1800 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1801 FN_EXIT1(NOT_OK);
1802 return NOT_OK;
1804 log(L_DEBUG,
1805 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1806 feat.feature_options, feat.data_flow_options);
1808 if (feature_options)
1809 *feature_options = le32_to_cpu(feat.feature_options);
1810 if (data_flow_options)
1811 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1813 FN_EXIT0;
1814 return OK;
1818 static int
1819 acx111_s_set_feature_config(acx_device_t * adev,
1820 u32 feature_options, u32 data_flow_options,
1821 unsigned int mode
1822 /* 0 == remove, 1 == add, 2 == set */ )
1824 struct acx111_ie_feature_config feat;
1826 FN_ENTER;
1828 if (!IS_ACX111(adev)) {
1829 FN_EXIT1(NOT_OK);
1830 return NOT_OK;
1833 if ((mode < 0) || (mode > 2)) {
1834 FN_EXIT1(NOT_OK);
1835 return NOT_OK;
1838 if (mode != 2)
1839 /* need to modify old data */
1840 acx111_s_get_feature_config(adev, &feat.feature_options,
1841 &feat.data_flow_options);
1842 else {
1843 /* need to set a completely new value */
1844 feat.feature_options = 0;
1845 feat.data_flow_options = 0;
1848 if (mode == 0) { /* remove */
1849 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1850 CLEAR_BIT(feat.data_flow_options,
1851 cpu_to_le32(data_flow_options));
1852 } else { /* add or set */
1853 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1854 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1857 log(L_DEBUG,
1858 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1859 "new: feature 0x%08X dataflow 0x%08X\n",
1860 feature_options, data_flow_options, mode,
1861 le32_to_cpu(feat.feature_options),
1862 le32_to_cpu(feat.data_flow_options));
1864 if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1865 FN_EXIT1(NOT_OK);
1866 return NOT_OK;
1869 FN_EXIT0;
1870 return OK;
1873 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1875 return acx111_s_set_feature_config(adev, f, d, 0);
1877 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1879 return acx111_s_set_feature_config(adev, f, d, 1);
1881 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1883 return acx111_s_set_feature_config(adev, f, d, 2);
1887 /***********************************************************************
1888 ** acx100_s_init_memory_pools
1890 static int
1891 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1893 acx100_ie_memblocksize_t MemoryBlockSize;
1894 acx100_ie_memconfigoption_t MemoryConfigOption;
1895 int TotalMemoryBlocks;
1896 int RxBlockNum;
1897 int TotalRxBlockSize;
1898 int TxBlockNum;
1899 int TotalTxBlockSize;
1901 FN_ENTER;
1903 /* Let's see if we can follow this:
1904 first we select our memory block size (which I think is
1905 completely arbitrary) */
1906 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1908 /* Then we alert the card to our decision of block size */
1909 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
1910 goto bad;
1913 /* We figure out how many total blocks we can create, using
1914 the block size we chose, and the beginning and ending
1915 memory pointers, i.e.: end-start/size */
1916 TotalMemoryBlocks =
1917 (le32_to_cpu(mmt->PoolEnd) -
1918 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1920 log(L_DEBUG, "TotalMemoryBlocks=%u (%u bytes)\n",
1921 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1923 /* MemoryConfigOption.DMA_config bitmask:
1924 access to ACX memory is to be done:
1925 0x00080000 using PCI conf space?!
1926 0x00040000 using IO instructions?
1927 0x00000000 using memory access instructions
1928 0x00020000 using local memory block linked list (else what?)
1929 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1931 if (IS_PCI(adev)) {
1932 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1933 /* Declare start of the Rx host pool */
1934 MemoryConfigOption.pRxHostDesc =
1935 cpu2acx(adev->rxhostdesc_startphy);
1936 log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
1937 acx2cpu(MemoryConfigOption.pRxHostDesc),
1938 (long)adev->rxhostdesc_startphy);
1939 } else {
1940 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1943 /* 50% of the allotment of memory blocks go to tx descriptors */
1944 TxBlockNum = TotalMemoryBlocks / 2;
1945 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1947 /* and 50% go to the rx descriptors */
1948 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1949 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1951 /* size of the tx and rx descriptor queues */
1952 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1953 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1954 log(L_DEBUG, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u "
1955 "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum,
1956 TotalTxBlockSize, TotalRxBlockSize);
1959 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1960 MemoryConfigOption.rx_mem =
1961 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1963 /* align the rx descriptor queue to units of 0x20
1964 * and offset it by the tx descriptor queue */
1965 MemoryConfigOption.tx_mem =
1966 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
1967 0x1f) & ~0x1f);
1968 log(L_DEBUG, "rx_mem %08X rx_mem %08X\n", MemoryConfigOption.tx_mem,
1969 MemoryConfigOption.rx_mem);
1971 /* alert the device to our decision */
1972 if (OK !=
1973 acx_s_configure(adev, &MemoryConfigOption,
1974 ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
1975 goto bad;
1978 /* and tell the device to kick it into gear */
1979 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
1980 goto bad;
1982 FN_EXIT1(OK);
1983 return OK;
1984 bad:
1985 FN_EXIT1(NOT_OK);
1986 return NOT_OK;
1990 /***********************************************************************
1991 ** acx100_s_create_dma_regions
1993 ** Note that this fn messes up heavily with hardware, but we cannot
1994 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1996 static int acx100_s_create_dma_regions(acx_device_t * adev)
1998 acx100_ie_queueconfig_t queueconf;
1999 acx_ie_memmap_t memmap;
2000 int res = NOT_OK;
2001 u32 tx_queue_start, rx_queue_start;
2003 FN_ENTER;
2005 /* read out the acx100 physical start address for the queues */
2006 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2007 goto fail;
2010 tx_queue_start = le32_to_cpu(memmap.QueueStart);
2011 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
2013 log(L_DEBUG, "initializing Queue Indicator\n");
2015 memset(&queueconf, 0, sizeof(queueconf));
2017 /* Not needed for PCI, so we can avoid setting them altogether */
2018 if (IS_USB(adev)) {
2019 queueconf.NumTxDesc = USB_TX_CNT;
2020 queueconf.NumRxDesc = USB_RX_CNT;
2023 /* calculate size of queues */
2024 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
2025 RX_CNT * sizeof(rxdesc_t) + 8);
2026 queueconf.NumTxQueues = 1; /* number of tx queues */
2027 /* sets the beginning of the tx descriptor queue */
2028 queueconf.TxQueueStart = memmap.QueueStart;
2029 /* done by memset: queueconf.TxQueuePri = 0; */
2030 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
2031 queueconf.QueueOptions = 1; /* auto reset descriptor */
2032 /* sets the end of the rx descriptor queue */
2033 queueconf.QueueEnd =
2034 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
2036 /* sets the beginning of the next queue */
2037 queueconf.HostQueueEnd =
2038 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
2039 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
2040 goto fail;
2043 if (IS_PCI(adev)) {
2044 /* sets the beginning of the rx descriptor queue, after the tx descrs */
2045 if (OK != acxpci_s_create_hostdesc_queues(adev))
2046 goto fail;
2047 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2050 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2051 goto fail;
2054 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
2055 0x1f) & ~0x1f);
2057 if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2058 goto fail;
2061 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
2062 goto fail;
2065 res = OK;
2066 goto end;
2068 fail:
2069 acx_s_mwait(1000); /* ? */
2070 if (IS_PCI(adev))
2071 acxpci_free_desc_queues(adev);
2072 end:
2073 FN_EXIT1(res);
2074 return res;
2078 /***********************************************************************
2079 ** acx111_s_create_dma_regions
2081 ** Note that this fn messes heavily with hardware, but we cannot
2082 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2084 #define ACX111_PERCENT(percent) ((percent)/5)
2086 static int acx111_s_create_dma_regions(acx_device_t * adev)
2088 struct acx111_ie_memoryconfig memconf;
2089 struct acx111_ie_queueconfig queueconf;
2090 u32 tx_queue_start, rx_queue_start;
2092 FN_ENTER;
2094 /* Calculate memory positions and queue sizes */
2096 /* Set up our host descriptor pool + data pool */
2097 if (IS_PCI(adev)) {
2098 if (OK != acxpci_s_create_hostdesc_queues(adev))
2099 goto fail;
2102 memset(&memconf, 0, sizeof(memconf));
2103 /* the number of STAs (STA contexts) to support
2104 ** NB: was set to 1 and everything seemed to work nevertheless... */
2105 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
2106 /* specify the memory block size. Default is 256 */
2107 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
2108 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
2109 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
2110 /* set the count of our queues
2111 ** NB: struct acx111_ie_memoryconfig shall be modified
2112 ** if we ever will switch to more than one rx and/or tx queue */
2113 memconf.count_rx_queues = 1;
2114 memconf.count_tx_queues = 1;
2115 /* 0 == Busmaster Indirect Memory Organization, which is what we want
2116 * (using linked host descs with their allocated mem).
2117 * 2 == Generic Bus Slave */
2118 /* done by memset: memconf.options = 0; */
2119 /* let's use 25% for fragmentations and 75% for frame transfers
2120 * (specified in units of 5%) */
2121 memconf.fragmentation = ACX111_PERCENT(75);
2122 /* Rx descriptor queue config */
2123 memconf.rx_queue1_count_descs = RX_CNT;
2124 memconf.rx_queue1_type = 7; /* must be set to 7 */
2125 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2126 if (IS_PCI(adev)) {
2127 memconf.rx_queue1_host_rx_start =
2128 cpu2acx(adev->rxhostdesc_startphy);
2130 /* Tx descriptor queue config */
2131 memconf.tx_queue1_count_descs = TX_CNT;
2132 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2134 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
2135 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2136 ** But it is actually correct wrt IE numbers.
2137 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
2138 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2139 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2140 if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
2141 goto fail;
2144 acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
2146 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2147 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2149 log(L_INIT, "dump queue head (from card):\n"
2150 "len: %u\n"
2151 "tx_memory_block_address: %X\n"
2152 "rx_memory_block_address: %X\n"
2153 "tx1_queue address: %X\n"
2154 "rx1_queue address: %X\n",
2155 le16_to_cpu(queueconf.len),
2156 le32_to_cpu(queueconf.tx_memory_block_address),
2157 le32_to_cpu(queueconf.rx_memory_block_address),
2158 tx_queue_start, rx_queue_start);
2160 if (IS_PCI(adev))
2161 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2163 FN_EXIT1(OK);
2164 return OK;
2165 fail:
2166 if (IS_PCI(adev))
2167 acxpci_free_desc_queues(adev);
2169 FN_EXIT1(NOT_OK);
2170 return NOT_OK;
2174 /***********************************************************************
2176 static void acx_s_initialize_rx_config(acx_device_t * adev)
2178 struct {
2179 u16 id;
2180 u16 len;
2181 u16 rx_cfg1;
2182 u16 rx_cfg2;
2183 } ACX_PACKED cfg;
2184 switch (adev->mode) {
2185 case ACX_MODE_MONITOR:
2186 adev->rx_config_1 = (u16) (0
2187 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2188 /* | RX_CFG1_FILTER_SSID */
2189 /* | RX_CFG1_FILTER_BCAST */
2190 /* | RX_CFG1_RCV_MC_ADDR1 */
2191 /* | RX_CFG1_RCV_MC_ADDR0 */
2192 /* | RX_CFG1_FILTER_ALL_MULTI */
2193 /* | RX_CFG1_FILTER_BSSID */
2194 /* | RX_CFG1_FILTER_MAC */
2195 | RX_CFG1_RCV_PROMISCUOUS
2196 | RX_CFG1_INCLUDE_FCS
2197 /* | RX_CFG1_INCLUDE_PHY_HDR */
2199 adev->rx_config_2 = (u16) (0
2200 | RX_CFG2_RCV_ASSOC_REQ
2201 | RX_CFG2_RCV_AUTH_FRAMES
2202 | RX_CFG2_RCV_BEACON_FRAMES
2203 | RX_CFG2_RCV_CONTENTION_FREE
2204 | RX_CFG2_RCV_CTRL_FRAMES
2205 | RX_CFG2_RCV_DATA_FRAMES
2206 | RX_CFG2_RCV_BROKEN_FRAMES
2207 | RX_CFG2_RCV_MGMT_FRAMES
2208 | RX_CFG2_RCV_PROBE_REQ
2209 | RX_CFG2_RCV_PROBE_RESP
2210 | RX_CFG2_RCV_ACK_FRAMES
2211 | RX_CFG2_RCV_OTHER);
2212 break;
2213 default:
2214 adev->rx_config_1 = (u16) (0
2215 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2216 /* | RX_CFG1_FILTER_SSID */
2217 /* | RX_CFG1_FILTER_BCAST */
2218 /* | RX_CFG1_RCV_MC_ADDR1 */
2219 /* | RX_CFG1_RCV_MC_ADDR0 */
2220 /* | RX_CFG1_FILTER_ALL_MULTI */
2221 /* | RX_CFG1_FILTER_BSSID */
2222 /* | RX_CFG1_FILTER_MAC */
2223 | RX_CFG1_RCV_PROMISCUOUS
2224 /* | RX_CFG1_INCLUDE_FCS */
2225 /* | RX_CFG1_INCLUDE_PHY_HDR */
2227 adev->rx_config_2 = (u16) (0
2228 | RX_CFG2_RCV_ASSOC_REQ
2229 | RX_CFG2_RCV_AUTH_FRAMES
2230 | RX_CFG2_RCV_BEACON_FRAMES
2231 | RX_CFG2_RCV_CONTENTION_FREE
2232 | RX_CFG2_RCV_CTRL_FRAMES
2233 | RX_CFG2_RCV_DATA_FRAMES
2234 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2235 | RX_CFG2_RCV_MGMT_FRAMES
2236 | RX_CFG2_RCV_PROBE_REQ
2237 | RX_CFG2_RCV_PROBE_RESP
2238 | RX_CFG2_RCV_ACK_FRAMES
2239 | RX_CFG2_RCV_OTHER);
2240 break;
2242 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2244 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2245 || (adev->firmware_numver >= 0x02000000))
2246 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2247 else
2248 adev->phy_header_len = 0;
2250 log(L_INIT, "setting RXconfig to %04X:%04X\n",
2251 adev->rx_config_1, adev->rx_config_2);
2252 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2253 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2254 acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
2258 /***********************************************************************
2259 ** acx_s_set_defaults
2261 void acx_s_set_defaults(acx_device_t * adev)
2263 unsigned long flags;
2265 FN_ENTER;
2267 acx_lock(adev, flags);
2268 /* do it before getting settings, prevent bogus channel 0 warning */
2269 adev->channel = 1;
2271 /* query some settings from the card.
2272 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2273 * query is REQUIRED, otherwise the card won't work correctly! */
2274 adev->get_mask =
2275 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2276 GETSET_REG_DOMAIN;
2277 /* Only ACX100 supports ED and CCA */
2278 if (IS_ACX100(adev))
2279 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2281 acx_s_update_card_settings(adev);
2284 /* set our global interrupt mask */
2285 if (IS_PCI(adev))
2286 acxpci_set_interrupt_mask(adev);
2288 adev->led_power = 1; /* LED is active on startup */
2289 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2290 adev->brange_time_last_state_change = jiffies;
2292 /* copy the MAC address we just got from the card
2293 * into our MAC address used during current 802.11 session */
2294 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
2295 MAC_BCAST(adev->ap);
2297 adev->essid_len =
2298 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2299 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2300 adev->essid_active = 1;
2302 /* we have a nick field to waste, so why not abuse it
2303 * to announce the driver version? ;-) */
2304 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2306 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2307 /* first regulatory domain entry in EEPROM == default reg. domain */
2308 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2311 /* 0xffff would be better, but then we won't get a "scan complete"
2312 * interrupt, so our current infrastructure will fail: */
2313 adev->scan_count = 1;
2314 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2315 adev->scan_duration = 100;
2316 adev->scan_probe_delay = 200;
2317 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2318 adev->scan_rate = ACX_SCAN_RATE_1;
2321 adev->mode = ACX_MODE_2_STA;
2322 adev->listen_interval = 100;
2323 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2324 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2326 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2328 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2329 adev->frag_threshold = 2346;
2331 /* use standard default values for retry limits */
2332 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2333 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2335 adev->preamble_mode = 2; /* auto */
2336 adev->fallback_threshold = 3;
2337 adev->stepup_threshold = 10;
2338 adev->rate_bcast = RATE111_1;
2339 adev->rate_bcast100 = RATE100_1;
2340 adev->rate_basic = RATE111_1 | RATE111_2;
2341 adev->rate_auto = 1;
2342 if (IS_ACX111(adev)) {
2343 adev->rate_oper = RATE111_ALL;
2344 } else {
2345 adev->rate_oper = RATE111_ACX100_COMPAT;
2348 /* Supported Rates element - the rates here are given in units of
2349 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2350 acx_l_update_ratevector(adev);
2352 /* set some more defaults */
2353 if (IS_ACX111(adev)) {
2354 /* 30mW (15dBm) is default, at least in my acx111 card: */
2355 adev->tx_level_dbm = 15;
2356 } else {
2357 /* don't use max. level, since it might be dangerous
2358 * (e.g. WRT54G people experience
2359 * excessive Tx power damage!) */
2360 adev->tx_level_dbm = 18;
2362 /* adev->tx_level_auto = 1; */
2363 if (IS_ACX111(adev)) {
2364 /* start with sensitivity level 1 out of 3: */
2365 adev->sensitivity = 1;
2368 /* #define ENABLE_POWER_SAVE */
2369 #ifdef ENABLE_POWER_SAVE
2370 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2371 adev->ps_listen_interval = 1;
2372 adev->ps_options =
2373 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2374 adev->ps_hangover_period = 30;
2375 adev->ps_enhanced_transition_time = 0;
2376 #else
2377 adev->ps_wakeup_cfg = 0;
2378 adev->ps_listen_interval = 0;
2379 adev->ps_options = 0;
2380 adev->ps_hangover_period = 0;
2381 adev->ps_enhanced_transition_time = 0;
2382 #endif
2384 /* These settings will be set in fw on ifup */
2385 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2386 /* configure card to do rate fallback when in auto rate mode */
2387 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2388 /* better re-init the antenna value we got above */
2389 | GETSET_ANTENNA
2390 #if POWER_SAVE_80211
2391 | GETSET_POWER_80211
2392 #endif
2395 acx_unlock(adev, flags);
2396 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2398 acx_s_initialize_rx_config(adev);
2400 FN_EXIT0;
2404 /***********************************************************************
2405 ** FIXME: this should be solved in a general way for all radio types
2406 ** by decoding the radio firmware module,
2407 ** since it probably has some standard structure describing how to
2408 ** set the power level of the radio module which it controls.
2409 ** Or maybe not, since the radio module probably has a function interface
2410 ** instead which then manages Tx level programming :-\
2412 ** Obvious
2414 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2416 struct acx111_ie_tx_level tx_level;
2418 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2419 * 1 (30mW) [15dBm]
2420 * 2 (10mW) [10dBm]
2421 * For now, just assume all other acx111 cards have the same.
2422 * FIXME: Ideally we would query it here, but we first need a
2423 * standard way to query individual configoptions easily.
2424 * Well, now we have proper cfgopt txpower variables, but this still
2425 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2426 if (level_dbm <= 12) {
2427 tx_level.level = 2; /* 10 dBm */
2428 adev->tx_level_dbm = 10;
2429 } else {
2430 tx_level.level = 1; /* 15 dBm */
2431 adev->tx_level_dbm = 15;
2433 /* if (level_dbm != adev->tx_level_dbm)
2434 log(L_INIT, "acx111 firmware has specific "
2435 "power levels only: adjusted %d dBm to %d dBm!\n",
2436 level_dbm, adev->tx_level_dbm);
2438 return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
2441 static int acx_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2443 if (IS_ACX111(adev)) {
2444 return acx111_s_set_tx_level(adev, level_dbm);
2446 if (IS_PCI(adev)) {
2447 return acx100pci_s_set_tx_level(adev, level_dbm);
2449 return OK;
2452 /***********************************************************************
2453 ** acx_l_process_rxbuf
2455 ** NB: used by USB code also
2457 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2459 struct ieee80211_hdr *hdr;
2460 u16 fc, buf_len;
2461 hdr = acx_get_wlan_hdr(adev, rxbuf);
2462 fc = le16_to_cpu(hdr->frame_control);
2463 /* length of frame from control field to first byte of FCS */
2464 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2466 if (unlikely(acx_debug & L_DATA)) {
2467 printk("rx: 802.11 buf[%u]: ", buf_len);
2468 acx_dump_bytes(hdr, buf_len);
2472 acx_l_rx(adev, rxbuf);
2473 /* Now check Rx quality level, AFTER processing packet.
2474 * I tried to figure out how to map these levels to dBm
2475 * values, but for the life of me I really didn't
2476 * manage to get it. Either these values are not meant to
2477 * be expressed in dBm, or it's some pretty complicated
2478 * calculation. */
2480 #ifdef FROM_SCAN_SOURCE_ONLY
2481 /* only consider packets originating from the MAC
2482 * address of the device that's managing our BSSID.
2483 * Disable it for now, since it removes information (levels
2484 * from different peers) and slows the Rx path. *//*
2485 if (adev->ap_client && mac_is_equal(hdr->a2, adev->ap_client->address)) {
2487 #endif
2491 /***********************************************************************
2492 ** acx_l_handle_txrate_auto
2494 ** Theory of operation:
2495 ** client->rate_cap is a bitmask of rates client is capable of.
2496 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2497 ** It is set as a result of iwconfig rate N [auto]
2498 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2499 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2500 ** auto (0x00ff == 18Mbit or any lower value),
2501 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2503 ** client->rate_cur is a value for rate111 field in tx descriptor.
2504 ** It is always set to txrate_cfg sans zero or more most significant
2505 ** bits. This routine handles selection of new rate_cur value depending on
2506 ** outcome of last tx event.
2508 ** client->rate_100 is a precalculated rate value for acx100
2509 ** (we can do without it, but will need to calculate it on each tx).
2511 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2512 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2513 ** In theory you can implement it, but so far it is considered not worth doing.
2515 ** 22Mbit, of course, is PBCC always. */
2517 /* maps acx100 tx descr rate field to acx111 one */
2519 static u16 rate100to111(u8 r)
2521 switch (r) {
2522 case RATE100_1:
2523 return RATE111_1;
2524 case RATE100_2:
2525 return RATE111_2;
2526 case RATE100_5:
2527 case (RATE100_5 | RATE100_PBCC511):
2528 return RATE111_5;
2529 case RATE100_11:
2530 case (RATE100_11 | RATE100_PBCC511):
2531 return RATE111_11;
2532 case RATE100_22:
2533 return RATE111_22;
2534 default:
2535 printk("acx: unexpected acx100 txrate: %u! "
2536 "Please report\n", r);
2537 return RATE111_1;
2544 acx_i_start_xmit(struct ieee80211_hw *hw,
2545 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2547 acx_device_t *adev = ieee2adev(hw);
2548 tx_t *tx;
2549 void *txbuf;
2550 unsigned long flags;
2552 int txresult = NOT_OK;
2554 FN_ENTER;
2556 if (unlikely(!skb)) {
2557 /* indicate success */
2558 txresult = OK;
2559 goto end_no_unlock;
2562 if (unlikely(!adev)) {
2563 goto end_no_unlock;
2567 acx_lock(adev, flags);
2569 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2570 goto end;
2572 if (unlikely(!adev->initialized)) {
2573 goto end;
2576 tx = acx_l_alloc_tx(adev);
2578 if (unlikely(!tx)) {
2579 printk_ratelimited("%s: start_xmit: txdesc ring is full, "
2580 "dropping tx\n", wiphy_name(adev->ieee->wiphy));
2581 txresult = NOT_OK;
2582 goto end;
2585 txbuf = acx_l_get_txbuf(adev, tx);
2587 if (unlikely(!txbuf)) {
2588 /* Card was removed */
2589 txresult = NOT_OK;
2590 acx_l_dealloc_tx(adev, tx);
2591 goto end;
2593 memcpy(txbuf, skb->data, skb->len);
2595 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2597 txresult = OK;
2598 adev->stats.tx_packets++;
2599 adev->stats.tx_bytes += skb->len;
2601 end:
2602 acx_unlock(adev, flags);
2604 end_no_unlock:
2606 FN_EXIT1(txresult);
2607 return txresult;
2609 /***********************************************************************
2610 ** acx_l_update_ratevector
2612 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2614 const u8 acx_bitpos2ratebyte[] = {
2615 DOT11RATEBYTE_1,
2616 DOT11RATEBYTE_2,
2617 DOT11RATEBYTE_5_5,
2618 DOT11RATEBYTE_6_G,
2619 DOT11RATEBYTE_9_G,
2620 DOT11RATEBYTE_11,
2621 DOT11RATEBYTE_12_G,
2622 DOT11RATEBYTE_18_G,
2623 DOT11RATEBYTE_22,
2624 DOT11RATEBYTE_24_G,
2625 DOT11RATEBYTE_36_G,
2626 DOT11RATEBYTE_48_G,
2627 DOT11RATEBYTE_54_G,
2630 void acx_l_update_ratevector(acx_device_t * adev)
2632 u16 bcfg = adev->rate_basic;
2633 u16 ocfg = adev->rate_oper;
2634 u8 *supp = adev->rate_supported;
2635 const u8 *dot11 = acx_bitpos2ratebyte;
2637 FN_ENTER;
2639 while (ocfg) {
2640 if (ocfg & 1) {
2641 *supp = *dot11;
2642 if (bcfg & 1) {
2643 *supp |= 0x80;
2645 supp++;
2647 dot11++;
2648 ocfg >>= 1;
2649 bcfg >>= 1;
2651 adev->rate_supported_len = supp - adev->rate_supported;
2652 if (acx_debug & L_ASSOC) {
2653 printk("new ratevector: ");
2654 acx_dump_bytes(adev->rate_supported, adev->rate_supported_len);
2656 FN_EXIT0;
2659 /***********************************************************************
2660 ** acx_i_timer
2662 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2664 ** Obvious
2666 void acx_i_timer(unsigned long address)
2668 unsigned long flags;
2669 acx_device_t *adev = (acx_device_t *) address;
2671 FN_ENTER;
2673 acx_lock(adev, flags);
2675 FIXME();
2676 /* We need calibration and stats gather tasks to perform here */
2678 acx_unlock(adev, flags);
2680 FN_EXIT0;
2684 /***********************************************************************
2685 ** acx_set_timer
2687 ** Sets the 802.11 state management timer's timeout.
2689 ** Linux derived
2691 void acx_set_timer(acx_device_t * adev, int timeout_us)
2693 FN_ENTER;
2695 log(L_DEBUG | L_IRQ, "%s(%u ms)\n", __func__, timeout_us / 1000);
2696 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2697 printk("attempt to set the timer "
2698 "when the card interface is not up!\n");
2699 goto end;
2702 /* first check if the timer was already initialized, THEN modify it */
2703 if (adev->mgmt_timer.function) {
2704 mod_timer(&adev->mgmt_timer,
2705 jiffies + (timeout_us * HZ / 1000000));
2707 end:
2708 FN_EXIT0;
2711 /** acx_plcp_get_bitrate_cck
2713 ** Obvious
2715 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2717 switch (plcp) {
2718 case 0x0A:
2719 return ACX_CCK_RATE_1MB;
2720 case 0x14:
2721 return ACX_CCK_RATE_2MB;
2722 case 0x37:
2723 return ACX_CCK_RATE_5MB;
2724 case 0x6E:
2725 return ACX_CCK_RATE_11MB;
2727 return 0;
2730 /* Extract the bitrate out of an OFDM PLCP header. */
2731 /** Obvious **/
2732 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2734 switch (plcp & 0xF) {
2735 case 0xB:
2736 return ACX_OFDM_RATE_6MB;
2737 case 0xF:
2738 return ACX_OFDM_RATE_9MB;
2739 case 0xA:
2740 return ACX_OFDM_RATE_12MB;
2741 case 0xE:
2742 return ACX_OFDM_RATE_18MB;
2743 case 0x9:
2744 return ACX_OFDM_RATE_24MB;
2745 case 0xD:
2746 return ACX_OFDM_RATE_36MB;
2747 case 0x8:
2748 return ACX_OFDM_RATE_48MB;
2749 case 0xC:
2750 return ACX_OFDM_RATE_54MB;
2752 return 0;
2756 /***********************************************************************
2757 ** acx_l_rx
2759 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2760 ** buffer and feeds it to the network stack via netif_rx().
2762 ** Look to bcm43xx or p54
2764 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2767 struct ieee80211_rx_status* status = &adev->rx_status;
2768 struct ieee80211_hdr *w_hdr;
2769 int buflen;
2770 FN_ENTER;
2772 if (likely(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2773 struct sk_buff *skb;
2774 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2775 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2776 skb = dev_alloc_skb(buflen + 2);
2777 skb_reserve(skb, 2);
2778 skb_put(skb, buflen);
2779 memcpy(skb->data, w_hdr, buflen);
2781 // memset(&status, 0, sizeof(status));
2783 if (likely(skb)) {
2784 adev->acx_stats.last_rx = jiffies;
2785 status->mactime = rxbuf->time;
2786 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2787 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr);
2788 status->flag = 0;
2789 status->rate = rxbuf->phy_plcp_signal;
2790 status->antenna = 1;
2792 #ifndef OLD_QUALITY
2793 qual = acx_signal_determine_quality(adev->wstats.qual.level,
2794 adev->wstats.qual.noise);
2795 #else
2796 qual = (adev->wstats.qual.noise <= 100) ?
2797 100 - adev->wstats.qual.noise : 0;
2798 #endif
2799 adev->wstats.qual.qual = qual;
2800 adev->wstats.qual.updated = 7; *//* all 3 indicators updated */
2802 #ifdef FROM_SCAN_SOURCE_ONLY
2804 #endif
2806 if (rxbuf->phy_stat_baseband & (1 << 3)) /* Uses OFDM */
2808 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2809 } else
2811 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2813 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2814 adev->stats.rx_packets++;
2815 adev->stats.rx_bytes += skb->len;
2818 FN_EXIT0;
2823 /***********************************************************************
2824 ** acx_s_read_fw
2826 ** Loads a firmware image
2828 ** Returns:
2829 ** 0 unable to load file
2830 ** pointer to firmware success
2832 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2833 u32 * size)
2835 firmware_image_t *res;
2836 const struct firmware *fw_entry;
2838 res = NULL;
2839 log(L_INIT, "requesting firmware image '%s'\n", file);
2840 if (!request_firmware(&fw_entry, file, dev)) {
2841 *size = 8;
2842 if (fw_entry->size >= 8)
2843 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2844 if (fw_entry->size != *size) {
2845 printk("acx: firmware size does not match "
2846 "firmware header: %d != %d, "
2847 "aborting fw upload\n",
2848 (int)fw_entry->size, (int)*size);
2849 goto release_ret;
2851 res = vmalloc(*size);
2852 if (!res) {
2853 printk("acx: no memory for firmware "
2854 "(%u bytes)\n", *size);
2855 goto release_ret;
2857 memcpy(res, fw_entry->data, fw_entry->size);
2858 release_ret:
2859 release_firmware(fw_entry);
2860 return res;
2862 printk("acx: firmware image '%s' was not provided. "
2863 "Check your hotplug scripts\n", file);
2865 /* checksum will be verified in write_fw, so don't bother here */
2866 return res;
2870 /***********************************************************************
2871 ** acx_s_set_wepkey
2873 static void acx100_s_set_wepkey(acx_device_t * adev)
2875 ie_dot11WEPDefaultKey_t dk;
2876 int i;
2878 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2879 if (adev->wep_keys[i].size != 0) {
2880 log(L_INIT, "setting WEP key: %d with "
2881 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2882 dk.action = 1;
2883 dk.keySize = adev->wep_keys[i].size;
2884 dk.defaultKeyNum = i;
2885 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2886 acx_s_configure(adev, &dk,
2887 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
2892 static void acx111_s_set_wepkey(acx_device_t * adev)
2894 acx111WEPDefaultKey_t dk;
2895 int i;
2897 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2898 if (adev->wep_keys[i].size != 0) {
2899 log(L_INIT, "setting WEP key: %d with "
2900 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2901 memset(&dk, 0, sizeof(dk));
2902 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2903 dk.keySize = adev->wep_keys[i].size;
2905 /* are these two lines necessary? */
2906 dk.type = 0; /* default WEP key */
2907 dk.index = 0; /* ignored when setting default key */
2909 dk.defaultKeyNum = i;
2910 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2911 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2912 sizeof(dk));
2916 /* Obvious */
2917 static void acx_s_set_wepkey(acx_device_t * adev)
2919 if (IS_ACX111(adev))
2920 acx111_s_set_wepkey(adev);
2921 else
2922 acx100_s_set_wepkey(adev);
2926 /***********************************************************************
2927 ** acx100_s_init_wep
2929 ** FIXME: this should probably be moved into the new card settings
2930 ** management, but since we're also modifying the memory map layout here
2931 ** due to the WEP key space we want, we should take care...
2933 static int acx100_s_init_wep(acx_device_t * adev)
2935 acx100_ie_wep_options_t options;
2936 ie_dot11WEPDefaultKeyID_t dk;
2937 acx_ie_memmap_t pt;
2938 int res = NOT_OK;
2940 FN_ENTER;
2942 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2943 goto fail;
2946 log(L_DEBUG, "CodeEnd:%X\n", pt.CodeEnd);
2948 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2949 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2951 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2952 goto fail;
2955 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2956 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2957 options.WEPOption = 0x00;
2959 log(L_ASSOC, "writing WEP options\n");
2960 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
2962 acx100_s_set_wepkey(adev);
2964 if (adev->wep_keys[adev->wep_current_index].size != 0) {
2965 log(L_ASSOC, "setting active default WEP key number: %d\n",
2966 adev->wep_current_index);
2967 dk.KeyID = adev->wep_current_index;
2968 acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
2970 /* FIXME!!! wep_key_struct is filled nowhere! But adev
2971 * is initialized to 0, and we don't REALLY need those keys either */
2972 /* for (i = 0; i < 10; i++) {
2973 if (adev->wep_key_struct[i].len != 0) {
2974 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
2975 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
2976 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
2977 wep_mgmt.Action = cpu_to_le16(1);
2978 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
2979 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
2980 adev->wep_key_struct[i].index = i;
2986 /* now retrieve the updated WEPCacheEnd pointer... */
2987 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2988 printk("%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
2989 wiphy_name(adev->ieee->wiphy));
2990 goto fail;
2992 /* ...and tell it to start allocating templates at that location */
2993 /* (no endianness conversion needed) */
2994 pt.PacketTemplateStart = pt.WEPCacheEnd;
2996 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2997 printk("%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
2998 wiphy_name(adev->ieee->wiphy));
2999 goto fail;
3001 res = OK;
3003 fail:
3004 FN_EXIT1(res);
3005 return res;
3009 static int
3010 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
3011 unsigned int cmd)
3013 int res;
3014 union {
3015 acx_template_nullframe_t null;
3016 acx_template_beacon_t b;
3017 acx_template_tim_t tim;
3018 acx_template_probereq_t preq;
3019 acx_template_proberesp_t presp;
3020 } templ;
3022 memset(&templ, 0, len);
3023 templ.null.size = cpu_to_le16(len - 2);
3024 res = acx_s_issue_cmd(adev, cmd, &templ, len);
3025 return res;
3028 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
3030 return acx_s_init_max_template_generic(adev,
3031 sizeof(acx_template_nullframe_t),
3032 ACX1xx_CMD_CONFIG_NULL_DATA);
3035 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
3037 return acx_s_init_max_template_generic(adev,
3038 sizeof(acx_template_beacon_t),
3039 ACX1xx_CMD_CONFIG_BEACON);
3042 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
3044 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
3045 ACX1xx_CMD_CONFIG_TIM);
3048 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
3050 return acx_s_init_max_template_generic(adev,
3051 sizeof(acx_template_proberesp_t),
3052 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
3055 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
3057 return acx_s_init_max_template_generic(adev,
3058 sizeof(acx_template_probereq_t),
3059 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
3062 /***********************************************************************
3063 ** acx_s_set_tim_template
3065 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
3066 ** by calling this function
3067 ** (it can be done by irq handler on each DTIM irq or by timer...)
3069 [802.11 7.3.2.6] TIM information element:
3070 - 1 EID
3071 - 1 Length
3072 1 1 DTIM Count
3073 indicates how many beacons (including this) appear before next DTIM
3074 (0=this one is a DTIM)
3075 2 1 DTIM Period
3076 number of beacons between successive DTIMs
3077 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
3078 3 1 Bitmap Control
3079 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
3080 set to 1 in TIM elements with a value of 0 in the DTIM Count field
3081 when one or more broadcast or multicast frames are buffered at the AP.
3082 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
3083 4 n Partial Virtual Bitmap
3084 Visible part of traffic-indication bitmap.
3085 Full bitmap consists of 2008 bits (251 octets) such that bit number N
3086 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
3087 in octet number N/8 where the low-order bit of each octet is bit0,
3088 and the high order bit is bit7.
3089 Each set bit in virtual bitmap corresponds to traffic buffered by AP
3090 for a specific station (with corresponding AID?).
3091 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
3092 Bitmap Offset is a number of skipped zero octets (see above).
3093 'Missing' octets at the tail are also assumed to be zero.
3094 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
3095 This means that traffic-indication bitmap is:
3096 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
3097 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
3099 static int acx_s_set_tim_template(acx_device_t * adev)
3101 /* For now, configure smallish test bitmap, all zero ("no pending data") */
3102 enum { bitmap_size = 5 };
3104 acx_template_tim_t t;
3105 int result;
3107 FN_ENTER;
3109 memset(&t, 0, sizeof(t));
3110 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3111 t.tim_eid = WLAN_EID_TIM;
3112 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3113 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3114 FN_EXIT1(result);
3115 return result;
3121 #if POWER_SAVE_80211
3122 /***********************************************************************
3123 ** acx_s_set_null_data_template
3125 static int acx_s_set_null_data_template(acx_device_t * adev)
3127 struct acx_template_nullframe b;
3128 int result;
3130 FN_ENTER;
3132 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3134 b.size = cpu_to_le16(sizeof(b) - 2);
3135 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3136 b.hdr.dur = 0;
3137 MAC_BCAST(b.hdr.a1);
3138 MAC_COPY(b.hdr.a2, adev->dev_addr);
3139 MAC_COPY(b.hdr.a3, adev->bssid);
3140 b.hdr.seq = 0;
3142 result =
3143 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3145 FN_EXIT1(result);
3146 return result;
3148 #endif
3155 /***********************************************************************
3156 ** acx_s_init_packet_templates()
3158 ** NOTE: order is very important here, to have a correct memory layout!
3159 ** init templates: max Probe Request (station mode), max NULL data,
3160 ** max Beacon, max TIM, max Probe Response.
3162 static int acx_s_init_packet_templates(acx_device_t * adev)
3164 acx_ie_memmap_t mm; /* ACX100 only */
3165 int result = NOT_OK;
3167 FN_ENTER;
3169 log(L_DEBUG | L_INIT, "initializing max packet templates\n");
3171 if (OK != acx_s_init_max_probe_request_template(adev))
3172 goto failed;
3174 if (OK != acx_s_init_max_null_data_template(adev))
3175 goto failed;
3177 if (OK != acx_s_init_max_beacon_template(adev))
3178 goto failed;
3180 if (OK != acx_s_init_max_tim_template(adev))
3181 goto failed;
3183 if (OK != acx_s_init_max_probe_response_template(adev))
3184 goto failed;
3186 if (IS_ACX111(adev)) {
3187 /* ACX111 doesn't need the memory map magic below,
3188 * and the other templates will be set later (acx_start) */
3189 result = OK;
3190 goto success;
3193 /* ACX100 will have its TIM template set,
3194 * and we also need to update the memory map */
3196 if (OK != acx_s_set_tim_template(adev))
3197 goto failed_acx100;
3199 log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3201 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3202 goto failed_acx100;
3204 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3205 if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3206 goto failed_acx100;
3208 result = OK;
3209 goto success;
3211 failed_acx100:
3212 log(L_DEBUG | L_INIT,
3213 /* "cb=0x%X\n" */
3214 "ACXMemoryMap:\n"
3215 ".CodeStart=0x%X\n"
3216 ".CodeEnd=0x%X\n"
3217 ".WEPCacheStart=0x%X\n"
3218 ".WEPCacheEnd=0x%X\n"
3219 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3220 /* len, */
3221 le32_to_cpu(mm.CodeStart),
3222 le32_to_cpu(mm.CodeEnd),
3223 le32_to_cpu(mm.WEPCacheStart),
3224 le32_to_cpu(mm.WEPCacheEnd),
3225 le32_to_cpu(mm.PacketTemplateStart),
3226 le32_to_cpu(mm.PacketTemplateEnd));
3228 failed:
3229 printk("%s: %s() FAILED\n", wiphy_name(adev->ieee->wiphy), __func__);
3231 success:
3232 FN_EXIT1(result);
3233 return result;
3238 /***********************************************************************
3239 ** acx_s_init_mac
3241 int acx_s_init_mac(acx_device_t * adev)
3243 int result = NOT_OK;
3245 FN_ENTER;
3247 if (IS_ACX111(adev)) {
3248 adev->ie_len = acx111_ie_len;
3249 adev->ie_len_dot11 = acx111_ie_len_dot11;
3250 } else {
3251 adev->ie_len = acx100_ie_len;
3252 adev->ie_len_dot11 = acx100_ie_len_dot11;
3255 if (IS_PCI(adev)) {
3256 adev->memblocksize = 256; /* 256 is default */
3257 /* try to load radio for both ACX100 and ACX111, since both
3258 * chips have at least some firmware versions making use of an
3259 * external radio module */
3260 acxpci_s_upload_radio(adev);
3261 } else {
3262 adev->memblocksize = 128;
3265 if (IS_ACX111(adev)) {
3266 /* for ACX111, the order is different from ACX100
3267 1. init packet templates
3268 2. create station context and create dma regions
3269 3. init wep default keys
3271 if (OK != acx_s_init_packet_templates(adev))
3272 goto fail;
3273 if (OK != acx111_s_create_dma_regions(adev)) {
3274 printk("%s: acx111_create_dma_regions FAILED\n",
3275 wiphy_name(adev->ieee->wiphy));
3276 goto fail;
3278 } else {
3279 if (OK != acx100_s_init_wep(adev))
3280 goto fail;
3281 if (OK != acx_s_init_packet_templates(adev))
3282 goto fail;
3283 if (OK != acx100_s_create_dma_regions(adev)) {
3284 printk("%s: acx100_create_dma_regions FAILED\n",
3285 wiphy_name(adev->ieee->wiphy));
3286 goto fail;
3290 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3291 result = OK;
3293 fail:
3294 if (result)
3295 printk("acx: init_mac() FAILED\n");
3296 FN_EXIT1(result);
3297 return result;
3302 #if POWER_SAVE_80211
3303 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3305 /* merge both structs in a union to be able to have common code */
3306 union {
3307 acx111_ie_powersave_t acx111;
3308 acx100_ie_powersave_t acx100;
3309 } pm;
3311 /* change 802.11 power save mode settings */
3312 log(L_INIT, "updating 802.11 power save mode settings: "
3313 "wakeup_cfg 0x%02X, listen interval %u, "
3314 "options 0x%02X, hangover period %u, "
3315 "enhanced_ps_transition_time %u\n",
3316 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3317 adev->ps_options, adev->ps_hangover_period,
3318 adev->ps_enhanced_transition_time);
3319 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3320 log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, "
3321 "listen interval %u, options 0x%02X, "
3322 "hangover period %u, "
3323 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3324 pm.acx111.wakeup_cfg,
3325 pm.acx111.listen_interval,
3326 pm.acx111.options,
3327 pm.acx111.hangover_period,
3328 IS_ACX111(adev) ?
3329 pm.acx111.enhanced_ps_transition_time
3330 : pm.acx100.enhanced_ps_transition_time,
3331 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3332 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3333 pm.acx111.listen_interval = adev->ps_listen_interval;
3334 pm.acx111.options = adev->ps_options;
3335 pm.acx111.hangover_period = adev->ps_hangover_period;
3336 if (IS_ACX111(adev)) {
3337 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3338 pm.acx111.enhanced_ps_transition_time =
3339 cpu_to_le32(adev->ps_enhanced_transition_time);
3340 } else {
3341 pm.acx100.enhanced_ps_transition_time =
3342 cpu_to_le16(adev->ps_enhanced_transition_time);
3344 acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT);
3345 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3346 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3347 acx_s_mwait(40);
3348 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3349 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3350 log(L_INIT, "power save mode change %s\n",
3351 (pm.acx111.
3352 wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful");
3353 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3354 * that power save mode change was successful. */
3355 /* FIXME: we shouldn't trigger a scan immediately after
3356 * fiddling with power save mode (since the firmware is sending
3357 * a NULL frame then). */
3359 #endif
3362 /***********************************************************************
3363 ** acx_s_update_card_settings
3365 ** Applies accumulated changes in various adev->xxxx members
3366 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3367 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3369 void acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
3371 unsigned mask;
3373 unsigned int i;
3375 for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
3376 if (acx_reg_domain_ids[i] == adev->reg_dom_id)
3377 break;
3379 if (sizeof(acx_reg_domain_ids) == i) {
3380 log(L_INIT, "Invalid or unsupported regulatory domain"
3381 " 0x%02X specified, falling back to FCC (USA)!"
3382 " Please report if this sounds fishy!\n",
3383 adev->reg_dom_id);
3384 i = 0;
3385 adev->reg_dom_id = acx_reg_domain_ids[i];
3387 /* since there was a mismatch, we need to force updating */
3388 do_set = 1;
3391 if (do_set) {
3392 acx_ie_generic_t dom;
3393 dom.m.bytes[0] = adev->reg_dom_id;
3394 acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3397 adev->reg_dom_chanmask = reg_domain_channel_masks[i];
3399 mask = (1 << (adev->channel - 1));
3400 if (!(adev->reg_dom_chanmask & mask)) {
3401 /* hmm, need to adjust our channel to reside within domain */
3402 mask = 1;
3403 for (i = 1; i <= 14; i++) {
3404 if (adev->reg_dom_chanmask & mask) {
3405 printk("%s: adjusting selected channel from %d "
3406 "to %d due to new regulatory domain\n",
3407 wiphy_name(adev->ieee->wiphy), adev->channel, i);
3408 adev->channel = i;
3409 break;
3411 mask <<= 1;
3416 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3418 u32 feature1, feature2;
3420 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3421 printk("%s: invalid sensitivity setting (1..3), "
3422 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3423 adev->sensitivity = 1;
3425 acx111_s_get_feature_config(adev, &feature1, &feature2);
3426 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3427 if (adev->sensitivity > 1)
3428 SET_BIT(feature1, FEATURE1_LOW_RX);
3429 if (adev->sensitivity > 2)
3430 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3431 acx111_s_feature_set(adev, feature1, feature2);
3435 void acx_s_update_card_settings(acx_device_t *adev)
3437 unsigned long flags;
3438 unsigned int start_scan = 0;
3439 int i;
3441 FN_ENTER;
3443 log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3444 adev->get_mask, adev->set_mask);
3446 /* Track dependencies betweed various settings */
3448 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3449 log(L_INIT, "important setting has been changed. "
3450 "Need to update packet templates, too\n");
3451 SET_BIT(adev->set_mask, SET_TEMPLATES);
3453 if (adev->set_mask & GETSET_CHANNEL) {
3454 /* This will actually tune RX/TX to the channel */
3455 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3456 switch (adev->mode) {
3457 case ACX_MODE_0_ADHOC:
3458 case ACX_MODE_3_AP:
3459 /* Beacons contain channel# - update them */
3460 SET_BIT(adev->set_mask, SET_TEMPLATES);
3463 switch (adev->mode) {
3464 case ACX_MODE_0_ADHOC:
3465 case ACX_MODE_2_STA:
3466 start_scan = 1;
3470 /* Apply settings */
3473 if (adev->get_mask & GETSET_STATION_ID) {
3474 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3475 const u8 *paddr;
3477 acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3478 paddr = &stationID[4];
3479 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3480 for (i = 0; i < ETH_ALEN; i++) {
3481 /* we copy the MAC address (reversed in
3482 * the card) to the netdevice's MAC
3483 * address, and on ifup it will be
3484 * copied into iwadev->dev_addr */
3485 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3487 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3488 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3491 if (adev->get_mask & GETSET_SENSITIVITY) {
3492 if ((RADIO_RFMD_11 == adev->radio_type)
3493 || (RADIO_MAXIM_0D == adev->radio_type)
3494 || (RADIO_RALINK_15 == adev->radio_type)) {
3495 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3496 } else {
3497 log(L_INIT, "don't know how to get sensitivity "
3498 "for radio type 0x%02X\n", adev->radio_type);
3499 adev->sensitivity = 0;
3501 log(L_INIT, "got sensitivity value %u\n", adev->sensitivity);
3503 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3506 if (adev->get_mask & GETSET_ANTENNA) {
3507 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3509 memset(antenna, 0, sizeof(antenna));
3510 acx_s_interrogate(adev, antenna,
3511 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3512 adev->antenna = antenna[4];
3513 log(L_INIT, "got antenna value 0x%02X\n", adev->antenna);
3514 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3517 if (adev->get_mask & GETSET_ED_THRESH) {
3518 if (IS_ACX100(adev)) {
3519 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3521 memset(ed_threshold, 0, sizeof(ed_threshold));
3522 acx_s_interrogate(adev, ed_threshold,
3523 ACX100_IE_DOT11_ED_THRESHOLD);
3524 adev->ed_threshold = ed_threshold[4];
3525 } else {
3526 log(L_INIT, "acx111 doesn't support ED\n");
3527 adev->ed_threshold = 0;
3529 log(L_INIT, "got Energy Detect (ED) threshold %u\n",
3530 adev->ed_threshold);
3531 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3534 if (adev->get_mask & GETSET_CCA) {
3535 if (IS_ACX100(adev)) {
3536 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3538 memset(cca, 0, sizeof(adev->cca));
3539 acx_s_interrogate(adev, cca,
3540 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3541 adev->cca = cca[4];
3542 } else {
3543 log(L_INIT, "acx111 doesn't support CCA\n");
3544 adev->cca = 0;
3546 log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n",
3547 adev->cca);
3548 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3551 if (adev->get_mask & GETSET_REG_DOMAIN) {
3552 acx_ie_generic_t dom;
3554 acx_s_interrogate(adev, &dom,
3555 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3556 adev->reg_dom_id = dom.m.bytes[0];
3557 acx_s_set_sane_reg_domain(adev, 0);
3558 log(L_INIT, "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3559 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3562 if (adev->set_mask & GETSET_STATION_ID) {
3563 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3564 u8 *paddr;
3566 paddr = &stationID[4];
3567 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3568 for (i = 0; i < ETH_ALEN; i++) {
3569 /* copy the MAC address we obtained when we noticed
3570 * that the ethernet iface's MAC changed
3571 * to the card (reversed in
3572 * the card!) */
3573 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3575 acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3576 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3579 if (adev->set_mask & SET_STA_LIST) {
3580 acx_lock(adev, flags);
3581 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3582 acx_unlock(adev, flags);
3584 if (adev->set_mask & SET_RATE_FALLBACK) {
3585 u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
3587 /* configure to not do fallbacks when not in auto rate mode */
3588 rate[4] =
3589 (adev->
3590 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3591 log(L_INIT, "updating Tx fallback to %u retries\n", rate[4]);
3592 acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK);
3593 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3595 if (adev->set_mask & GETSET_TXPOWER) {
3596 log(L_INIT, "updating transmit power: %u dBm\n",
3597 adev->tx_level_dbm);
3598 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3599 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3602 if (adev->set_mask & GETSET_SENSITIVITY) {
3603 log(L_INIT, "updating sensitivity value: %u\n",
3604 adev->sensitivity);
3605 switch (adev->radio_type) {
3606 case RADIO_RFMD_11:
3607 case RADIO_MAXIM_0D:
3608 case RADIO_RALINK_15:
3609 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3610 break;
3611 case RADIO_RADIA_16:
3612 case RADIO_UNKNOWN_17:
3613 acx111_s_sens_radio_16_17(adev);
3614 break;
3615 default:
3616 log(L_INIT, "don't know how to modify sensitivity "
3617 "for radio type 0x%02X\n", adev->radio_type);
3619 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3622 if (adev->set_mask & GETSET_ANTENNA) {
3623 /* antenna */
3624 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3626 memset(antenna, 0, sizeof(antenna));
3627 antenna[4] = adev->antenna;
3628 log(L_INIT, "updating antenna value: 0x%02X\n", adev->antenna);
3629 acx_s_configure(adev, &antenna,
3630 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3631 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3634 if (adev->set_mask & GETSET_ED_THRESH) {
3635 /* ed_threshold */
3636 log(L_INIT, "updating Energy Detect (ED) threshold: %u\n",
3637 adev->ed_threshold);
3638 if (IS_ACX100(adev)) {
3639 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3641 memset(ed_threshold, 0, sizeof(ed_threshold));
3642 ed_threshold[4] = adev->ed_threshold;
3643 acx_s_configure(adev, &ed_threshold,
3644 ACX100_IE_DOT11_ED_THRESHOLD);
3645 } else
3646 log(L_INIT, "acx111 doesn't support ED!\n");
3647 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3650 if (adev->set_mask & GETSET_CCA) {
3651 /* CCA value */
3652 log(L_INIT, "updating Channel Clear Assessment "
3653 "(CCA) value: 0x%02X\n", adev->cca);
3654 if (IS_ACX100(adev)) {
3655 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3657 memset(cca, 0, sizeof(cca));
3658 cca[4] = adev->cca;
3659 acx_s_configure(adev, &cca,
3660 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3661 } else
3662 log(L_INIT, "acx111 doesn't support CCA!\n");
3663 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3666 if (adev->set_mask & GETSET_LED_POWER) {
3667 /* Enable Tx */
3668 log(L_INIT, "updating power LED status: %u\n", adev->led_power);
3670 acx_lock(adev, flags);
3671 if (IS_PCI(adev))
3672 acxpci_l_power_led(adev, adev->led_power);
3673 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3674 acx_unlock(adev, flags);
3677 if (adev->set_mask & GETSET_POWER_80211) {
3678 #if POWER_SAVE_80211
3679 acx_s_update_80211_powersave_mode(adev);
3680 #endif
3681 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3684 if (adev->set_mask & GETSET_CHANNEL) {
3685 /* channel */
3686 log(L_INIT, "updating channel to: %u\n", adev->channel);
3687 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3690 if (adev->set_mask & GETSET_TX) {
3691 /* set Tx */
3692 log(L_INIT, "updating: %s Tx\n",
3693 adev->tx_disabled ? "disable" : "enable");
3694 if (adev->tx_disabled)
3695 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3696 else {
3697 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3698 &adev->channel, 1);
3699 FIXME();
3700 /* This needs to be keyed on WEP? */
3701 acx111_s_feature_on(adev, 0,
3702 FEATURE2_NO_TXCRYPT |
3703 FEATURE2_SNIFFER);
3704 acx_wake_queue(adev->ieee, NULL);
3706 CLEAR_BIT(adev->set_mask, GETSET_TX);
3709 if (adev->set_mask & GETSET_RX) {
3710 /* Enable Rx */
3711 log(L_INIT, "updating: enable Rx on channel: %u\n",
3712 adev->channel);
3713 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3714 CLEAR_BIT(adev->set_mask, GETSET_RX);
3717 if (adev->set_mask & GETSET_RETRY) {
3718 u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
3719 u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
3721 log(L_INIT,
3722 "updating short retry limit: %u, long retry limit: %u\n",
3723 adev->short_retry, adev->long_retry);
3724 short_retry[0x4] = adev->short_retry;
3725 long_retry[0x4] = adev->long_retry;
3726 acx_s_configure(adev, &short_retry,
3727 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
3728 acx_s_configure(adev, &long_retry,
3729 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
3730 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3733 if (adev->set_mask & SET_MSDU_LIFETIME) {
3734 u8 xmt_msdu_lifetime[4 +
3735 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3737 log(L_INIT, "updating tx MSDU lifetime: %u\n",
3738 adev->msdu_lifetime);
3739 *(u32 *) & xmt_msdu_lifetime[4] =
3740 cpu_to_le32((u32) adev->msdu_lifetime);
3741 acx_s_configure(adev, &xmt_msdu_lifetime,
3742 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
3743 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3746 if (adev->set_mask & GETSET_REG_DOMAIN) {
3747 log(L_INIT, "updating regulatory domain: 0x%02X\n",
3748 adev->reg_dom_id);
3749 acx_s_set_sane_reg_domain(adev, 1);
3750 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3752 if (adev->set_mask & GETSET_MODE ) {
3753 acx111_s_feature_on(adev, 0,
3754 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3755 switch (adev->mode) {
3756 case ACX_MODE_3_AP:
3757 adev->aid = 0;
3758 //acx111_s_feature_off(adev, 0,
3759 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3760 MAC_COPY(adev->bssid,adev->dev_addr);
3761 acx_s_cmd_join_bssid(adev,adev->dev_addr);
3762 break;
3763 case ACX_MODE_MONITOR:
3764 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3765 break;
3766 case ACX_MODE_0_ADHOC:
3767 case ACX_MODE_2_STA:
3768 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3769 break;
3770 default:
3771 break;
3773 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3775 if (adev->set_mask & SET_TEMPLATES) {
3776 switch (adev->mode)
3778 case ACX_MODE_3_AP:
3779 acx_s_set_tim_template(adev);
3780 break;
3781 default:
3782 break;
3784 if (adev->beacon_cache)
3786 acx_s_set_beacon_template(adev, adev->beacon_cache);
3787 dev_kfree_skb(adev->beacon_cache);
3788 adev->beacon_cache = NULL;
3790 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3793 if (adev->set_mask & SET_RXCONFIG) {
3794 acx_s_initialize_rx_config(adev);
3795 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3798 if (adev->set_mask & GETSET_RESCAN) {
3799 /* switch (adev->mode) {
3800 case ACX_MODE_0_ADHOC:
3801 case ACX_MODE_2_STA:
3802 start_scan = 1;
3803 break;
3805 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3808 if (adev->set_mask & GETSET_WEP) {
3809 /* encode */
3811 ie_dot11WEPDefaultKeyID_t dkey;
3812 #ifdef DEBUG_WEP
3813 struct {
3814 u16 type;
3815 u16 len;
3816 u8 val;
3817 } ACX_PACKED keyindic;
3818 #endif
3819 log(L_INIT, "updating WEP key settings\n");
3821 acx_s_set_wepkey(adev);
3822 if (adev->wep_enabled) {
3823 dkey.KeyID = adev->wep_current_index;
3824 log(L_INIT, "setting WEP key %u as default\n",
3825 dkey.KeyID);
3826 acx_s_configure(adev, &dkey,
3827 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
3828 #ifdef DEBUG_WEP
3829 keyindic.val = 3;
3830 acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
3831 #endif
3834 // start_scan = 1;
3835 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3838 if (adev->set_mask & SET_WEP_OPTIONS) {
3839 acx100_ie_wep_options_t options;
3841 if (IS_ACX111(adev)) {
3842 log(L_DEBUG,
3843 "setting WEP Options for acx111 is not supported\n");
3844 } else {
3845 log(L_INIT, "setting WEP Options\n");
3847 /* let's choose maximum setting: 4 default keys,
3848 * plus 10 other keys: */
3849 options.NumKeys =
3850 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3851 /* don't decrypt default key only,
3852 * don't override decryption: */
3853 options.WEPOption = 0;
3854 if (adev->mode == ACX_MODE_3_AP) {
3855 /* don't decrypt default key only,
3856 * override decryption mechanism: */
3857 options.WEPOption = 2;
3860 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3862 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3866 /* debug, rate, and nick don't need any handling */
3867 /* what about sniffing mode?? */
3869 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3870 adev->get_mask, adev->set_mask);
3872 /* end: */
3873 FN_EXIT0;
3876 #if 0
3877 /***********************************************************************
3878 ** acx_e_after_interrupt_task
3880 static int acx_s_recalib_radio(acx_device_t * adev)
3882 if (IS_ACX111(adev)) {
3883 acx111_cmd_radiocalib_t cal;
3885 /* automatic recalibration, choose all methods: */
3886 cal.methods = cpu_to_le32(0x8000000f);
3887 /* automatic recalibration every 60 seconds (value in TUs)
3888 * I wonder what the firmware default here is? */
3889 cal.interval = cpu_to_le32(58594);
3890 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3891 &cal, sizeof(cal),
3892 CMD_TIMEOUT_MS(100));
3893 } else {
3894 /* On ACX100, we need to recalibrate the radio
3895 * by issuing a GETSET_TX|GETSET_RX */
3896 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3897 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3898 (OK ==
3899 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3900 &adev->channel, 1))
3901 && (OK ==
3902 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3903 &adev->channel, 1)))
3904 return OK;
3905 return NOT_OK;
3908 #endif // if 0
3909 #if 0
3910 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3912 int res;
3914 /* this helps with ACX100 at least;
3915 * hopefully ACX111 also does a
3916 * recalibration here */
3918 /* clear flag beforehand, since we want to make sure
3919 * it's cleared; then only set it again on specific circumstances */
3920 CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3922 /* better wait a bit between recalibrations to
3923 * prevent overheating due to torturing the card
3924 * into working too long despite high temperature
3925 * (just a safety measure) */
3926 if (adev->recalib_time_last_success
3927 && time_before(jiffies, adev->recalib_time_last_success
3928 + RECALIB_PAUSE * 60 * HZ)) {
3929 if (adev->recalib_msg_ratelimit <= 4) {
3930 printk("%s: less than " STRING(RECALIB_PAUSE)
3931 " minutes since last radio recalibration, "
3932 "not recalibrating (maybe card is too hot?)\n",
3933 wiphy_name(adev->ieee->wiphy));
3934 adev->recalib_msg_ratelimit++;
3935 if (adev->recalib_msg_ratelimit == 5)
3936 printk("disabling above message until next recalib\n");
3938 return;
3941 adev->recalib_msg_ratelimit = 0;
3943 /* note that commands sometimes fail (card busy),
3944 * so only clear flag if we were fully successful */
3945 res = acx_s_recalib_radio(adev);
3946 if (res == OK) {
3947 printk("%s: successfully recalibrated radio\n",
3948 wiphy_name(adev->ieee->wiphy));
3949 adev->recalib_time_last_success = jiffies;
3950 adev->recalib_failure_count = 0;
3951 } else {
3952 /* failed: resubmit, but only limited
3953 * amount of times within some time range
3954 * to prevent endless loop */
3956 adev->recalib_time_last_success = 0; /* we failed */
3958 /* if some time passed between last
3959 * attempts, then reset failure retry counter
3960 * to be able to do next recalib attempt */
3961 if (time_after
3962 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3963 adev->recalib_failure_count = 0;
3965 if (adev->recalib_failure_count < 5) {
3966 /* increment inside only, for speedup of outside path */
3967 adev->recalib_failure_count++;
3968 adev->recalib_time_last_attempt = jiffies;
3969 acx_schedule_task(adev,
3970 ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3974 #endif // if 0
3976 void acx_e_after_interrupt_task(struct work_struct *work)
3978 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
3979 unsigned int flags;
3980 FN_ENTER;
3981 acx_lock(adev, flags);
3982 if (!adev->after_interrupt_jobs || !adev->initialized)
3983 goto end; /* no jobs to do */
3985 /* we see lotsa tx errors */
3986 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) {
3987 // acx_s_after_interrupt_recalib(adev);
3990 /* a poor interrupt code wanted to do update_card_settings() */
3991 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) {
3992 if (ACX_STATE_IFACE_UP & adev->dev_state_mask)
3993 acx_s_update_card_settings(adev);
3994 CLEAR_BIT(adev->after_interrupt_jobs,
3995 ACX_AFTER_IRQ_UPDATE_CARD_CFG);
3997 /* 1) we detected that no Scan_Complete IRQ came from fw, or
3998 ** 2) we found too many STAs */
3999 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) {
4000 log(L_IRQ, "sending a stop scan cmd...\n");
4001 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
4002 /* HACK: set the IRQ bit, since we won't get a
4003 * scan complete IRQ any more on ACX111 (works on ACX100!),
4004 * since _we_, not a fw, have stopped the scan */
4005 SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
4006 CLEAR_BIT(adev->after_interrupt_jobs,
4007 ACX_AFTER_IRQ_CMD_STOP_SCAN);
4010 /* either fw sent Scan_Complete or we detected that
4011 ** no Scan_Complete IRQ came from fw. Finish scanning,
4012 ** pick join partner if any */
4013 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) {
4014 /* + scan kills current join status - restore it
4015 ** (do we need it for STA?) */
4016 /* + does it happen only with active scans?
4017 ** active and passive scans? ALL scans including
4018 ** background one? */
4019 /* + was not verified that everything is restored
4020 ** (but at least we start to emit beacons again) */
4021 CLEAR_BIT(adev->after_interrupt_jobs,
4022 ACX_AFTER_IRQ_COMPLETE_SCAN);
4025 /* STA auth or assoc timed out, start over again */
4027 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) {
4028 log(L_IRQ, "sending a start_scan cmd...\n");
4029 CLEAR_BIT(adev->after_interrupt_jobs,
4030 ACX_AFTER_IRQ_RESTART_SCAN);
4033 /* whee, we got positive assoc response! 8) */
4034 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) {
4035 CLEAR_BIT(adev->after_interrupt_jobs,
4036 ACX_AFTER_IRQ_CMD_ASSOCIATE);
4038 end:
4039 if(adev->after_interrupt_jobs)
4041 printk("Jobs still to be run: %x\n",adev->after_interrupt_jobs);
4042 adev->after_interrupt_jobs = 0;
4044 acx_unlock(adev, flags);
4045 // acx_sem_unlock(adev);
4046 FN_EXIT0;
4050 /***********************************************************************
4051 ** acx_schedule_task
4053 ** Schedule the call of the after_interrupt method after leaving
4054 ** the interrupt context.
4056 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
4058 if (!adev->after_interrupt_jobs)
4060 SET_BIT(adev->after_interrupt_jobs, set_flag);
4061 schedule_work(&adev->after_interrupt_task);
4066 /***********************************************************************
4068 void acx_init_task_scheduler(acx_device_t * adev)
4070 /* configure task scheduler */
4071 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4075 /***********************************************************************
4076 ** acx_s_start
4078 void acx_s_start(acx_device_t * adev)
4080 FN_ENTER;
4083 * Ok, now we do everything that can possibly be done with ioctl
4084 * calls to make sure that when it was called before the card
4085 * was up we get the changes asked for
4088 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4089 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4090 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4091 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4093 log(L_INIT, "updating initial settings on iface activation\n");
4094 acx_s_update_card_settings(adev);
4096 FN_EXIT0;
4100 /***********************************************************************
4101 ** acx_update_capabilities
4102 *//*
4103 void acx_update_capabilities(acx_device_t * adev)
4105 u16 cap = 0;
4107 switch (adev->mode) {
4108 case ACX_MODE_3_AP:
4109 SET_BIT(cap, WF_MGMT_CAP_ESS);
4110 break;
4111 case ACX_MODE_0_ADHOC:
4112 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4113 break;
4114 */ /* other types of stations do not emit beacons */
4115 /* }
4117 if (adev->wep_restricted) {
4118 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4120 if (adev->cfgopt_dot11ShortPreambleOption) {
4121 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4123 if (adev->cfgopt_dot11PBCCOption) {
4124 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4126 if (adev->cfgopt_dot11ChannelAgility) {
4127 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4129 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4130 adev->capabilities, cap);
4131 adev->capabilities = cap;
4135 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4138 static void acx_select_opmode(acx_device_t * adev)
4140 int changed = 0;
4142 FN_ENTER;
4144 if (adev->interface.operating) {
4145 switch (adev->interface.type) {
4146 case IEEE80211_IF_TYPE_AP:
4147 if (adev->mode != ACX_MODE_3_AP)
4149 adev->mode = ACX_MODE_3_AP;
4150 changed = 1;
4152 break;
4153 case IEEE80211_IF_TYPE_IBSS:
4154 if (adev->mode != ACX_MODE_0_ADHOC)
4156 adev->mode = ACX_MODE_0_ADHOC;
4157 changed = 1;
4159 break;
4160 case IEEE80211_IF_TYPE_STA:
4161 if (adev->mode != ACX_MODE_2_STA)
4163 adev->mode = ACX_MODE_2_STA;
4164 changed = 1;
4166 break;
4167 case IEEE80211_IF_TYPE_WDS:
4168 default:
4169 if (adev->mode != ACX_MODE_OFF)
4171 adev->mode = ACX_MODE_OFF;
4172 changed = 1;
4174 break;
4176 } else {
4177 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4179 if (adev->mode != ACX_MODE_MONITOR)
4181 adev->mode = ACX_MODE_MONITOR;
4182 changed = 1;
4185 else
4187 if (adev->mode != ACX_MODE_OFF)
4189 adev->mode = ACX_MODE_OFF;
4190 changed = 1;
4194 if (changed)
4196 SET_BIT(adev->set_mask, GETSET_MODE);
4197 acx_s_update_card_settings(adev);
4198 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4203 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4207 int acx_add_interface(struct ieee80211_hw *ieee,
4208 struct ieee80211_if_init_conf *conf)
4210 acx_device_t *adev = ieee2adev(ieee);
4211 unsigned long flags;
4212 int err = -EOPNOTSUPP;
4214 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4215 DECLARE_MAC_BUF(mac);
4216 #endif
4218 FN_ENTER;
4219 acx_lock(adev, flags);
4221 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4222 adev->interface.monitor++;
4223 } else {
4224 if (adev->interface.operating)
4225 goto out_unlock;
4226 adev->interface.operating = 1;
4227 /* for 2.6.25 or later */
4229 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4230 adev->interface.if_id = conf->if_id;
4231 #else
4232 adev->vif = conf->vif;
4233 #endif
4235 adev->interface.if_id = conf->if_id;
4236 adev->interface.mac_addr = conf->mac_addr;
4237 adev->interface.type = conf->type;
4239 // adev->mode = conf->type;
4240 if (adev->initialized)
4241 acx_select_opmode(adev);
4242 err = 0;
4244 printk(KERN_INFO "Virtual interface added "
4245 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4246 "(type: 0x%08X, ID: %d, MAC: "
4247 MAC_FMT ")\n",
4248 conf->type,
4249 conf->if_id,
4250 MAC_ARG(conf->mac_addr));
4251 #else
4252 "(type: 0x%08X), ID: %d, MAC: %s\n",
4253 conf->type,
4254 conf->if_id, /* use conf->vif, and %pd here on 2.6.25 or later */
4255 print_mac(mac, conf->mac_addr));
4256 #endif
4258 out_unlock:
4259 acx_unlock(adev, flags);
4261 FN_EXIT0;
4262 return err;
4265 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4269 void acx_remove_interface(struct ieee80211_hw *hw,
4270 struct ieee80211_if_init_conf *conf)
4272 acx_device_t *adev = ieee2adev(hw);
4273 unsigned long flags;
4275 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4276 DECLARE_MAC_BUF(mac);
4277 #endif
4279 FN_ENTER;
4281 acx_lock(adev, flags);
4282 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4283 adev->interface.monitor--;
4284 // assert(bcm->interface.monitor >= 0);
4285 } else
4286 adev->interface.operating = 0;
4287 printk("Removing interface: %d %d\n", adev->interface.operating, conf->type);
4288 if (adev->initialized)
4289 acx_select_opmode(adev);
4290 flush_scheduled_work();
4291 acx_unlock(adev, flags);
4293 printk(KERN_INFO "Virtual interface removed "
4294 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4295 "(type: 0x%08X, ID: %d, MAC: "
4296 MAC_FMT ")\n",
4297 conf->type, conf->if_id, MAC_ARG(conf->mac_addr));
4298 #else
4299 "(type: 0x%08X, ID: %pd, MAC: %s)\n",
4300 conf->type,
4301 conf->if_id, /* use conf->vif, and %pd here on 2.6.25 or later */
4302 print_mac(mac, conf->mac_addr));
4303 #endif
4304 FN_EXIT0;
4307 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4311 int acx_net_reset(struct ieee80211_hw *ieee)
4313 acx_device_t *adev = ieee2adev(ieee);
4314 FN_ENTER;
4315 if (IS_PCI(adev))
4316 acxpci_s_reset_dev(adev);
4317 else
4318 TODO();
4320 FN_EXIT0;
4321 return 0;
4325 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4328 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4330 int result;
4332 FN_ENTER;
4334 acx_sem_lock(adev);
4335 adev->rx_status.channel = channel;
4336 adev->rx_status.freq = freq;
4338 adev->channel = channel;
4339 /* hmm, the following code part is strange, but this is how
4340 * it was being done before... */
4341 log(L_IOCTL, "Changing to channel %d\n", channel);
4342 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4343 result = -EINPROGRESS; /* need to call commit handler */
4345 acx_sem_unlock(adev);
4346 FN_EXIT1(result);
4347 return result;
4351 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4354 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4356 acx_device_t *adev = ieee2adev(hw);
4357 unsigned long flags;
4358 #if 0
4359 int change = 0;
4360 #endif
4361 FN_ENTER;
4363 acx_lock(adev, flags);
4364 //FIXME();
4365 if (!adev->initialized) {
4366 acx_unlock(adev,flags);
4367 return 0;
4369 if (conf->beacon_int != adev->beacon_interval)
4370 adev->beacon_interval = conf->beacon_int;
4371 if (conf->channel != adev->channel) {
4372 acx_selectchannel(adev, conf->channel,conf->freq);
4373 /* acx_schedule_task(adev,
4374 ACX_AFTER_IRQ_UPDATE_CARD_CFG
4375 */ /*+ ACX_AFTER_IRQ_RESTART_SCAN */ /*);*/
4378 if (conf->short_slot_time != adev->short_slot) {
4379 // assert(phy->type == BCM43xx_PHYTYPE_G);
4380 if (conf->short_slot_time)
4381 acx_short_slot_timing_enable(adev);
4382 else
4383 acx_short_slot_timing_disable(adev);
4384 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4387 adev->tx_disabled = !conf->radio_enabled;
4388 if (conf->power_level != 0 && adev->tx_level_dbm > 15){
4389 adev->tx_level_dbm = conf->power_level;
4390 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4391 //acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4394 //FIXME: This does not seem to wake up:
4395 #if 0
4396 if (conf->power_level == 0) {
4397 if (radio->enabled)
4398 bcm43xx_radio_turn_off(bcm);
4399 } else {
4400 if (!radio->enabled)
4401 bcm43xx_radio_turn_on(bcm);
4403 #endif
4405 //TODO: phymode
4406 //TODO: antennas
4407 if (adev->set_mask > 0)
4408 acx_s_update_card_settings(adev);
4409 acx_unlock(adev, flags);
4411 FN_EXIT0;
4412 return 0;
4416 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4420 /* for 2.6.25 or later */
4422 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4423 int acx_config_interface(struct ieee80211_hw* ieee, int if_id,
4424 struct ieee80211_if_conf *conf)
4426 acx_device_t *adev = ieee2adev(ieee);
4427 unsigned long flags;
4428 int err = -ENODEV;
4429 FN_ENTER;
4430 if (!adev->interface.operating)
4431 goto err_out;
4432 acx_lock(adev, flags);
4434 if (adev->initialized)
4435 acx_select_opmode(adev);
4437 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4438 && (adev->interface.if_id == if_id)) {
4439 if (conf->bssid)
4441 adev->interface.bssid = conf->bssid;
4442 MAC_COPY(adev->bssid,conf->bssid);
4445 if ((conf->type == IEEE80211_IF_TYPE_AP)
4446 && (adev->interface.if_id == if_id)) {
4447 #else
4449 extern int acx_config_interface(struct ieee80211_hw* ieee,
4450 struct ieee80211_vif *vif,
4451 struct ieee80211_if_conf *conf)
4453 acx_device_t *adev = ieee2adev(ieee);
4454 unsigned long flags;
4455 int err = -ENODEV;
4456 FN_ENTER;
4457 if (!adev->interface.operating)
4458 goto err_out;
4459 acx_lock(adev, flags);
4461 if (adev->initialized)
4462 acx_select_opmode(adev);
4464 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4465 && (adev->vif == vif)) {
4466 if (conf->bssid)
4468 adev->interface.bssid = conf->bssid;
4469 MAC_COPY(adev->bssid,conf->bssid);
4472 if ((conf->type == IEEE80211_IF_TYPE_AP)
4473 && (adev->vif == vif)) {
4474 //#endif (see above)
4475 if ((conf->ssid_len > 0) && conf->ssid)
4477 adev->essid_len = conf->ssid_len;
4478 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4479 SET_BIT(adev->set_mask, SET_TEMPLATES);
4482 if (conf->beacon != 0)
4484 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4485 adev->beacon_cache = conf->beacon;
4486 SET_BIT(adev->set_mask, SET_TEMPLATES);
4488 if (adev->set_mask != 0)
4489 acx_s_update_card_settings(adev);
4490 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4491 acx_unlock(adev, flags);
4492 err = 0;
4493 err_out:
4494 FN_EXIT1(err);
4495 return err;
4499 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4503 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4504 struct ieee80211_tx_queue_stats *stats)
4506 // acx_device_t *adev = ndev2adev(net_dev);
4507 struct ieee80211_tx_queue_stats_data *data;
4508 int err = -ENODEV;
4510 FN_ENTER;
4512 // acx_lock(adev, flags);
4513 data = &(stats->data[0]);
4514 data->len = 0;
4515 data->limit = TX_CNT;
4516 data->count = 0;
4517 // acx_unlock(adev, flags);
4519 FN_EXIT0;
4520 return err;
4523 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4527 int acx_net_conf_tx(struct ieee80211_hw *hw,
4528 int queue, const struct ieee80211_tx_queue_params *params)
4530 FN_ENTER;
4531 // TODO();
4532 FN_EXIT0;
4533 return 0;
4536 static void keymac_write(acx_device_t * adev, u8 index, const u32 * addr)
4538 /* for keys 0-3 there is no associated mac address */
4539 if (index < 4)
4540 return;
4542 index -= 4;
4543 if (1) {
4544 TODO();
4546 bcm43xx_shm_write32(bcm,
4547 BCM43xx_SHM_HWMAC,
4548 index * 2,
4549 cpu_to_be32(*addr));
4550 bcm43xx_shm_write16(bcm,
4551 BCM43xx_SHM_HWMAC,
4552 (index * 2) + 1,
4553 cpu_to_be16(*((u16 *)(addr + 1))));
4555 } else {
4556 if (index < 8) {
4557 TODO(); /* Put them in the macaddress filter */
4558 } else {
4559 TODO();
4560 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4561 Keep in mind to update the count of keymacs in 0x003 */
4567 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4571 int acx_clear_keys(acx_device_t * adev)
4573 static const u32 zero_mac[2] = { 0 };
4574 unsigned int i, j, nr_keys = 54;
4575 u16 offset;
4577 /* FixMe:Check for Number of Keys available */
4579 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4581 for (i = 0; i < nr_keys; i++) {
4582 adev->key[i].enabled = 0;
4583 /* returns for i < 4 immediately */
4584 keymac_write(adev, i, zero_mac);
4586 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4587 0x100 + (i * 2), 0x0000);
4589 for (j = 0; j < 8; j++) {
4590 offset =
4591 adev->security_offset + (j * 4) +
4592 (i * ACX_SEC_KEYSIZE);
4594 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4595 offset, 0x0000);
4599 return 1;
4603 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4607 int acx_key_write(acx_device_t * adev,
4608 u8 index,
4609 u8 algorithm,
4610 const u8 * _key, int key_len, const u8 * mac_addr)
4612 // struct iw_point *dwrq = &wrqu->encoding;
4613 // acx_device_t *adev = ndev2adev(ndev);
4614 int result;
4616 FN_ENTER;
4618 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4619 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4621 acx_sem_lock(adev);
4623 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4624 if (key_len > 0) {
4625 /* if index is 0 or invalid, use default key */
4626 if (index > 3)
4627 index = (int)adev->wep_current_index;
4628 if ((algorithm == ACX_SEC_ALGO_WEP)
4629 || (algorithm == ACX_SEC_ALGO_WEP104)) {
4630 if (key_len > 29)
4631 key_len = 29; /* restrict it */
4633 if (key_len > 13) {
4634 /* 29*8 == 232, WEP256 */
4635 adev->wep_keys[index].size = 29;
4636 } else if (key_len > 5) {
4637 /* 13*8 == 104bit, WEP128 */
4638 adev->wep_keys[index].size = 13;
4639 } else if (key_len > 0) {
4640 /* 5*8 == 40bit, WEP64 */
4641 adev->wep_keys[index].size = 5;
4642 } else {
4643 /* disable key */
4644 adev->wep_keys[index].size = 0;
4647 memset(adev->wep_keys[index].key, 0,
4648 sizeof(adev->wep_keys[index].key));
4649 memcpy(adev->wep_keys[index].key, _key, key_len);
4651 } else {
4652 /* set transmit key */
4653 if (index <= 3)
4654 adev->wep_current_index = index;
4655 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4656 /* complain if we were not just setting
4657 * the key mode */
4658 // result = -EINVAL;
4659 // goto end_unlock;
4660 // }
4663 adev->wep_enabled = (algorithm == ALG_WEP);
4665 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4667 if (algorithm & IW_ENCODE_OPEN) {
4668 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4669 adev->wep_restricted = 0;
4671 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4672 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4673 adev->wep_restricted = 1;
4676 // adev->auth_alg = algorithm;
4677 /* set flag to make sure the card WEP settings get updated */
4678 if (adev->wep_enabled) {
4679 SET_BIT(adev->set_mask, GETSET_WEP);
4680 acx_s_update_card_settings(adev);
4681 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4684 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4685 dwrq->length, extra, dwrq->flags);
4686 for (index = 0; index <= 3; index++) {
4687 if (adev->wep_keys[index].size) {
4688 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4689 adev->wep_keys[index].index,
4690 (int) adev->wep_keys[index].size,
4691 adev->wep_keys[index].key);
4695 result = -EINPROGRESS;
4696 acx_sem_unlock(adev);
4698 FN_EXIT1(result);
4699 return result;
4705 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4709 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4710 int acx_net_set_key(struct ieee80211_hw *ieee,
4711 set_key_cmd cmd,
4712 u8 * addr, struct ieee80211_key_conf *key, int aid)
4713 #else
4714 int acx_net_set_key(struct ieee80211_hw *ieee,
4715 enum set_key_cmd cmd, const u8 *local_addr,
4716 const u8 * addr, struct ieee80211_key_conf *key)
4717 #endif
4719 // return 0;
4720 struct acx_device *adev = ieee2adev(ieee);
4721 unsigned long flags;
4722 u8 algorithm;
4723 u8 index;
4724 int err = -EINVAL;
4725 FN_ENTER;
4726 // TODO();
4727 switch (key->alg) {
4728 default:
4729 /* case ALG_NONE:
4730 case ALG_NULL:
4731 algorithm = ACX_SEC_ALGO_NONE;
4732 break;
4733 */ case ALG_WEP:
4734 if (key->keylen == 5)
4735 algorithm = ACX_SEC_ALGO_WEP;
4736 else
4737 algorithm = ACX_SEC_ALGO_WEP104;
4738 break;
4739 case ALG_TKIP:
4740 algorithm = ACX_SEC_ALGO_TKIP;
4741 break;
4742 case ALG_CCMP:
4743 algorithm = ACX_SEC_ALGO_AES;
4744 break;
4747 index = (u8) (key->keyidx);
4748 if (index >= ARRAY_SIZE(adev->key))
4749 goto out;
4750 acx_lock(adev, flags);
4751 switch (cmd) {
4752 case SET_KEY:
4753 err = acx_key_write(adev, index, algorithm,
4754 key->key, key->keylen, addr);
4755 if (err)
4756 goto out_unlock;
4757 key->hw_key_idx = index;
4758 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4759 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4760 adev->default_key_idx = index;*/
4761 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4762 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4763 #endif
4764 adev->key[index].enabled = 1;
4765 break;
4766 case DISABLE_KEY:
4767 adev->key[index].enabled = 0;
4768 err = 0;
4769 break;
4770 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4771 case REMOVE_ALL_KEYS:
4772 acx_clear_keys(adev);
4773 err = 0;
4774 break;
4775 #endif
4776 /* case ENABLE_COMPRESSION:
4777 case DISABLE_COMPRESSION:
4778 err = 0;
4779 break; */
4781 out_unlock:
4782 acx_unlock(adev, flags);
4783 out:
4784 FN_EXIT0;
4785 return err;
4790 /***********************************************************************
4791 ** Common function to parse ALL configoption struct formats
4792 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4793 ** FIXME: logging should be removed here and added to a /proc file instead
4795 ** Look into bcm43xx
4797 void
4798 acx_s_parse_configoption(acx_device_t * adev,
4799 const acx111_ie_configoption_t * pcfg)
4801 const u8 *pEle;
4802 int i;
4803 int is_acx111 = IS_ACX111(adev);
4805 if (acx_debug & L_DEBUG) {
4806 printk("configoption struct content:\n");
4807 acx_dump_bytes(pcfg, sizeof(*pcfg));
4810 if ((is_acx111 && (adev->eeprom_version == 5))
4811 || (!is_acx111 && (adev->eeprom_version == 4))
4812 || (!is_acx111 && (adev->eeprom_version == 5))) {
4813 /* these versions are known to be supported */
4814 } else {
4815 printk("unknown chip and EEPROM version combination (%s, v%d), "
4816 "don't know how to parse config options yet. "
4817 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4818 adev->eeprom_version);
4819 return;
4822 /* first custom-parse the first part which has chip-specific layout */
4824 pEle = (const u8 *)pcfg;
4826 pEle += 4; /* skip (type,len) header */
4828 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4829 pEle += sizeof(adev->cfgopt_NVSv);
4831 if (is_acx111) {
4832 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4833 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4835 adev->cfgopt_probe_delay = 200; /* good default value? */
4836 pEle += 2; /* FIXME: unknown, value 0x0001 */
4837 } else {
4838 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4839 pEle += sizeof(adev->cfgopt_MAC);
4841 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4842 pEle += sizeof(adev->cfgopt_probe_delay);
4843 if ((adev->cfgopt_probe_delay < 100)
4844 || (adev->cfgopt_probe_delay > 500)) {
4845 printk("strange probe_delay value %d, "
4846 "tweaking to 200\n", adev->cfgopt_probe_delay);
4847 adev->cfgopt_probe_delay = 200;
4851 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4852 pEle += sizeof(adev->cfgopt_eof_memory);
4854 printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n",
4855 adev->cfgopt_NVS_vendor_offs,
4856 adev->cfgopt_probe_delay, adev->cfgopt_eof_memory);
4858 adev->cfgopt_dot11CCAModes = *pEle++;
4859 adev->cfgopt_dot11Diversity = *pEle++;
4860 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4861 adev->cfgopt_dot11PBCCOption = *pEle++;
4862 adev->cfgopt_dot11ChannelAgility = *pEle++;
4863 adev->cfgopt_dot11PhyType = *pEle++;
4864 adev->cfgopt_dot11TempType = *pEle++;
4865 printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4866 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4867 adev->cfgopt_dot11CCAModes,
4868 adev->cfgopt_dot11Diversity,
4869 adev->cfgopt_dot11ShortPreambleOption,
4870 adev->cfgopt_dot11PBCCOption,
4871 adev->cfgopt_dot11ChannelAgility,
4872 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4874 /* then use common parsing for next part which has common layout */
4876 pEle++; /* skip table_count (6) */
4878 adev->cfgopt_antennas.type = pEle[0];
4879 adev->cfgopt_antennas.len = pEle[1];
4880 printk("AntennaID:%02X Len:%02X Data:",
4881 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4882 for (i = 0; i < pEle[1]; i++) {
4883 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4884 printk("%02X ", pEle[i + 2]);
4886 printk("\n");
4888 pEle += pEle[1] + 2;
4889 adev->cfgopt_power_levels.type = pEle[0];
4890 adev->cfgopt_power_levels.len = pEle[1];
4891 printk("PowerLevelID:%02X Len:%02X Data:",
4892 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4893 for (i = 0; i < pEle[1]; i++) {
4894 adev->cfgopt_power_levels.list[i] =
4895 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4896 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4898 printk("\n");
4900 pEle += pEle[1] * 2 + 2;
4901 adev->cfgopt_data_rates.type = pEle[0];
4902 adev->cfgopt_data_rates.len = pEle[1];
4903 printk("DataRatesID:%02X Len:%02X Data:",
4904 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4905 for (i = 0; i < pEle[1]; i++) {
4906 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4907 printk("%02X ", pEle[i + 2]);
4909 printk("\n");
4911 pEle += pEle[1] + 2;
4912 adev->cfgopt_domains.type = pEle[0];
4913 adev->cfgopt_domains.len = pEle[1];
4914 printk("DomainID:%02X Len:%02X Data:",
4915 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4916 for (i = 0; i < pEle[1]; i++) {
4917 adev->cfgopt_domains.list[i] = pEle[i + 2];
4918 printk("%02X ", pEle[i + 2]);
4920 printk("\n");
4922 pEle += pEle[1] + 2;
4923 adev->cfgopt_product_id.type = pEle[0];
4924 adev->cfgopt_product_id.len = pEle[1];
4925 for (i = 0; i < pEle[1]; i++) {
4926 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4928 printk("ProductID:%02X Len:%02X Data:%.*s\n",
4929 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4930 adev->cfgopt_product_id.len,
4931 (char *)adev->cfgopt_product_id.list);
4933 pEle += pEle[1] + 2;
4934 adev->cfgopt_manufacturer.type = pEle[0];
4935 adev->cfgopt_manufacturer.len = pEle[1];
4936 for (i = 0; i < pEle[1]; i++) {
4937 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4939 printk("ManufacturerID:%02X Len:%02X Data:%.*s\n",
4940 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4941 adev->cfgopt_manufacturer.len,
4942 (char *)adev->cfgopt_manufacturer.list);
4944 printk("EEPROM part:\n");
4945 for (i=0; i<58; i++) {
4946 printk("%02X =======> 0x%02X\n",
4947 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4953 /***********************************************************************
4954 ** Linux Kernel Specific
4956 static int __init acx_e_init_module(void)
4958 int r1, r2;
4960 acx_struct_size_check();
4962 printk("acx: this driver is still EXPERIMENTAL\n"
4963 "acx: reading README file and/or Craig's HOWTO is "
4964 "recommended, visit http://acx100.sourceforge.net/wiki in case "
4965 "of further questions/discussion\n");
4967 #if defined(CONFIG_ACX_MAC80211_PCI)
4968 r1 = acxpci_e_init_module();
4969 #else
4970 r1 = -EINVAL;
4971 #endif
4972 #if defined(CONFIG_ACX_MAC80211_USB)
4973 r2 = acxusb_e_init_module();
4974 #else
4975 r2 = -EINVAL;
4976 #endif
4977 if (r2 && r1) /* both failed! */
4978 return r2 ? r2 : r1;
4979 /* return success if at least one succeeded */
4980 return 0;
4983 static void __exit acx_e_cleanup_module(void)
4985 #if defined(CONFIG_ACX_MAC80211_PCI)
4986 acxpci_e_cleanup_module();
4987 #endif
4988 #if defined(CONFIG_ACX_MAC80211_USB)
4989 acxusb_e_cleanup_module();
4990 #endif
4993 module_init(acx_e_init_module)
4994 module_exit(acx_e_cleanup_module)