fix format type
[acx-mac80211.git] / common.c
blob7706e7742bf52d8b0c594f4f7450376a591d46f7
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;
1449 #define RATETAB_ENT(_rate, _rateid, _flags) \
1451 .rate = (_rate), \
1452 .val = (_rateid), \
1453 .val2 = (_rateid), \
1454 .flags = (_flags), \
1458 static struct ieee80211_rate __acx_rates[] = {
1459 { .rate = 10,
1460 .val = RATE111_1,
1461 .flags = IEEE80211_RATE_CCK },
1462 { .rate = 20,
1463 .val = RATE111_2,
1464 .flags = IEEE80211_RATE_CCK_2 },
1465 { .rate = 55,
1466 .val = RATE111_5,
1467 .flags = IEEE80211_RATE_CCK_2 },
1468 { .rate = 110,
1469 .val = RATE111_11,
1470 .flags = IEEE80211_RATE_CCK_2 },
1471 { .rate = 60,
1472 .val = RATE111_6,
1473 .flags = IEEE80211_RATE_OFDM },
1474 { .rate = 90,
1475 .val = RATE111_9,
1476 .flags = IEEE80211_RATE_OFDM },
1477 { .rate = 120,
1478 .val = RATE111_12,
1479 .flags = IEEE80211_RATE_OFDM },
1480 { .rate = 180,
1481 .val = RATE111_18,
1482 .flags = IEEE80211_RATE_OFDM },
1483 { .rate = 240,
1484 .val = RATE111_24,
1485 .flags = IEEE80211_RATE_OFDM },
1486 { .rate = 360,
1487 .val = RATE111_36,
1488 .flags = IEEE80211_RATE_OFDM },
1489 { .rate = 480,
1490 .val = RATE111_48,
1491 .flags = IEEE80211_RATE_OFDM },
1492 { .rate = 540,
1493 .val = RATE111_54,
1494 .flags = IEEE80211_RATE_OFDM },
1497 #define acx_b_ratetable (__acx_rates + 0)
1498 #define acx_g_ratetable (__acx_rates + 0)
1501 #define CHANTAB_ENT(_chanid, _freq) \
1503 .chan = (_chanid), \
1504 .freq = (_freq), \
1505 .val = (_chanid), \
1506 .flag = IEEE80211_CHAN_W_SCAN | \
1507 IEEE80211_CHAN_W_ACTIVE_SCAN | \
1508 IEEE80211_CHAN_W_IBSS, \
1509 .power_level = 0xf, \
1510 .antenna_max = 0xFF, \
1513 static struct ieee80211_channel channels[] = {
1514 { .chan = 1,
1515 .freq = 2412},
1516 { .chan = 2,
1517 .freq = 2417},
1518 { .chan = 3,
1519 .freq = 2422},
1520 { .chan = 4,
1521 .freq = 2427},
1522 { .chan = 5,
1523 .freq = 2432},
1524 { .chan = 6,
1525 .freq = 2437},
1526 { .chan = 7,
1527 .freq = 2442},
1528 { .chan = 8,
1529 .freq = 2447},
1530 { .chan = 9,
1531 .freq = 2452},
1532 { .chan = 10,
1533 .freq = 2457},
1534 { .chan = 11,
1535 .freq = 2462},
1536 { .chan = 12,
1537 .freq = 2467},
1538 { .chan = 13,
1539 .freq = 2472},
1543 static int acx_setup_modes_bphy(acx_device_t * adev)
1545 int err = 0;
1546 struct ieee80211_hw *hw = adev->ieee;
1547 struct ieee80211_hw_mode *mode;
1549 FN_ENTER;
1551 mode = &adev->modes[0];
1552 mode->mode = MODE_IEEE80211B;
1553 mode->num_channels = acx_chantable_size;
1554 mode->channels = channels;
1555 mode->num_rates = acx_b_ratetable_size;
1556 mode->rates = acx_b_ratetable;
1557 err = ieee80211_register_hwmode(hw,mode);
1559 FN_EXIT1(err);
1560 return err;
1563 static int acx_setup_modes_gphy(acx_device_t * adev)
1565 int err = 0;
1566 struct ieee80211_hw *hw = adev->ieee;
1567 struct ieee80211_hw_mode *mode;
1569 FN_ENTER;
1571 mode = &adev->modes[1];
1572 mode->mode = MODE_IEEE80211G;
1573 mode->num_channels = acx_chantable_size;
1574 mode->channels = channels;
1575 mode->num_rates = acx_g_ratetable_size;
1576 mode->rates = acx_g_ratetable;
1577 err = ieee80211_register_hwmode(hw,mode);
1579 FN_EXIT1(err);
1580 return err;
1584 int acx_setup_modes(acx_device_t * adev)
1586 struct ieee80211_hw *hw = adev->ieee;
1587 struct ieee80211_hw_mode *mode;
1588 int err = -ENOMEM;
1590 FN_ENTER;
1592 if (IS_ACX111(adev)) {
1594 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);
1595 err = acx_setup_modes_gphy(adev);
1597 mode = &adev->modes[0];
1598 mode->mode = MODE_IEEE80211G;
1599 mode->num_channels = ARRAY_SIZE(channels);
1600 mode->num_rates = 12;
1601 mode->rates = acx_g_ratetable;
1602 } else {
1604 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1605 err = acx_setup_modes_bphy(adev);
1607 mode = &adev->modes[1];
1608 mode->mode = MODE_IEEE80211B;
1609 mode->num_channels = ARRAY_SIZE(channels);
1610 mode->num_rates = 4;
1611 mode->rates = acx_b_ratetable;
1614 /* if (err && adev->modes)
1615 kfree(adev->modes);*/
1617 mode->channels = channels;
1618 err = ieee80211_register_hwmode(hw,mode);
1620 FN_EXIT1(err);
1621 return err;
1625 /***********************************************************************
1626 ** acx_fill_beacon_or_proberesp_template
1628 ** Origin: derived from rt2x00 project
1630 static int
1631 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1632 struct acx_template_beacon *templ,
1633 struct sk_buff* skb /* in host order! */)
1635 FN_ENTER;
1637 memcpy(templ,skb->data, skb->len);
1638 FN_EXIT1(skb->len);
1639 return skb->len;
1642 /***********************************************************************
1643 ** acx_s_set_beacon_template
1647 static int
1648 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1650 struct acx_template_beacon bcn;
1651 int len, result;
1653 FN_ENTER;
1654 printk("Size of template: %08X, Size of beacon: %08X\n",sizeof(struct acx_template_beacon),skb->len);
1655 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1656 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1658 FN_EXIT1(result);
1659 return result;
1662 /***********************************************************************
1663 ** acx_cmd_join_bssid
1665 ** Common code for both acx100 and acx111.
1667 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1668 static const u8 bitpos2genframe_txrate[] = {
1669 10, /* 0. 1 Mbit/s */
1670 20, /* 1. 2 Mbit/s */
1671 55, /* 2. 5.5 Mbit/s */
1672 0x0B, /* 3. 6 Mbit/s */
1673 0x0F, /* 4. 9 Mbit/s */
1674 110, /* 5. 11 Mbit/s */
1675 0x0A, /* 6. 12 Mbit/s */
1676 0x0E, /* 7. 18 Mbit/s */
1677 220, /* 8. 22 Mbit/s */
1678 0x09, /* 9. 24 Mbit/s */
1679 0x0D, /* 10. 36 Mbit/s */
1680 0x08, /* 11. 48 Mbit/s */
1681 0x0C, /* 12. 54 Mbit/s */
1682 10, /* 13. 1 Mbit/s, should never happen */
1683 10, /* 14. 1 Mbit/s, should never happen */
1684 10, /* 15. 1 Mbit/s, should never happen */
1687 /* Looks scary, eh?
1688 ** Actually, each one compiled into one AND and one SHIFT,
1689 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1690 static inline unsigned int rate111to5bits(unsigned int rate)
1692 return (rate & 0x7)
1693 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1694 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1698 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1700 acx_joinbss_t tmp;
1701 int dtim_interval;
1702 int i;
1704 if (mac_is_zero(bssid))
1705 return;
1707 FN_ENTER;
1709 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1710 1 : adev->dtim_interval;
1712 memset(&tmp, 0, sizeof(tmp));
1714 for (i = 0; i < ETH_ALEN; i++) {
1715 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1718 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1720 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1721 ** are sent with one of these rates */
1722 if (IS_ACX111(adev)) {
1723 /* It was experimentally determined that rates_basic
1724 ** can take 11g rates as well, not only rates
1725 ** defined with JOINBSS_RATES_BASIC111_nnn.
1726 ** Just use RATE111_nnn constants... */
1727 tmp.u.acx111.dtim_interval = dtim_interval;
1728 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1729 log(L_ASSOC, "rates_basic:%04X, rates_supported:%04X\n",
1730 adev->rate_basic, adev->rate_oper);
1731 } else {
1732 tmp.u.acx100.dtim_interval = dtim_interval;
1733 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1734 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1735 log(L_ASSOC, "rates_basic:%04X->%02X, "
1736 "rates_supported:%04X->%02X\n",
1737 adev->rate_basic, tmp.u.acx100.rates_basic,
1738 adev->rate_oper, tmp.u.acx100.rates_supported);
1741 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1742 ** will be sent (rate/modulation/preamble) */
1743 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1744 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1745 /* we can use short pre *if* all peers can understand it */
1746 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1748 /* we switch fw to STA mode in MONITOR mode, it seems to be
1749 ** the only mode where fw does not emit beacons by itself
1750 ** but allows us to send anything (we really want to retain
1751 ** ability to tx arbitrary frames in MONITOR mode)
1753 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1754 tmp.channel = adev->channel;
1755 tmp.essid_len = adev->essid_len;
1757 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1758 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1760 log(L_ASSOC|L_DEBUG, "BSS_Type = %u\n", tmp.macmode);
1761 acxlog_mac(L_ASSOC|L_DEBUG, "JoinBSSID MAC:", adev->bssid, "\n");
1763 /* acx_update_capabilities(adev); */
1764 FN_EXIT0;
1767 /***********************************************************************
1768 ** acxpci_i_set_multicast_list
1769 ** FIXME: most likely needs refinement
1771 void
1772 acx_i_set_multicast_list(struct ieee80211_hw *hw,
1773 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1774 unsigned short netflags, int mc_count)
1775 #else
1776 unsigned int changed_flags,
1777 unsigned int *total_flags,
1778 int mc_count, struct dev_addr_list *mc_list)
1779 #endif
1781 acx_device_t *adev = ieee2adev(hw);
1782 unsigned long flags;
1784 FN_ENTER;
1786 acx_lock(adev, flags);
1788 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
1789 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI);
1790 if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1791 return;
1792 #endif
1794 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1795 if (netflags & (IFF_PROMISC | IFF_ALLMULTI)) {
1796 #else
1797 if (*total_flags) {
1798 #endif
1799 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1800 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1801 SET_BIT(adev->set_mask, SET_RXCONFIG);
1802 /* let kernel know in case *we* needed to set promiscuous */
1803 } else {
1804 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1805 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1806 SET_BIT(adev->set_mask, SET_RXCONFIG);
1809 /* cannot update card settings directly here, atomic context */
1810 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
1812 acx_unlock(adev, flags);
1814 FN_EXIT0;
1817 /***********************************************************************
1818 ** acx111 feature config
1820 ** Obvious
1822 static int
1823 acx111_s_get_feature_config(acx_device_t * adev,
1824 u32 * feature_options, u32 * data_flow_options)
1826 struct acx111_ie_feature_config feat;
1828 FN_ENTER;
1830 if (!IS_ACX111(adev)) {
1831 return NOT_OK;
1834 memset(&feat, 0, sizeof(feat));
1836 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1837 FN_EXIT1(NOT_OK);
1838 return NOT_OK;
1840 log(L_DEBUG,
1841 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1842 feat.feature_options, feat.data_flow_options);
1844 if (feature_options)
1845 *feature_options = le32_to_cpu(feat.feature_options);
1846 if (data_flow_options)
1847 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1849 FN_EXIT0;
1850 return OK;
1854 static int
1855 acx111_s_set_feature_config(acx_device_t * adev,
1856 u32 feature_options, u32 data_flow_options,
1857 unsigned int mode
1858 /* 0 == remove, 1 == add, 2 == set */ )
1860 struct acx111_ie_feature_config feat;
1862 FN_ENTER;
1864 if (!IS_ACX111(adev)) {
1865 FN_EXIT1(NOT_OK);
1866 return NOT_OK;
1869 if ((mode < 0) || (mode > 2)) {
1870 FN_EXIT1(NOT_OK);
1871 return NOT_OK;
1874 if (mode != 2)
1875 /* need to modify old data */
1876 acx111_s_get_feature_config(adev, &feat.feature_options,
1877 &feat.data_flow_options);
1878 else {
1879 /* need to set a completely new value */
1880 feat.feature_options = 0;
1881 feat.data_flow_options = 0;
1884 if (mode == 0) { /* remove */
1885 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1886 CLEAR_BIT(feat.data_flow_options,
1887 cpu_to_le32(data_flow_options));
1888 } else { /* add or set */
1889 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1890 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1893 log(L_DEBUG,
1894 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1895 "new: feature 0x%08X dataflow 0x%08X\n",
1896 feature_options, data_flow_options, mode,
1897 le32_to_cpu(feat.feature_options),
1898 le32_to_cpu(feat.data_flow_options));
1900 if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1901 FN_EXIT1(NOT_OK);
1902 return NOT_OK;
1905 FN_EXIT0;
1906 return OK;
1909 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1911 return acx111_s_set_feature_config(adev, f, d, 0);
1913 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1915 return acx111_s_set_feature_config(adev, f, d, 1);
1917 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1919 return acx111_s_set_feature_config(adev, f, d, 2);
1923 /***********************************************************************
1924 ** acx100_s_init_memory_pools
1926 static int
1927 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1929 acx100_ie_memblocksize_t MemoryBlockSize;
1930 acx100_ie_memconfigoption_t MemoryConfigOption;
1931 int TotalMemoryBlocks;
1932 int RxBlockNum;
1933 int TotalRxBlockSize;
1934 int TxBlockNum;
1935 int TotalTxBlockSize;
1937 FN_ENTER;
1939 /* Let's see if we can follow this:
1940 first we select our memory block size (which I think is
1941 completely arbitrary) */
1942 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1944 /* Then we alert the card to our decision of block size */
1945 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
1946 goto bad;
1949 /* We figure out how many total blocks we can create, using
1950 the block size we chose, and the beginning and ending
1951 memory pointers, i.e.: end-start/size */
1952 TotalMemoryBlocks =
1953 (le32_to_cpu(mmt->PoolEnd) -
1954 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1956 log(L_DEBUG, "TotalMemoryBlocks=%u (%u bytes)\n",
1957 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1959 /* MemoryConfigOption.DMA_config bitmask:
1960 access to ACX memory is to be done:
1961 0x00080000 using PCI conf space?!
1962 0x00040000 using IO instructions?
1963 0x00000000 using memory access instructions
1964 0x00020000 using local memory block linked list (else what?)
1965 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1967 if (IS_PCI(adev)) {
1968 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1969 /* Declare start of the Rx host pool */
1970 MemoryConfigOption.pRxHostDesc =
1971 cpu2acx(adev->rxhostdesc_startphy);
1972 log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
1973 acx2cpu(MemoryConfigOption.pRxHostDesc),
1974 (long)adev->rxhostdesc_startphy);
1975 } else {
1976 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1979 /* 50% of the allotment of memory blocks go to tx descriptors */
1980 TxBlockNum = TotalMemoryBlocks / 2;
1981 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1983 /* and 50% go to the rx descriptors */
1984 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1985 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1987 /* size of the tx and rx descriptor queues */
1988 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1989 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1990 log(L_DEBUG, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u "
1991 "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum,
1992 TotalTxBlockSize, TotalRxBlockSize);
1995 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1996 MemoryConfigOption.rx_mem =
1997 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1999 /* align the rx descriptor queue to units of 0x20
2000 * and offset it by the tx descriptor queue */
2001 MemoryConfigOption.tx_mem =
2002 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
2003 0x1f) & ~0x1f);
2004 log(L_DEBUG, "rx_mem %08X rx_mem %08X\n", MemoryConfigOption.tx_mem,
2005 MemoryConfigOption.rx_mem);
2007 /* alert the device to our decision */
2008 if (OK !=
2009 acx_s_configure(adev, &MemoryConfigOption,
2010 ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
2011 goto bad;
2014 /* and tell the device to kick it into gear */
2015 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
2016 goto bad;
2018 FN_EXIT1(OK);
2019 return OK;
2020 bad:
2021 FN_EXIT1(NOT_OK);
2022 return NOT_OK;
2026 /***********************************************************************
2027 ** acx100_s_create_dma_regions
2029 ** Note that this fn messes up heavily with hardware, but we cannot
2030 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2032 static int acx100_s_create_dma_regions(acx_device_t * adev)
2034 acx100_ie_queueconfig_t queueconf;
2035 acx_ie_memmap_t memmap;
2036 int res = NOT_OK;
2037 u32 tx_queue_start, rx_queue_start;
2039 FN_ENTER;
2041 /* read out the acx100 physical start address for the queues */
2042 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2043 goto fail;
2046 tx_queue_start = le32_to_cpu(memmap.QueueStart);
2047 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
2049 log(L_DEBUG, "initializing Queue Indicator\n");
2051 memset(&queueconf, 0, sizeof(queueconf));
2053 /* Not needed for PCI, so we can avoid setting them altogether */
2054 if (IS_USB(adev)) {
2055 queueconf.NumTxDesc = USB_TX_CNT;
2056 queueconf.NumRxDesc = USB_RX_CNT;
2059 /* calculate size of queues */
2060 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
2061 RX_CNT * sizeof(rxdesc_t) + 8);
2062 queueconf.NumTxQueues = 1; /* number of tx queues */
2063 /* sets the beginning of the tx descriptor queue */
2064 queueconf.TxQueueStart = memmap.QueueStart;
2065 /* done by memset: queueconf.TxQueuePri = 0; */
2066 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
2067 queueconf.QueueOptions = 1; /* auto reset descriptor */
2068 /* sets the end of the rx descriptor queue */
2069 queueconf.QueueEnd =
2070 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
2072 /* sets the beginning of the next queue */
2073 queueconf.HostQueueEnd =
2074 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
2075 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
2076 goto fail;
2079 if (IS_PCI(adev)) {
2080 /* sets the beginning of the rx descriptor queue, after the tx descrs */
2081 if (OK != acxpci_s_create_hostdesc_queues(adev))
2082 goto fail;
2083 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2086 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2087 goto fail;
2090 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
2091 0x1f) & ~0x1f);
2093 if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2094 goto fail;
2097 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
2098 goto fail;
2101 res = OK;
2102 goto end;
2104 fail:
2105 acx_s_mwait(1000); /* ? */
2106 if (IS_PCI(adev))
2107 acxpci_free_desc_queues(adev);
2108 end:
2109 FN_EXIT1(res);
2110 return res;
2114 /***********************************************************************
2115 ** acx111_s_create_dma_regions
2117 ** Note that this fn messes heavily with hardware, but we cannot
2118 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2120 #define ACX111_PERCENT(percent) ((percent)/5)
2122 static int acx111_s_create_dma_regions(acx_device_t * adev)
2124 struct acx111_ie_memoryconfig memconf;
2125 struct acx111_ie_queueconfig queueconf;
2126 u32 tx_queue_start, rx_queue_start;
2128 FN_ENTER;
2130 /* Calculate memory positions and queue sizes */
2132 /* Set up our host descriptor pool + data pool */
2133 if (IS_PCI(adev)) {
2134 if (OK != acxpci_s_create_hostdesc_queues(adev))
2135 goto fail;
2138 memset(&memconf, 0, sizeof(memconf));
2139 /* the number of STAs (STA contexts) to support
2140 ** NB: was set to 1 and everything seemed to work nevertheless... */
2141 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
2142 /* specify the memory block size. Default is 256 */
2143 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
2144 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
2145 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
2146 /* set the count of our queues
2147 ** NB: struct acx111_ie_memoryconfig shall be modified
2148 ** if we ever will switch to more than one rx and/or tx queue */
2149 memconf.count_rx_queues = 1;
2150 memconf.count_tx_queues = 1;
2151 /* 0 == Busmaster Indirect Memory Organization, which is what we want
2152 * (using linked host descs with their allocated mem).
2153 * 2 == Generic Bus Slave */
2154 /* done by memset: memconf.options = 0; */
2155 /* let's use 25% for fragmentations and 75% for frame transfers
2156 * (specified in units of 5%) */
2157 memconf.fragmentation = ACX111_PERCENT(75);
2158 /* Rx descriptor queue config */
2159 memconf.rx_queue1_count_descs = RX_CNT;
2160 memconf.rx_queue1_type = 7; /* must be set to 7 */
2161 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2162 if (IS_PCI(adev)) {
2163 memconf.rx_queue1_host_rx_start =
2164 cpu2acx(adev->rxhostdesc_startphy);
2166 /* Tx descriptor queue config */
2167 memconf.tx_queue1_count_descs = TX_CNT;
2168 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2170 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
2171 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2172 ** But it is actually correct wrt IE numbers.
2173 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
2174 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2175 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2176 if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
2177 goto fail;
2180 acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
2182 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2183 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2185 log(L_INIT, "dump queue head (from card):\n"
2186 "len: %u\n"
2187 "tx_memory_block_address: %X\n"
2188 "rx_memory_block_address: %X\n"
2189 "tx1_queue address: %X\n"
2190 "rx1_queue address: %X\n",
2191 le16_to_cpu(queueconf.len),
2192 le32_to_cpu(queueconf.tx_memory_block_address),
2193 le32_to_cpu(queueconf.rx_memory_block_address),
2194 tx_queue_start, rx_queue_start);
2196 if (IS_PCI(adev))
2197 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2199 FN_EXIT1(OK);
2200 return OK;
2201 fail:
2202 if (IS_PCI(adev))
2203 acxpci_free_desc_queues(adev);
2205 FN_EXIT1(NOT_OK);
2206 return NOT_OK;
2210 /***********************************************************************
2212 static void acx_s_initialize_rx_config(acx_device_t * adev)
2214 struct {
2215 u16 id;
2216 u16 len;
2217 u16 rx_cfg1;
2218 u16 rx_cfg2;
2219 } ACX_PACKED cfg;
2220 switch (adev->mode) {
2221 case ACX_MODE_MONITOR:
2222 adev->rx_config_1 = (u16) (0
2223 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2224 /* | RX_CFG1_FILTER_SSID */
2225 /* | RX_CFG1_FILTER_BCAST */
2226 /* | RX_CFG1_RCV_MC_ADDR1 */
2227 /* | RX_CFG1_RCV_MC_ADDR0 */
2228 /* | RX_CFG1_FILTER_ALL_MULTI */
2229 /* | RX_CFG1_FILTER_BSSID */
2230 /* | RX_CFG1_FILTER_MAC */
2231 | RX_CFG1_RCV_PROMISCUOUS
2232 | RX_CFG1_INCLUDE_FCS
2233 /* | RX_CFG1_INCLUDE_PHY_HDR */
2235 adev->rx_config_2 = (u16) (0
2236 | RX_CFG2_RCV_ASSOC_REQ
2237 | RX_CFG2_RCV_AUTH_FRAMES
2238 | RX_CFG2_RCV_BEACON_FRAMES
2239 | RX_CFG2_RCV_CONTENTION_FREE
2240 | RX_CFG2_RCV_CTRL_FRAMES
2241 | RX_CFG2_RCV_DATA_FRAMES
2242 | RX_CFG2_RCV_BROKEN_FRAMES
2243 | RX_CFG2_RCV_MGMT_FRAMES
2244 | RX_CFG2_RCV_PROBE_REQ
2245 | RX_CFG2_RCV_PROBE_RESP
2246 | RX_CFG2_RCV_ACK_FRAMES
2247 | RX_CFG2_RCV_OTHER);
2248 break;
2249 default:
2250 adev->rx_config_1 = (u16) (0
2251 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2252 /* | RX_CFG1_FILTER_SSID */
2253 /* | RX_CFG1_FILTER_BCAST */
2254 /* | RX_CFG1_RCV_MC_ADDR1 */
2255 /* | RX_CFG1_RCV_MC_ADDR0 */
2256 /* | RX_CFG1_FILTER_ALL_MULTI */
2257 /* | RX_CFG1_FILTER_BSSID */
2258 /* | RX_CFG1_FILTER_MAC */
2259 | RX_CFG1_RCV_PROMISCUOUS
2260 /* | RX_CFG1_INCLUDE_FCS */
2261 /* | RX_CFG1_INCLUDE_PHY_HDR */
2263 adev->rx_config_2 = (u16) (0
2264 | RX_CFG2_RCV_ASSOC_REQ
2265 | RX_CFG2_RCV_AUTH_FRAMES
2266 | RX_CFG2_RCV_BEACON_FRAMES
2267 | RX_CFG2_RCV_CONTENTION_FREE
2268 | RX_CFG2_RCV_CTRL_FRAMES
2269 | RX_CFG2_RCV_DATA_FRAMES
2270 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2271 | RX_CFG2_RCV_MGMT_FRAMES
2272 | RX_CFG2_RCV_PROBE_REQ
2273 | RX_CFG2_RCV_PROBE_RESP
2274 | RX_CFG2_RCV_ACK_FRAMES
2275 | RX_CFG2_RCV_OTHER);
2276 break;
2278 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2280 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2281 || (adev->firmware_numver >= 0x02000000))
2282 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2283 else
2284 adev->phy_header_len = 0;
2286 log(L_INIT, "setting RXconfig to %04X:%04X\n",
2287 adev->rx_config_1, adev->rx_config_2);
2288 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2289 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2290 acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
2294 /***********************************************************************
2295 ** acx_s_set_defaults
2297 void acx_s_set_defaults(acx_device_t * adev)
2299 unsigned long flags;
2301 FN_ENTER;
2303 acx_lock(adev, flags);
2304 /* do it before getting settings, prevent bogus channel 0 warning */
2305 adev->channel = 1;
2307 /* query some settings from the card.
2308 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2309 * query is REQUIRED, otherwise the card won't work correctly! */
2310 adev->get_mask =
2311 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2312 GETSET_REG_DOMAIN;
2313 /* Only ACX100 supports ED and CCA */
2314 if (IS_ACX100(adev))
2315 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2317 acx_s_update_card_settings(adev);
2320 /* set our global interrupt mask */
2321 if (IS_PCI(adev))
2322 acxpci_set_interrupt_mask(adev);
2324 adev->led_power = 1; /* LED is active on startup */
2325 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2326 adev->brange_time_last_state_change = jiffies;
2328 /* copy the MAC address we just got from the card
2329 * into our MAC address used during current 802.11 session */
2330 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
2331 MAC_BCAST(adev->ap);
2333 adev->essid_len =
2334 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2335 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2336 adev->essid_active = 1;
2338 /* we have a nick field to waste, so why not abuse it
2339 * to announce the driver version? ;-) */
2340 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2342 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2343 /* first regulatory domain entry in EEPROM == default reg. domain */
2344 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2347 /* 0xffff would be better, but then we won't get a "scan complete"
2348 * interrupt, so our current infrastructure will fail: */
2349 adev->scan_count = 1;
2350 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2351 adev->scan_duration = 100;
2352 adev->scan_probe_delay = 200;
2353 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2354 adev->scan_rate = ACX_SCAN_RATE_1;
2357 adev->mode = ACX_MODE_2_STA;
2358 adev->listen_interval = 100;
2359 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2360 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2362 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2364 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2365 adev->frag_threshold = 2346;
2367 /* use standard default values for retry limits */
2368 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2369 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2371 adev->preamble_mode = 2; /* auto */
2372 adev->fallback_threshold = 3;
2373 adev->stepup_threshold = 10;
2374 adev->rate_bcast = RATE111_1;
2375 adev->rate_bcast100 = RATE100_1;
2376 adev->rate_basic = RATE111_1 | RATE111_2;
2377 adev->rate_auto = 1;
2378 if (IS_ACX111(adev)) {
2379 adev->rate_oper = RATE111_ALL;
2380 } else {
2381 adev->rate_oper = RATE111_ACX100_COMPAT;
2384 /* Supported Rates element - the rates here are given in units of
2385 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2386 acx_l_update_ratevector(adev);
2388 /* set some more defaults */
2389 if (IS_ACX111(adev)) {
2390 /* 30mW (15dBm) is default, at least in my acx111 card: */
2391 adev->tx_level_dbm = 15;
2392 } else {
2393 /* don't use max. level, since it might be dangerous
2394 * (e.g. WRT54G people experience
2395 * excessive Tx power damage!) */
2396 adev->tx_level_dbm = 18;
2398 /* adev->tx_level_auto = 1; */
2399 if (IS_ACX111(adev)) {
2400 /* start with sensitivity level 1 out of 3: */
2401 adev->sensitivity = 1;
2404 /* #define ENABLE_POWER_SAVE */
2405 #ifdef ENABLE_POWER_SAVE
2406 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2407 adev->ps_listen_interval = 1;
2408 adev->ps_options =
2409 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2410 adev->ps_hangover_period = 30;
2411 adev->ps_enhanced_transition_time = 0;
2412 #else
2413 adev->ps_wakeup_cfg = 0;
2414 adev->ps_listen_interval = 0;
2415 adev->ps_options = 0;
2416 adev->ps_hangover_period = 0;
2417 adev->ps_enhanced_transition_time = 0;
2418 #endif
2420 /* These settings will be set in fw on ifup */
2421 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2422 /* configure card to do rate fallback when in auto rate mode */
2423 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2424 /* better re-init the antenna value we got above */
2425 | GETSET_ANTENNA
2426 #if POWER_SAVE_80211
2427 | GETSET_POWER_80211
2428 #endif
2431 acx_unlock(adev, flags);
2432 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2434 acx_s_initialize_rx_config(adev);
2436 FN_EXIT0;
2440 /***********************************************************************
2441 ** FIXME: this should be solved in a general way for all radio types
2442 ** by decoding the radio firmware module,
2443 ** since it probably has some standard structure describing how to
2444 ** set the power level of the radio module which it controls.
2445 ** Or maybe not, since the radio module probably has a function interface
2446 ** instead which then manages Tx level programming :-\
2448 ** Obvious
2450 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2452 struct acx111_ie_tx_level tx_level;
2454 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2455 * 1 (30mW) [15dBm]
2456 * 2 (10mW) [10dBm]
2457 * For now, just assume all other acx111 cards have the same.
2458 * FIXME: Ideally we would query it here, but we first need a
2459 * standard way to query individual configoptions easily.
2460 * Well, now we have proper cfgopt txpower variables, but this still
2461 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2462 if (level_dbm <= 12) {
2463 tx_level.level = 2; /* 10 dBm */
2464 adev->tx_level_dbm = 10;
2465 } else {
2466 tx_level.level = 1; /* 15 dBm */
2467 adev->tx_level_dbm = 15;
2469 /* if (level_dbm != adev->tx_level_dbm)
2470 log(L_INIT, "acx111 firmware has specific "
2471 "power levels only: adjusted %d dBm to %d dBm!\n",
2472 level_dbm, adev->tx_level_dbm);
2474 return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
2477 static int acx_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2479 if (IS_ACX111(adev)) {
2480 return acx111_s_set_tx_level(adev, level_dbm);
2482 if (IS_PCI(adev)) {
2483 return acx100pci_s_set_tx_level(adev, level_dbm);
2485 return OK;
2488 /***********************************************************************
2489 ** acx_l_process_rxbuf
2491 ** NB: used by USB code also
2493 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2495 struct ieee80211_hdr *hdr;
2496 u16 fc, buf_len;
2497 hdr = acx_get_wlan_hdr(adev, rxbuf);
2498 fc = le16_to_cpu(hdr->frame_control);
2499 /* length of frame from control field to first byte of FCS */
2500 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2502 if (unlikely(acx_debug & L_DATA)) {
2503 printk("rx: 802.11 buf[%u]: ", buf_len);
2504 acx_dump_bytes(hdr, buf_len);
2508 acx_l_rx(adev, rxbuf);
2509 /* Now check Rx quality level, AFTER processing packet.
2510 * I tried to figure out how to map these levels to dBm
2511 * values, but for the life of me I really didn't
2512 * manage to get it. Either these values are not meant to
2513 * be expressed in dBm, or it's some pretty complicated
2514 * calculation. */
2516 #ifdef FROM_SCAN_SOURCE_ONLY
2517 /* only consider packets originating from the MAC
2518 * address of the device that's managing our BSSID.
2519 * Disable it for now, since it removes information (levels
2520 * from different peers) and slows the Rx path. *//*
2521 if (adev->ap_client && mac_is_equal(hdr->a2, adev->ap_client->address)) {
2523 #endif
2527 /***********************************************************************
2528 ** acx_l_handle_txrate_auto
2530 ** Theory of operation:
2531 ** client->rate_cap is a bitmask of rates client is capable of.
2532 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2533 ** It is set as a result of iwconfig rate N [auto]
2534 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2535 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2536 ** auto (0x00ff == 18Mbit or any lower value),
2537 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2539 ** client->rate_cur is a value for rate111 field in tx descriptor.
2540 ** It is always set to txrate_cfg sans zero or more most significant
2541 ** bits. This routine handles selection of new rate_cur value depending on
2542 ** outcome of last tx event.
2544 ** client->rate_100 is a precalculated rate value for acx100
2545 ** (we can do without it, but will need to calculate it on each tx).
2547 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2548 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2549 ** In theory you can implement it, but so far it is considered not worth doing.
2551 ** 22Mbit, of course, is PBCC always. */
2553 /* maps acx100 tx descr rate field to acx111 one */
2555 static u16 rate100to111(u8 r)
2557 switch (r) {
2558 case RATE100_1:
2559 return RATE111_1;
2560 case RATE100_2:
2561 return RATE111_2;
2562 case RATE100_5:
2563 case (RATE100_5 | RATE100_PBCC511):
2564 return RATE111_5;
2565 case RATE100_11:
2566 case (RATE100_11 | RATE100_PBCC511):
2567 return RATE111_11;
2568 case RATE100_22:
2569 return RATE111_22;
2570 default:
2571 printk("acx: unexpected acx100 txrate: %u! "
2572 "Please report\n", r);
2573 return RATE111_1;
2580 acx_i_start_xmit(struct ieee80211_hw *hw,
2581 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2583 acx_device_t *adev = ieee2adev(hw);
2584 tx_t *tx;
2585 void *txbuf;
2586 unsigned long flags;
2588 int txresult = NOT_OK;
2590 FN_ENTER;
2592 if (unlikely(!skb)) {
2593 /* indicate success */
2594 txresult = OK;
2595 goto end_no_unlock;
2598 if (unlikely(!adev)) {
2599 goto end_no_unlock;
2603 acx_lock(adev, flags);
2605 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2606 goto end;
2608 if (unlikely(!adev->initialized)) {
2609 goto end;
2612 tx = acx_l_alloc_tx(adev);
2614 if (unlikely(!tx)) {
2615 printk_ratelimited("%s: start_xmit: txdesc ring is full, "
2616 "dropping tx\n", wiphy_name(adev->ieee->wiphy));
2617 txresult = NOT_OK;
2618 goto end;
2621 txbuf = acx_l_get_txbuf(adev, tx);
2623 if (unlikely(!txbuf)) {
2624 /* Card was removed */
2625 txresult = NOT_OK;
2626 acx_l_dealloc_tx(adev, tx);
2627 goto end;
2629 memcpy(txbuf, skb->data, skb->len);
2631 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2633 txresult = OK;
2634 adev->stats.tx_packets++;
2635 adev->stats.tx_bytes += skb->len;
2637 end:
2638 acx_unlock(adev, flags);
2640 end_no_unlock:
2642 FN_EXIT1(txresult);
2643 return txresult;
2645 /***********************************************************************
2646 ** acx_l_update_ratevector
2648 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2650 const u8 acx_bitpos2ratebyte[] = {
2651 DOT11RATEBYTE_1,
2652 DOT11RATEBYTE_2,
2653 DOT11RATEBYTE_5_5,
2654 DOT11RATEBYTE_6_G,
2655 DOT11RATEBYTE_9_G,
2656 DOT11RATEBYTE_11,
2657 DOT11RATEBYTE_12_G,
2658 DOT11RATEBYTE_18_G,
2659 DOT11RATEBYTE_22,
2660 DOT11RATEBYTE_24_G,
2661 DOT11RATEBYTE_36_G,
2662 DOT11RATEBYTE_48_G,
2663 DOT11RATEBYTE_54_G,
2666 void acx_l_update_ratevector(acx_device_t * adev)
2668 u16 bcfg = adev->rate_basic;
2669 u16 ocfg = adev->rate_oper;
2670 u8 *supp = adev->rate_supported;
2671 const u8 *dot11 = acx_bitpos2ratebyte;
2673 FN_ENTER;
2675 while (ocfg) {
2676 if (ocfg & 1) {
2677 *supp = *dot11;
2678 if (bcfg & 1) {
2679 *supp |= 0x80;
2681 supp++;
2683 dot11++;
2684 ocfg >>= 1;
2685 bcfg >>= 1;
2687 adev->rate_supported_len = supp - adev->rate_supported;
2688 if (acx_debug & L_ASSOC) {
2689 printk("new ratevector: ");
2690 acx_dump_bytes(adev->rate_supported, adev->rate_supported_len);
2692 FN_EXIT0;
2695 /***********************************************************************
2696 ** acx_i_timer
2698 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2700 ** Obvious
2702 void acx_i_timer(unsigned long address)
2704 unsigned long flags;
2705 acx_device_t *adev = (acx_device_t *) address;
2707 FN_ENTER;
2709 acx_lock(adev, flags);
2711 FIXME();
2712 /* We need calibration and stats gather tasks to perform here */
2714 acx_unlock(adev, flags);
2716 FN_EXIT0;
2720 /***********************************************************************
2721 ** acx_set_timer
2723 ** Sets the 802.11 state management timer's timeout.
2725 ** Linux derived
2727 void acx_set_timer(acx_device_t * adev, int timeout_us)
2729 FN_ENTER;
2731 log(L_DEBUG | L_IRQ, "%s(%u ms)\n", __func__, timeout_us / 1000);
2732 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2733 printk("attempt to set the timer "
2734 "when the card interface is not up!\n");
2735 goto end;
2738 /* first check if the timer was already initialized, THEN modify it */
2739 if (adev->mgmt_timer.function) {
2740 mod_timer(&adev->mgmt_timer,
2741 jiffies + (timeout_us * HZ / 1000000));
2743 end:
2744 FN_EXIT0;
2747 /** acx_plcp_get_bitrate_cck
2749 ** Obvious
2751 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2753 switch (plcp) {
2754 case 0x0A:
2755 return ACX_CCK_RATE_1MB;
2756 case 0x14:
2757 return ACX_CCK_RATE_2MB;
2758 case 0x37:
2759 return ACX_CCK_RATE_5MB;
2760 case 0x6E:
2761 return ACX_CCK_RATE_11MB;
2763 return 0;
2766 /* Extract the bitrate out of an OFDM PLCP header. */
2767 /** Obvious **/
2768 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2770 switch (plcp & 0xF) {
2771 case 0xB:
2772 return ACX_OFDM_RATE_6MB;
2773 case 0xF:
2774 return ACX_OFDM_RATE_9MB;
2775 case 0xA:
2776 return ACX_OFDM_RATE_12MB;
2777 case 0xE:
2778 return ACX_OFDM_RATE_18MB;
2779 case 0x9:
2780 return ACX_OFDM_RATE_24MB;
2781 case 0xD:
2782 return ACX_OFDM_RATE_36MB;
2783 case 0x8:
2784 return ACX_OFDM_RATE_48MB;
2785 case 0xC:
2786 return ACX_OFDM_RATE_54MB;
2788 return 0;
2792 /***********************************************************************
2793 ** acx_l_rx
2795 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2796 ** buffer and feeds it to the network stack via netif_rx().
2798 ** Look to bcm43xx or p54
2800 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2803 struct ieee80211_rx_status* status = &adev->rx_status;
2804 struct ieee80211_hdr *w_hdr;
2805 int buflen;
2806 FN_ENTER;
2808 if (likely(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2809 struct sk_buff *skb;
2810 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2811 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2812 skb = dev_alloc_skb(buflen + 2);
2813 skb_reserve(skb, 2);
2814 skb_put(skb, buflen);
2815 memcpy(skb->data, w_hdr, buflen);
2817 // memset(&status, 0, sizeof(status));
2819 if (likely(skb)) {
2820 adev->acx_stats.last_rx = jiffies;
2821 status->mactime = rxbuf->time;
2822 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2823 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr);
2824 status->flag = 0;
2825 status->rate = rxbuf->phy_plcp_signal;
2826 status->antenna = 1;
2828 #ifndef OLD_QUALITY
2829 qual = acx_signal_determine_quality(adev->wstats.qual.level,
2830 adev->wstats.qual.noise);
2831 #else
2832 qual = (adev->wstats.qual.noise <= 100) ?
2833 100 - adev->wstats.qual.noise : 0;
2834 #endif
2835 adev->wstats.qual.qual = qual;
2836 adev->wstats.qual.updated = 7; *//* all 3 indicators updated */
2838 #ifdef FROM_SCAN_SOURCE_ONLY
2840 #endif
2842 if (rxbuf->phy_stat_baseband & (1 << 3)) /* Uses OFDM */
2844 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2845 } else
2847 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2849 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2850 adev->stats.rx_packets++;
2851 adev->stats.rx_bytes += skb->len;
2854 FN_EXIT0;
2859 /***********************************************************************
2860 ** acx_s_read_fw
2862 ** Loads a firmware image
2864 ** Returns:
2865 ** 0 unable to load file
2866 ** pointer to firmware success
2868 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2869 u32 * size)
2871 firmware_image_t *res;
2872 const struct firmware *fw_entry;
2874 res = NULL;
2875 log(L_INIT, "requesting firmware image '%s'\n", file);
2876 if (!request_firmware(&fw_entry, file, dev)) {
2877 *size = 8;
2878 if (fw_entry->size >= 8)
2879 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2880 if (fw_entry->size != *size) {
2881 printk("acx: firmware size does not match "
2882 "firmware header: %d != %d, "
2883 "aborting fw upload\n",
2884 (int)fw_entry->size, (int)*size);
2885 goto release_ret;
2887 res = vmalloc(*size);
2888 if (!res) {
2889 printk("acx: no memory for firmware "
2890 "(%u bytes)\n", *size);
2891 goto release_ret;
2893 memcpy(res, fw_entry->data, fw_entry->size);
2894 release_ret:
2895 release_firmware(fw_entry);
2896 return res;
2898 printk("acx: firmware image '%s' was not provided. "
2899 "Check your hotplug scripts\n", file);
2901 /* checksum will be verified in write_fw, so don't bother here */
2902 return res;
2906 /***********************************************************************
2907 ** acx_s_set_wepkey
2909 static void acx100_s_set_wepkey(acx_device_t * adev)
2911 ie_dot11WEPDefaultKey_t dk;
2912 int i;
2914 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2915 if (adev->wep_keys[i].size != 0) {
2916 log(L_INIT, "setting WEP key: %d with "
2917 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2918 dk.action = 1;
2919 dk.keySize = adev->wep_keys[i].size;
2920 dk.defaultKeyNum = i;
2921 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2922 acx_s_configure(adev, &dk,
2923 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
2928 static void acx111_s_set_wepkey(acx_device_t * adev)
2930 acx111WEPDefaultKey_t dk;
2931 int i;
2933 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2934 if (adev->wep_keys[i].size != 0) {
2935 log(L_INIT, "setting WEP key: %d with "
2936 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2937 memset(&dk, 0, sizeof(dk));
2938 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2939 dk.keySize = adev->wep_keys[i].size;
2941 /* are these two lines necessary? */
2942 dk.type = 0; /* default WEP key */
2943 dk.index = 0; /* ignored when setting default key */
2945 dk.defaultKeyNum = i;
2946 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2947 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2948 sizeof(dk));
2952 /* Obvious */
2953 static void acx_s_set_wepkey(acx_device_t * adev)
2955 if (IS_ACX111(adev))
2956 acx111_s_set_wepkey(adev);
2957 else
2958 acx100_s_set_wepkey(adev);
2962 /***********************************************************************
2963 ** acx100_s_init_wep
2965 ** FIXME: this should probably be moved into the new card settings
2966 ** management, but since we're also modifying the memory map layout here
2967 ** due to the WEP key space we want, we should take care...
2969 static int acx100_s_init_wep(acx_device_t * adev)
2971 acx100_ie_wep_options_t options;
2972 ie_dot11WEPDefaultKeyID_t dk;
2973 acx_ie_memmap_t pt;
2974 int res = NOT_OK;
2976 FN_ENTER;
2978 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2979 goto fail;
2982 log(L_DEBUG, "CodeEnd:%X\n", pt.CodeEnd);
2984 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2985 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2987 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2988 goto fail;
2991 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2992 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2993 options.WEPOption = 0x00;
2995 log(L_ASSOC, "writing WEP options\n");
2996 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
2998 acx100_s_set_wepkey(adev);
3000 if (adev->wep_keys[adev->wep_current_index].size != 0) {
3001 log(L_ASSOC, "setting active default WEP key number: %d\n",
3002 adev->wep_current_index);
3003 dk.KeyID = adev->wep_current_index;
3004 acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
3006 /* FIXME!!! wep_key_struct is filled nowhere! But adev
3007 * is initialized to 0, and we don't REALLY need those keys either */
3008 /* for (i = 0; i < 10; i++) {
3009 if (adev->wep_key_struct[i].len != 0) {
3010 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
3011 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
3012 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
3013 wep_mgmt.Action = cpu_to_le16(1);
3014 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
3015 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
3016 adev->wep_key_struct[i].index = i;
3022 /* now retrieve the updated WEPCacheEnd pointer... */
3023 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
3024 printk("%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
3025 wiphy_name(adev->ieee->wiphy));
3026 goto fail;
3028 /* ...and tell it to start allocating templates at that location */
3029 /* (no endianness conversion needed) */
3030 pt.PacketTemplateStart = pt.WEPCacheEnd;
3032 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
3033 printk("%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
3034 wiphy_name(adev->ieee->wiphy));
3035 goto fail;
3037 res = OK;
3039 fail:
3040 FN_EXIT1(res);
3041 return res;
3045 static int
3046 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
3047 unsigned int cmd)
3049 int res;
3050 union {
3051 acx_template_nullframe_t null;
3052 acx_template_beacon_t b;
3053 acx_template_tim_t tim;
3054 acx_template_probereq_t preq;
3055 acx_template_proberesp_t presp;
3056 } templ;
3058 memset(&templ, 0, len);
3059 templ.null.size = cpu_to_le16(len - 2);
3060 res = acx_s_issue_cmd(adev, cmd, &templ, len);
3061 return res;
3064 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
3066 return acx_s_init_max_template_generic(adev,
3067 sizeof(acx_template_nullframe_t),
3068 ACX1xx_CMD_CONFIG_NULL_DATA);
3071 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
3073 return acx_s_init_max_template_generic(adev,
3074 sizeof(acx_template_beacon_t),
3075 ACX1xx_CMD_CONFIG_BEACON);
3078 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
3080 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
3081 ACX1xx_CMD_CONFIG_TIM);
3084 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
3086 return acx_s_init_max_template_generic(adev,
3087 sizeof(acx_template_proberesp_t),
3088 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
3091 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
3093 return acx_s_init_max_template_generic(adev,
3094 sizeof(acx_template_probereq_t),
3095 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
3098 /***********************************************************************
3099 ** acx_s_set_tim_template
3101 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
3102 ** by calling this function
3103 ** (it can be done by irq handler on each DTIM irq or by timer...)
3105 [802.11 7.3.2.6] TIM information element:
3106 - 1 EID
3107 - 1 Length
3108 1 1 DTIM Count
3109 indicates how many beacons (including this) appear before next DTIM
3110 (0=this one is a DTIM)
3111 2 1 DTIM Period
3112 number of beacons between successive DTIMs
3113 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
3114 3 1 Bitmap Control
3115 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
3116 set to 1 in TIM elements with a value of 0 in the DTIM Count field
3117 when one or more broadcast or multicast frames are buffered at the AP.
3118 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
3119 4 n Partial Virtual Bitmap
3120 Visible part of traffic-indication bitmap.
3121 Full bitmap consists of 2008 bits (251 octets) such that bit number N
3122 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
3123 in octet number N/8 where the low-order bit of each octet is bit0,
3124 and the high order bit is bit7.
3125 Each set bit in virtual bitmap corresponds to traffic buffered by AP
3126 for a specific station (with corresponding AID?).
3127 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
3128 Bitmap Offset is a number of skipped zero octets (see above).
3129 'Missing' octets at the tail are also assumed to be zero.
3130 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
3131 This means that traffic-indication bitmap is:
3132 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
3133 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
3135 static int acx_s_set_tim_template(acx_device_t * adev)
3137 /* For now, configure smallish test bitmap, all zero ("no pending data") */
3138 enum { bitmap_size = 5 };
3140 acx_template_tim_t t;
3141 int result;
3143 FN_ENTER;
3145 memset(&t, 0, sizeof(t));
3146 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3147 t.tim_eid = WLAN_EID_TIM;
3148 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3149 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3150 FN_EXIT1(result);
3151 return result;
3157 #if POWER_SAVE_80211
3158 /***********************************************************************
3159 ** acx_s_set_null_data_template
3161 static int acx_s_set_null_data_template(acx_device_t * adev)
3163 struct acx_template_nullframe b;
3164 int result;
3166 FN_ENTER;
3168 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3170 b.size = cpu_to_le16(sizeof(b) - 2);
3171 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3172 b.hdr.dur = 0;
3173 MAC_BCAST(b.hdr.a1);
3174 MAC_COPY(b.hdr.a2, adev->dev_addr);
3175 MAC_COPY(b.hdr.a3, adev->bssid);
3176 b.hdr.seq = 0;
3178 result =
3179 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3181 FN_EXIT1(result);
3182 return result;
3184 #endif
3191 /***********************************************************************
3192 ** acx_s_init_packet_templates()
3194 ** NOTE: order is very important here, to have a correct memory layout!
3195 ** init templates: max Probe Request (station mode), max NULL data,
3196 ** max Beacon, max TIM, max Probe Response.
3198 static int acx_s_init_packet_templates(acx_device_t * adev)
3200 acx_ie_memmap_t mm; /* ACX100 only */
3201 int result = NOT_OK;
3203 FN_ENTER;
3205 log(L_DEBUG | L_INIT, "initializing max packet templates\n");
3207 if (OK != acx_s_init_max_probe_request_template(adev))
3208 goto failed;
3210 if (OK != acx_s_init_max_null_data_template(adev))
3211 goto failed;
3213 if (OK != acx_s_init_max_beacon_template(adev))
3214 goto failed;
3216 if (OK != acx_s_init_max_tim_template(adev))
3217 goto failed;
3219 if (OK != acx_s_init_max_probe_response_template(adev))
3220 goto failed;
3222 if (IS_ACX111(adev)) {
3223 /* ACX111 doesn't need the memory map magic below,
3224 * and the other templates will be set later (acx_start) */
3225 result = OK;
3226 goto success;
3229 /* ACX100 will have its TIM template set,
3230 * and we also need to update the memory map */
3232 if (OK != acx_s_set_tim_template(adev))
3233 goto failed_acx100;
3235 log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3237 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3238 goto failed_acx100;
3240 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3241 if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3242 goto failed_acx100;
3244 result = OK;
3245 goto success;
3247 failed_acx100:
3248 log(L_DEBUG | L_INIT,
3249 /* "cb=0x%X\n" */
3250 "ACXMemoryMap:\n"
3251 ".CodeStart=0x%X\n"
3252 ".CodeEnd=0x%X\n"
3253 ".WEPCacheStart=0x%X\n"
3254 ".WEPCacheEnd=0x%X\n"
3255 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3256 /* len, */
3257 le32_to_cpu(mm.CodeStart),
3258 le32_to_cpu(mm.CodeEnd),
3259 le32_to_cpu(mm.WEPCacheStart),
3260 le32_to_cpu(mm.WEPCacheEnd),
3261 le32_to_cpu(mm.PacketTemplateStart),
3262 le32_to_cpu(mm.PacketTemplateEnd));
3264 failed:
3265 printk("%s: %s() FAILED\n", wiphy_name(adev->ieee->wiphy), __func__);
3267 success:
3268 FN_EXIT1(result);
3269 return result;
3274 /***********************************************************************
3275 ** acx_s_init_mac
3277 int acx_s_init_mac(acx_device_t * adev)
3279 int result = NOT_OK;
3281 FN_ENTER;
3283 if (IS_ACX111(adev)) {
3284 adev->ie_len = acx111_ie_len;
3285 adev->ie_len_dot11 = acx111_ie_len_dot11;
3286 } else {
3287 adev->ie_len = acx100_ie_len;
3288 adev->ie_len_dot11 = acx100_ie_len_dot11;
3291 if (IS_PCI(adev)) {
3292 adev->memblocksize = 256; /* 256 is default */
3293 /* try to load radio for both ACX100 and ACX111, since both
3294 * chips have at least some firmware versions making use of an
3295 * external radio module */
3296 acxpci_s_upload_radio(adev);
3297 } else {
3298 adev->memblocksize = 128;
3301 if (IS_ACX111(adev)) {
3302 /* for ACX111, the order is different from ACX100
3303 1. init packet templates
3304 2. create station context and create dma regions
3305 3. init wep default keys
3307 if (OK != acx_s_init_packet_templates(adev))
3308 goto fail;
3309 if (OK != acx111_s_create_dma_regions(adev)) {
3310 printk("%s: acx111_create_dma_regions FAILED\n",
3311 wiphy_name(adev->ieee->wiphy));
3312 goto fail;
3314 } else {
3315 if (OK != acx100_s_init_wep(adev))
3316 goto fail;
3317 if (OK != acx_s_init_packet_templates(adev))
3318 goto fail;
3319 if (OK != acx100_s_create_dma_regions(adev)) {
3320 printk("%s: acx100_create_dma_regions FAILED\n",
3321 wiphy_name(adev->ieee->wiphy));
3322 goto fail;
3326 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3327 result = OK;
3329 fail:
3330 if (result)
3331 printk("acx: init_mac() FAILED\n");
3332 FN_EXIT1(result);
3333 return result;
3338 #if POWER_SAVE_80211
3339 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3341 /* merge both structs in a union to be able to have common code */
3342 union {
3343 acx111_ie_powersave_t acx111;
3344 acx100_ie_powersave_t acx100;
3345 } pm;
3347 /* change 802.11 power save mode settings */
3348 log(L_INIT, "updating 802.11 power save mode settings: "
3349 "wakeup_cfg 0x%02X, listen interval %u, "
3350 "options 0x%02X, hangover period %u, "
3351 "enhanced_ps_transition_time %u\n",
3352 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3353 adev->ps_options, adev->ps_hangover_period,
3354 adev->ps_enhanced_transition_time);
3355 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3356 log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, "
3357 "listen interval %u, options 0x%02X, "
3358 "hangover period %u, "
3359 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3360 pm.acx111.wakeup_cfg,
3361 pm.acx111.listen_interval,
3362 pm.acx111.options,
3363 pm.acx111.hangover_period,
3364 IS_ACX111(adev) ?
3365 pm.acx111.enhanced_ps_transition_time
3366 : pm.acx100.enhanced_ps_transition_time,
3367 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3368 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3369 pm.acx111.listen_interval = adev->ps_listen_interval;
3370 pm.acx111.options = adev->ps_options;
3371 pm.acx111.hangover_period = adev->ps_hangover_period;
3372 if (IS_ACX111(adev)) {
3373 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3374 pm.acx111.enhanced_ps_transition_time =
3375 cpu_to_le32(adev->ps_enhanced_transition_time);
3376 } else {
3377 pm.acx100.enhanced_ps_transition_time =
3378 cpu_to_le16(adev->ps_enhanced_transition_time);
3380 acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT);
3381 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3382 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3383 acx_s_mwait(40);
3384 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3385 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3386 log(L_INIT, "power save mode change %s\n",
3387 (pm.acx111.
3388 wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful");
3389 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3390 * that power save mode change was successful. */
3391 /* FIXME: we shouldn't trigger a scan immediately after
3392 * fiddling with power save mode (since the firmware is sending
3393 * a NULL frame then). */
3395 #endif
3398 /***********************************************************************
3399 ** acx_s_update_card_settings
3401 ** Applies accumulated changes in various adev->xxxx members
3402 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3403 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3405 void acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
3407 unsigned mask;
3409 unsigned int i;
3411 for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
3412 if (acx_reg_domain_ids[i] == adev->reg_dom_id)
3413 break;
3415 if (sizeof(acx_reg_domain_ids) == i) {
3416 log(L_INIT, "Invalid or unsupported regulatory domain"
3417 " 0x%02X specified, falling back to FCC (USA)!"
3418 " Please report if this sounds fishy!\n",
3419 adev->reg_dom_id);
3420 i = 0;
3421 adev->reg_dom_id = acx_reg_domain_ids[i];
3423 /* since there was a mismatch, we need to force updating */
3424 do_set = 1;
3427 if (do_set) {
3428 acx_ie_generic_t dom;
3429 dom.m.bytes[0] = adev->reg_dom_id;
3430 acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3433 adev->reg_dom_chanmask = reg_domain_channel_masks[i];
3435 mask = (1 << (adev->channel - 1));
3436 if (!(adev->reg_dom_chanmask & mask)) {
3437 /* hmm, need to adjust our channel to reside within domain */
3438 mask = 1;
3439 for (i = 1; i <= 14; i++) {
3440 if (adev->reg_dom_chanmask & mask) {
3441 printk("%s: adjusting selected channel from %d "
3442 "to %d due to new regulatory domain\n",
3443 wiphy_name(adev->ieee->wiphy), adev->channel, i);
3444 adev->channel = i;
3445 break;
3447 mask <<= 1;
3452 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3454 u32 feature1, feature2;
3456 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3457 printk("%s: invalid sensitivity setting (1..3), "
3458 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3459 adev->sensitivity = 1;
3461 acx111_s_get_feature_config(adev, &feature1, &feature2);
3462 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3463 if (adev->sensitivity > 1)
3464 SET_BIT(feature1, FEATURE1_LOW_RX);
3465 if (adev->sensitivity > 2)
3466 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3467 acx111_s_feature_set(adev, feature1, feature2);
3471 void acx_s_update_card_settings(acx_device_t *adev)
3473 unsigned long flags;
3474 unsigned int start_scan = 0;
3475 int i;
3477 FN_ENTER;
3479 log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3480 adev->get_mask, adev->set_mask);
3482 /* Track dependencies betweed various settings */
3484 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3485 log(L_INIT, "important setting has been changed. "
3486 "Need to update packet templates, too\n");
3487 SET_BIT(adev->set_mask, SET_TEMPLATES);
3489 if (adev->set_mask & GETSET_CHANNEL) {
3490 /* This will actually tune RX/TX to the channel */
3491 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3492 switch (adev->mode) {
3493 case ACX_MODE_0_ADHOC:
3494 case ACX_MODE_3_AP:
3495 /* Beacons contain channel# - update them */
3496 SET_BIT(adev->set_mask, SET_TEMPLATES);
3499 switch (adev->mode) {
3500 case ACX_MODE_0_ADHOC:
3501 case ACX_MODE_2_STA:
3502 start_scan = 1;
3506 /* Apply settings */
3509 if (adev->get_mask & GETSET_STATION_ID) {
3510 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3511 const u8 *paddr;
3513 acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3514 paddr = &stationID[4];
3515 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3516 for (i = 0; i < ETH_ALEN; i++) {
3517 /* we copy the MAC address (reversed in
3518 * the card) to the netdevice's MAC
3519 * address, and on ifup it will be
3520 * copied into iwadev->dev_addr */
3521 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3523 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3524 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3527 if (adev->get_mask & GETSET_SENSITIVITY) {
3528 if ((RADIO_RFMD_11 == adev->radio_type)
3529 || (RADIO_MAXIM_0D == adev->radio_type)
3530 || (RADIO_RALINK_15 == adev->radio_type)) {
3531 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3532 } else {
3533 log(L_INIT, "don't know how to get sensitivity "
3534 "for radio type 0x%02X\n", adev->radio_type);
3535 adev->sensitivity = 0;
3537 log(L_INIT, "got sensitivity value %u\n", adev->sensitivity);
3539 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3542 if (adev->get_mask & GETSET_ANTENNA) {
3543 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3545 memset(antenna, 0, sizeof(antenna));
3546 acx_s_interrogate(adev, antenna,
3547 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3548 adev->antenna = antenna[4];
3549 log(L_INIT, "got antenna value 0x%02X\n", adev->antenna);
3550 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3553 if (adev->get_mask & GETSET_ED_THRESH) {
3554 if (IS_ACX100(adev)) {
3555 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3557 memset(ed_threshold, 0, sizeof(ed_threshold));
3558 acx_s_interrogate(adev, ed_threshold,
3559 ACX100_IE_DOT11_ED_THRESHOLD);
3560 adev->ed_threshold = ed_threshold[4];
3561 } else {
3562 log(L_INIT, "acx111 doesn't support ED\n");
3563 adev->ed_threshold = 0;
3565 log(L_INIT, "got Energy Detect (ED) threshold %u\n",
3566 adev->ed_threshold);
3567 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3570 if (adev->get_mask & GETSET_CCA) {
3571 if (IS_ACX100(adev)) {
3572 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3574 memset(cca, 0, sizeof(adev->cca));
3575 acx_s_interrogate(adev, cca,
3576 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3577 adev->cca = cca[4];
3578 } else {
3579 log(L_INIT, "acx111 doesn't support CCA\n");
3580 adev->cca = 0;
3582 log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n",
3583 adev->cca);
3584 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3587 if (adev->get_mask & GETSET_REG_DOMAIN) {
3588 acx_ie_generic_t dom;
3590 acx_s_interrogate(adev, &dom,
3591 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3592 adev->reg_dom_id = dom.m.bytes[0];
3593 acx_s_set_sane_reg_domain(adev, 0);
3594 log(L_INIT, "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3595 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3598 if (adev->set_mask & GETSET_STATION_ID) {
3599 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3600 u8 *paddr;
3602 paddr = &stationID[4];
3603 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3604 for (i = 0; i < ETH_ALEN; i++) {
3605 /* copy the MAC address we obtained when we noticed
3606 * that the ethernet iface's MAC changed
3607 * to the card (reversed in
3608 * the card!) */
3609 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3611 acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3612 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3615 if (adev->set_mask & SET_STA_LIST) {
3616 acx_lock(adev, flags);
3617 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3618 acx_unlock(adev, flags);
3620 if (adev->set_mask & SET_RATE_FALLBACK) {
3621 u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
3623 /* configure to not do fallbacks when not in auto rate mode */
3624 rate[4] =
3625 (adev->
3626 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3627 log(L_INIT, "updating Tx fallback to %u retries\n", rate[4]);
3628 acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK);
3629 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3631 if (adev->set_mask & GETSET_TXPOWER) {
3632 log(L_INIT, "updating transmit power: %u dBm\n",
3633 adev->tx_level_dbm);
3634 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3635 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3638 if (adev->set_mask & GETSET_SENSITIVITY) {
3639 log(L_INIT, "updating sensitivity value: %u\n",
3640 adev->sensitivity);
3641 switch (adev->radio_type) {
3642 case RADIO_RFMD_11:
3643 case RADIO_MAXIM_0D:
3644 case RADIO_RALINK_15:
3645 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3646 break;
3647 case RADIO_RADIA_16:
3648 case RADIO_UNKNOWN_17:
3649 acx111_s_sens_radio_16_17(adev);
3650 break;
3651 default:
3652 log(L_INIT, "don't know how to modify sensitivity "
3653 "for radio type 0x%02X\n", adev->radio_type);
3655 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3658 if (adev->set_mask & GETSET_ANTENNA) {
3659 /* antenna */
3660 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3662 memset(antenna, 0, sizeof(antenna));
3663 antenna[4] = adev->antenna;
3664 log(L_INIT, "updating antenna value: 0x%02X\n", adev->antenna);
3665 acx_s_configure(adev, &antenna,
3666 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3667 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3670 if (adev->set_mask & GETSET_ED_THRESH) {
3671 /* ed_threshold */
3672 log(L_INIT, "updating Energy Detect (ED) threshold: %u\n",
3673 adev->ed_threshold);
3674 if (IS_ACX100(adev)) {
3675 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3677 memset(ed_threshold, 0, sizeof(ed_threshold));
3678 ed_threshold[4] = adev->ed_threshold;
3679 acx_s_configure(adev, &ed_threshold,
3680 ACX100_IE_DOT11_ED_THRESHOLD);
3681 } else
3682 log(L_INIT, "acx111 doesn't support ED!\n");
3683 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3686 if (adev->set_mask & GETSET_CCA) {
3687 /* CCA value */
3688 log(L_INIT, "updating Channel Clear Assessment "
3689 "(CCA) value: 0x%02X\n", adev->cca);
3690 if (IS_ACX100(adev)) {
3691 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3693 memset(cca, 0, sizeof(cca));
3694 cca[4] = adev->cca;
3695 acx_s_configure(adev, &cca,
3696 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3697 } else
3698 log(L_INIT, "acx111 doesn't support CCA!\n");
3699 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3702 if (adev->set_mask & GETSET_LED_POWER) {
3703 /* Enable Tx */
3704 log(L_INIT, "updating power LED status: %u\n", adev->led_power);
3706 acx_lock(adev, flags);
3707 if (IS_PCI(adev))
3708 acxpci_l_power_led(adev, adev->led_power);
3709 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3710 acx_unlock(adev, flags);
3713 if (adev->set_mask & GETSET_POWER_80211) {
3714 #if POWER_SAVE_80211
3715 acx_s_update_80211_powersave_mode(adev);
3716 #endif
3717 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3720 if (adev->set_mask & GETSET_CHANNEL) {
3721 /* channel */
3722 log(L_INIT, "updating channel to: %u\n", adev->channel);
3723 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3726 if (adev->set_mask & GETSET_TX) {
3727 /* set Tx */
3728 log(L_INIT, "updating: %s Tx\n",
3729 adev->tx_disabled ? "disable" : "enable");
3730 if (adev->tx_disabled)
3731 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3732 else {
3733 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3734 &adev->channel, 1);
3735 FIXME();
3736 /* This needs to be keyed on WEP? */
3737 acx111_s_feature_on(adev, 0,
3738 FEATURE2_NO_TXCRYPT |
3739 FEATURE2_SNIFFER);
3740 acx_wake_queue(adev->ieee, NULL);
3742 CLEAR_BIT(adev->set_mask, GETSET_TX);
3745 if (adev->set_mask & GETSET_RX) {
3746 /* Enable Rx */
3747 log(L_INIT, "updating: enable Rx on channel: %u\n",
3748 adev->channel);
3749 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3750 CLEAR_BIT(adev->set_mask, GETSET_RX);
3753 if (adev->set_mask & GETSET_RETRY) {
3754 u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
3755 u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
3757 log(L_INIT,
3758 "updating short retry limit: %u, long retry limit: %u\n",
3759 adev->short_retry, adev->long_retry);
3760 short_retry[0x4] = adev->short_retry;
3761 long_retry[0x4] = adev->long_retry;
3762 acx_s_configure(adev, &short_retry,
3763 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
3764 acx_s_configure(adev, &long_retry,
3765 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
3766 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3769 if (adev->set_mask & SET_MSDU_LIFETIME) {
3770 u8 xmt_msdu_lifetime[4 +
3771 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3773 log(L_INIT, "updating tx MSDU lifetime: %u\n",
3774 adev->msdu_lifetime);
3775 *(u32 *) & xmt_msdu_lifetime[4] =
3776 cpu_to_le32((u32) adev->msdu_lifetime);
3777 acx_s_configure(adev, &xmt_msdu_lifetime,
3778 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
3779 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3782 if (adev->set_mask & GETSET_REG_DOMAIN) {
3783 log(L_INIT, "updating regulatory domain: 0x%02X\n",
3784 adev->reg_dom_id);
3785 acx_s_set_sane_reg_domain(adev, 1);
3786 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3788 if (adev->set_mask & GETSET_MODE ) {
3789 acx111_s_feature_on(adev, 0,
3790 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3791 switch (adev->mode) {
3792 case ACX_MODE_3_AP:
3793 adev->aid = 0;
3794 //acx111_s_feature_off(adev, 0,
3795 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3796 MAC_COPY(adev->bssid,adev->dev_addr);
3797 acx_s_cmd_join_bssid(adev,adev->dev_addr);
3798 break;
3799 case ACX_MODE_MONITOR:
3800 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3801 break;
3802 case ACX_MODE_0_ADHOC:
3803 case ACX_MODE_2_STA:
3804 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3805 break;
3806 default:
3807 break;
3809 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3811 if (adev->set_mask & SET_TEMPLATES) {
3812 switch (adev->mode)
3814 case ACX_MODE_3_AP:
3815 acx_s_set_tim_template(adev);
3816 break;
3817 default:
3818 break;
3820 if (adev->beacon_cache)
3822 acx_s_set_beacon_template(adev, adev->beacon_cache);
3823 dev_kfree_skb(adev->beacon_cache);
3824 adev->beacon_cache = NULL;
3826 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3829 if (adev->set_mask & SET_RXCONFIG) {
3830 acx_s_initialize_rx_config(adev);
3831 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3834 if (adev->set_mask & GETSET_RESCAN) {
3835 /* switch (adev->mode) {
3836 case ACX_MODE_0_ADHOC:
3837 case ACX_MODE_2_STA:
3838 start_scan = 1;
3839 break;
3841 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3844 if (adev->set_mask & GETSET_WEP) {
3845 /* encode */
3847 ie_dot11WEPDefaultKeyID_t dkey;
3848 #ifdef DEBUG_WEP
3849 struct {
3850 u16 type;
3851 u16 len;
3852 u8 val;
3853 } ACX_PACKED keyindic;
3854 #endif
3855 log(L_INIT, "updating WEP key settings\n");
3857 acx_s_set_wepkey(adev);
3858 if (adev->wep_enabled) {
3859 dkey.KeyID = adev->wep_current_index;
3860 log(L_INIT, "setting WEP key %u as default\n",
3861 dkey.KeyID);
3862 acx_s_configure(adev, &dkey,
3863 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
3864 #ifdef DEBUG_WEP
3865 keyindic.val = 3;
3866 acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
3867 #endif
3870 // start_scan = 1;
3871 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3874 if (adev->set_mask & SET_WEP_OPTIONS) {
3875 acx100_ie_wep_options_t options;
3877 if (IS_ACX111(adev)) {
3878 log(L_DEBUG,
3879 "setting WEP Options for acx111 is not supported\n");
3880 } else {
3881 log(L_INIT, "setting WEP Options\n");
3883 /* let's choose maximum setting: 4 default keys,
3884 * plus 10 other keys: */
3885 options.NumKeys =
3886 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3887 /* don't decrypt default key only,
3888 * don't override decryption: */
3889 options.WEPOption = 0;
3890 if (adev->mode == ACX_MODE_3_AP) {
3891 /* don't decrypt default key only,
3892 * override decryption mechanism: */
3893 options.WEPOption = 2;
3896 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3898 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3902 /* debug, rate, and nick don't need any handling */
3903 /* what about sniffing mode?? */
3905 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3906 adev->get_mask, adev->set_mask);
3908 /* end: */
3909 FN_EXIT0;
3912 #if 0
3913 /***********************************************************************
3914 ** acx_e_after_interrupt_task
3916 static int acx_s_recalib_radio(acx_device_t * adev)
3918 if (IS_ACX111(adev)) {
3919 acx111_cmd_radiocalib_t cal;
3921 /* automatic recalibration, choose all methods: */
3922 cal.methods = cpu_to_le32(0x8000000f);
3923 /* automatic recalibration every 60 seconds (value in TUs)
3924 * I wonder what the firmware default here is? */
3925 cal.interval = cpu_to_le32(58594);
3926 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3927 &cal, sizeof(cal),
3928 CMD_TIMEOUT_MS(100));
3929 } else {
3930 /* On ACX100, we need to recalibrate the radio
3931 * by issuing a GETSET_TX|GETSET_RX */
3932 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3933 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3934 (OK ==
3935 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3936 &adev->channel, 1))
3937 && (OK ==
3938 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3939 &adev->channel, 1)))
3940 return OK;
3941 return NOT_OK;
3944 #endif // if 0
3945 #if 0
3946 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3948 int res;
3950 /* this helps with ACX100 at least;
3951 * hopefully ACX111 also does a
3952 * recalibration here */
3954 /* clear flag beforehand, since we want to make sure
3955 * it's cleared; then only set it again on specific circumstances */
3956 CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3958 /* better wait a bit between recalibrations to
3959 * prevent overheating due to torturing the card
3960 * into working too long despite high temperature
3961 * (just a safety measure) */
3962 if (adev->recalib_time_last_success
3963 && time_before(jiffies, adev->recalib_time_last_success
3964 + RECALIB_PAUSE * 60 * HZ)) {
3965 if (adev->recalib_msg_ratelimit <= 4) {
3966 printk("%s: less than " STRING(RECALIB_PAUSE)
3967 " minutes since last radio recalibration, "
3968 "not recalibrating (maybe card is too hot?)\n",
3969 wiphy_name(adev->ieee->wiphy));
3970 adev->recalib_msg_ratelimit++;
3971 if (adev->recalib_msg_ratelimit == 5)
3972 printk("disabling above message until next recalib\n");
3974 return;
3977 adev->recalib_msg_ratelimit = 0;
3979 /* note that commands sometimes fail (card busy),
3980 * so only clear flag if we were fully successful */
3981 res = acx_s_recalib_radio(adev);
3982 if (res == OK) {
3983 printk("%s: successfully recalibrated radio\n",
3984 wiphy_name(adev->ieee->wiphy));
3985 adev->recalib_time_last_success = jiffies;
3986 adev->recalib_failure_count = 0;
3987 } else {
3988 /* failed: resubmit, but only limited
3989 * amount of times within some time range
3990 * to prevent endless loop */
3992 adev->recalib_time_last_success = 0; /* we failed */
3994 /* if some time passed between last
3995 * attempts, then reset failure retry counter
3996 * to be able to do next recalib attempt */
3997 if (time_after
3998 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3999 adev->recalib_failure_count = 0;
4001 if (adev->recalib_failure_count < 5) {
4002 /* increment inside only, for speedup of outside path */
4003 adev->recalib_failure_count++;
4004 adev->recalib_time_last_attempt = jiffies;
4005 acx_schedule_task(adev,
4006 ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
4010 #endif // if 0
4012 void acx_e_after_interrupt_task(struct work_struct *work)
4014 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
4015 unsigned int flags;
4016 FN_ENTER;
4017 acx_lock(adev, flags);
4018 if (!adev->after_interrupt_jobs || !adev->initialized)
4019 goto end; /* no jobs to do */
4021 /* we see lotsa tx errors */
4022 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) {
4023 // acx_s_after_interrupt_recalib(adev);
4026 /* a poor interrupt code wanted to do update_card_settings() */
4027 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) {
4028 if (ACX_STATE_IFACE_UP & adev->dev_state_mask)
4029 acx_s_update_card_settings(adev);
4030 CLEAR_BIT(adev->after_interrupt_jobs,
4031 ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4033 /* 1) we detected that no Scan_Complete IRQ came from fw, or
4034 ** 2) we found too many STAs */
4035 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) {
4036 log(L_IRQ, "sending a stop scan cmd...\n");
4037 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
4038 /* HACK: set the IRQ bit, since we won't get a
4039 * scan complete IRQ any more on ACX111 (works on ACX100!),
4040 * since _we_, not a fw, have stopped the scan */
4041 SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
4042 CLEAR_BIT(adev->after_interrupt_jobs,
4043 ACX_AFTER_IRQ_CMD_STOP_SCAN);
4046 /* either fw sent Scan_Complete or we detected that
4047 ** no Scan_Complete IRQ came from fw. Finish scanning,
4048 ** pick join partner if any */
4049 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) {
4050 /* + scan kills current join status - restore it
4051 ** (do we need it for STA?) */
4052 /* + does it happen only with active scans?
4053 ** active and passive scans? ALL scans including
4054 ** background one? */
4055 /* + was not verified that everything is restored
4056 ** (but at least we start to emit beacons again) */
4057 CLEAR_BIT(adev->after_interrupt_jobs,
4058 ACX_AFTER_IRQ_COMPLETE_SCAN);
4061 /* STA auth or assoc timed out, start over again */
4063 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) {
4064 log(L_IRQ, "sending a start_scan cmd...\n");
4065 CLEAR_BIT(adev->after_interrupt_jobs,
4066 ACX_AFTER_IRQ_RESTART_SCAN);
4069 /* whee, we got positive assoc response! 8) */
4070 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) {
4071 CLEAR_BIT(adev->after_interrupt_jobs,
4072 ACX_AFTER_IRQ_CMD_ASSOCIATE);
4074 end:
4075 if(adev->after_interrupt_jobs)
4077 printk("Jobs still to be run: %x\n",adev->after_interrupt_jobs);
4078 adev->after_interrupt_jobs = 0;
4080 acx_unlock(adev, flags);
4081 // acx_sem_unlock(adev);
4082 FN_EXIT0;
4086 /***********************************************************************
4087 ** acx_schedule_task
4089 ** Schedule the call of the after_interrupt method after leaving
4090 ** the interrupt context.
4092 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
4094 if (!adev->after_interrupt_jobs)
4096 SET_BIT(adev->after_interrupt_jobs, set_flag);
4097 schedule_work(&adev->after_interrupt_task);
4102 /***********************************************************************
4104 void acx_init_task_scheduler(acx_device_t * adev)
4106 /* configure task scheduler */
4107 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4111 /***********************************************************************
4112 ** acx_s_start
4114 void acx_s_start(acx_device_t * adev)
4116 FN_ENTER;
4119 * Ok, now we do everything that can possibly be done with ioctl
4120 * calls to make sure that when it was called before the card
4121 * was up we get the changes asked for
4124 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4125 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4126 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4127 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4129 log(L_INIT, "updating initial settings on iface activation\n");
4130 acx_s_update_card_settings(adev);
4132 FN_EXIT0;
4136 /***********************************************************************
4137 ** acx_update_capabilities
4138 *//*
4139 void acx_update_capabilities(acx_device_t * adev)
4141 u16 cap = 0;
4143 switch (adev->mode) {
4144 case ACX_MODE_3_AP:
4145 SET_BIT(cap, WF_MGMT_CAP_ESS);
4146 break;
4147 case ACX_MODE_0_ADHOC:
4148 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4149 break;
4150 */ /* other types of stations do not emit beacons */
4151 /* }
4153 if (adev->wep_restricted) {
4154 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4156 if (adev->cfgopt_dot11ShortPreambleOption) {
4157 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4159 if (adev->cfgopt_dot11PBCCOption) {
4160 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4162 if (adev->cfgopt_dot11ChannelAgility) {
4163 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4165 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4166 adev->capabilities, cap);
4167 adev->capabilities = cap;
4171 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4174 static void acx_select_opmode(acx_device_t * adev)
4176 int changed = 0;
4178 FN_ENTER;
4180 if (adev->interface.operating) {
4181 switch (adev->interface.type) {
4182 case IEEE80211_IF_TYPE_AP:
4183 if (adev->mode != ACX_MODE_3_AP)
4185 adev->mode = ACX_MODE_3_AP;
4186 changed = 1;
4188 break;
4189 case IEEE80211_IF_TYPE_IBSS:
4190 if (adev->mode != ACX_MODE_0_ADHOC)
4192 adev->mode = ACX_MODE_0_ADHOC;
4193 changed = 1;
4195 break;
4196 case IEEE80211_IF_TYPE_STA:
4197 if (adev->mode != ACX_MODE_2_STA)
4199 adev->mode = ACX_MODE_2_STA;
4200 changed = 1;
4202 break;
4203 case IEEE80211_IF_TYPE_WDS:
4204 default:
4205 if (adev->mode != ACX_MODE_OFF)
4207 adev->mode = ACX_MODE_OFF;
4208 changed = 1;
4210 break;
4212 } else {
4213 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4215 if (adev->mode != ACX_MODE_MONITOR)
4217 adev->mode = ACX_MODE_MONITOR;
4218 changed = 1;
4221 else
4223 if (adev->mode != ACX_MODE_OFF)
4225 adev->mode = ACX_MODE_OFF;
4226 changed = 1;
4230 if (changed)
4232 SET_BIT(adev->set_mask, GETSET_MODE);
4233 acx_s_update_card_settings(adev);
4234 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4239 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4243 int acx_add_interface(struct ieee80211_hw *ieee,
4244 struct ieee80211_if_init_conf *conf)
4246 acx_device_t *adev = ieee2adev(ieee);
4247 unsigned long flags;
4248 int err = -EOPNOTSUPP;
4250 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4251 DECLARE_MAC_BUF(mac);
4252 #endif
4254 FN_ENTER;
4255 acx_lock(adev, flags);
4257 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4258 adev->interface.monitor++;
4259 } else {
4260 if (adev->interface.operating)
4261 goto out_unlock;
4262 adev->interface.operating = 1;
4263 /* for 2.6.25 or later */
4265 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4266 adev->interface.if_id = conf->if_id;
4267 #else
4268 adev->vif = conf->vif;
4269 #endif
4271 adev->interface.if_id = conf->if_id;
4272 adev->interface.mac_addr = conf->mac_addr;
4273 adev->interface.type = conf->type;
4275 // adev->mode = conf->type;
4276 if (adev->initialized)
4277 acx_select_opmode(adev);
4278 err = 0;
4280 printk(KERN_INFO "Virtual interface added "
4281 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4282 "(type: 0x%08X, ID: %d, MAC: "
4283 MAC_FMT ")\n",
4284 conf->type,
4285 conf->if_id,
4286 MAC_ARG(conf->mac_addr));
4287 #else
4288 "(type: 0x%08X), ID: %d, MAC: %s\n",
4289 conf->type,
4290 conf->if_id, /* use conf->vif, and %pd here on 2.6.25 or later */
4291 print_mac(mac, conf->mac_addr));
4292 #endif
4294 out_unlock:
4295 acx_unlock(adev, flags);
4297 FN_EXIT0;
4298 return err;
4301 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4305 void acx_remove_interface(struct ieee80211_hw *hw,
4306 struct ieee80211_if_init_conf *conf)
4308 acx_device_t *adev = ieee2adev(hw);
4309 unsigned long flags;
4311 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4312 DECLARE_MAC_BUF(mac);
4313 #endif
4315 FN_ENTER;
4317 acx_lock(adev, flags);
4318 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4319 adev->interface.monitor--;
4320 // assert(bcm->interface.monitor >= 0);
4321 } else
4322 adev->interface.operating = 0;
4323 printk("Removing interface: %d %d\n", adev->interface.operating, conf->type);
4324 if (adev->initialized)
4325 acx_select_opmode(adev);
4326 flush_scheduled_work();
4327 acx_unlock(adev, flags);
4329 printk(KERN_INFO "Virtual interface removed "
4330 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4331 "(type: 0x%08X, ID: %d, MAC: "
4332 MAC_FMT ")\n",
4333 conf->type, conf->if_id, MAC_ARG(conf->mac_addr));
4334 #else
4335 "(type: 0x%08X, ID: %d, MAC: %s)\n",
4336 conf->type,
4337 conf->if_id, /* use conf->vif, and %pd here on 2.6.25 or later */
4338 print_mac(mac, conf->mac_addr));
4339 #endif
4340 FN_EXIT0;
4343 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4347 int acx_net_reset(struct ieee80211_hw *ieee)
4349 acx_device_t *adev = ieee2adev(ieee);
4350 FN_ENTER;
4351 if (IS_PCI(adev))
4352 acxpci_s_reset_dev(adev);
4353 else
4354 TODO();
4356 FN_EXIT0;
4357 return 0;
4361 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4364 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4366 int result;
4368 FN_ENTER;
4370 acx_sem_lock(adev);
4371 adev->rx_status.channel = channel;
4372 adev->rx_status.freq = freq;
4374 adev->channel = channel;
4375 /* hmm, the following code part is strange, but this is how
4376 * it was being done before... */
4377 log(L_IOCTL, "Changing to channel %d\n", channel);
4378 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4379 result = -EINPROGRESS; /* need to call commit handler */
4381 acx_sem_unlock(adev);
4382 FN_EXIT1(result);
4383 return result;
4387 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4390 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4392 acx_device_t *adev = ieee2adev(hw);
4393 unsigned long flags;
4394 #if 0
4395 int change = 0;
4396 #endif
4397 FN_ENTER;
4399 acx_lock(adev, flags);
4400 //FIXME();
4401 if (!adev->initialized) {
4402 acx_unlock(adev,flags);
4403 return 0;
4405 if (conf->beacon_int != adev->beacon_interval)
4406 adev->beacon_interval = conf->beacon_int;
4407 if (conf->channel != adev->channel) {
4408 acx_selectchannel(adev, conf->channel,conf->freq);
4409 /* acx_schedule_task(adev,
4410 ACX_AFTER_IRQ_UPDATE_CARD_CFG
4411 */ /*+ ACX_AFTER_IRQ_RESTART_SCAN */ /*);*/
4414 if (conf->short_slot_time != adev->short_slot) {
4415 // assert(phy->type == BCM43xx_PHYTYPE_G);
4416 if (conf->short_slot_time)
4417 acx_short_slot_timing_enable(adev);
4418 else
4419 acx_short_slot_timing_disable(adev);
4420 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4423 adev->tx_disabled = !conf->radio_enabled;
4424 if (conf->power_level != 0 && adev->tx_level_dbm > 15){
4425 adev->tx_level_dbm = conf->power_level;
4426 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4427 //acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4430 //FIXME: This does not seem to wake up:
4431 #if 0
4432 if (conf->power_level == 0) {
4433 if (radio->enabled)
4434 bcm43xx_radio_turn_off(bcm);
4435 } else {
4436 if (!radio->enabled)
4437 bcm43xx_radio_turn_on(bcm);
4439 #endif
4441 //TODO: phymode
4442 //TODO: antennas
4443 if (adev->set_mask > 0)
4444 acx_s_update_card_settings(adev);
4445 acx_unlock(adev, flags);
4447 FN_EXIT0;
4448 return 0;
4452 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4456 //#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) (see below)
4457 int acx_config_interface(struct ieee80211_hw* ieee, int if_id,
4458 struct ieee80211_if_conf *conf)
4460 acx_device_t *adev = ieee2adev(ieee);
4461 unsigned long flags;
4462 int err = -ENODEV;
4463 FN_ENTER;
4464 if (!adev->interface.operating)
4465 goto err_out;
4466 acx_lock(adev, flags);
4468 if (adev->initialized)
4469 acx_select_opmode(adev);
4471 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4472 && (adev->interface.if_id == if_id)) {
4473 if (conf->bssid)
4475 adev->interface.bssid = conf->bssid;
4476 MAC_COPY(adev->bssid,conf->bssid);
4479 if ((conf->type == IEEE80211_IF_TYPE_AP)
4480 && (adev->interface.if_id == if_id)) {
4481 /* for 2.6.25 or later */
4483 #else
4484 extern int acx_config_interface(struct ieee80211_hw* ieee,
4485 struct ieee80211_vif *vif,
4486 struct ieee80211_if_conf *conf)
4488 acx_device_t *adev = ieee2adev(ieee);
4489 unsigned long flags;
4490 int err = -ENODEV;
4491 FN_ENTER;
4492 if (!adev->interface.operating)
4493 goto err_out;
4494 acx_lock(adev, flags);
4496 if (adev->initialized)
4497 acx_select_opmode(adev);
4499 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4500 && (adev->vif == vif)) {
4501 if (conf->bssid)
4503 adev->interface.bssid = conf->bssid;
4504 MAC_COPY(adev->bssid,conf->bssid);
4507 if ((conf->type == IEEE80211_IF_TYPE_AP)
4508 && (adev->vif == vif)) {
4509 #endif
4511 if ((conf->ssid_len > 0) && conf->ssid)
4513 adev->essid_len = conf->ssid_len;
4514 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4515 SET_BIT(adev->set_mask, SET_TEMPLATES);
4518 if (conf->beacon != 0)
4520 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4521 adev->beacon_cache = conf->beacon;
4522 SET_BIT(adev->set_mask, SET_TEMPLATES);
4524 if (adev->set_mask != 0)
4525 acx_s_update_card_settings(adev);
4526 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4527 acx_unlock(adev, flags);
4528 err = 0;
4529 err_out:
4530 FN_EXIT1(err);
4531 return err;
4535 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4539 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4540 struct ieee80211_tx_queue_stats *stats)
4542 // acx_device_t *adev = ndev2adev(net_dev);
4543 struct ieee80211_tx_queue_stats_data *data;
4544 int err = -ENODEV;
4546 FN_ENTER;
4548 // acx_lock(adev, flags);
4549 data = &(stats->data[0]);
4550 data->len = 0;
4551 data->limit = TX_CNT;
4552 data->count = 0;
4553 // acx_unlock(adev, flags);
4555 FN_EXIT0;
4556 return err;
4559 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4563 int acx_net_conf_tx(struct ieee80211_hw *hw,
4564 int queue, const struct ieee80211_tx_queue_params *params)
4566 FN_ENTER;
4567 // TODO();
4568 FN_EXIT0;
4569 return 0;
4572 static void keymac_write(acx_device_t * adev, u8 index, const u32 * addr)
4574 /* for keys 0-3 there is no associated mac address */
4575 if (index < 4)
4576 return;
4578 index -= 4;
4579 if (1) {
4580 TODO();
4582 bcm43xx_shm_write32(bcm,
4583 BCM43xx_SHM_HWMAC,
4584 index * 2,
4585 cpu_to_be32(*addr));
4586 bcm43xx_shm_write16(bcm,
4587 BCM43xx_SHM_HWMAC,
4588 (index * 2) + 1,
4589 cpu_to_be16(*((u16 *)(addr + 1))));
4591 } else {
4592 if (index < 8) {
4593 TODO(); /* Put them in the macaddress filter */
4594 } else {
4595 TODO();
4596 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4597 Keep in mind to update the count of keymacs in 0x003 */
4603 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4607 int acx_clear_keys(acx_device_t * adev)
4609 static const u32 zero_mac[2] = { 0 };
4610 unsigned int i, j, nr_keys = 54;
4611 u16 offset;
4613 /* FixMe:Check for Number of Keys available */
4615 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4617 for (i = 0; i < nr_keys; i++) {
4618 adev->key[i].enabled = 0;
4619 /* returns for i < 4 immediately */
4620 keymac_write(adev, i, zero_mac);
4622 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4623 0x100 + (i * 2), 0x0000);
4625 for (j = 0; j < 8; j++) {
4626 offset =
4627 adev->security_offset + (j * 4) +
4628 (i * ACX_SEC_KEYSIZE);
4630 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4631 offset, 0x0000);
4635 return 1;
4639 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4643 int acx_key_write(acx_device_t * adev,
4644 u8 index,
4645 u8 algorithm,
4646 const u8 * _key, int key_len, const u8 * mac_addr)
4648 // struct iw_point *dwrq = &wrqu->encoding;
4649 // acx_device_t *adev = ndev2adev(ndev);
4650 int result;
4652 FN_ENTER;
4654 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4655 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4657 acx_sem_lock(adev);
4659 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4660 if (key_len > 0) {
4661 /* if index is 0 or invalid, use default key */
4662 if (index > 3)
4663 index = (int)adev->wep_current_index;
4664 if ((algorithm == ACX_SEC_ALGO_WEP)
4665 || (algorithm == ACX_SEC_ALGO_WEP104)) {
4666 if (key_len > 29)
4667 key_len = 29; /* restrict it */
4669 if (key_len > 13) {
4670 /* 29*8 == 232, WEP256 */
4671 adev->wep_keys[index].size = 29;
4672 } else if (key_len > 5) {
4673 /* 13*8 == 104bit, WEP128 */
4674 adev->wep_keys[index].size = 13;
4675 } else if (key_len > 0) {
4676 /* 5*8 == 40bit, WEP64 */
4677 adev->wep_keys[index].size = 5;
4678 } else {
4679 /* disable key */
4680 adev->wep_keys[index].size = 0;
4683 memset(adev->wep_keys[index].key, 0,
4684 sizeof(adev->wep_keys[index].key));
4685 memcpy(adev->wep_keys[index].key, _key, key_len);
4687 } else {
4688 /* set transmit key */
4689 if (index <= 3)
4690 adev->wep_current_index = index;
4691 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4692 /* complain if we were not just setting
4693 * the key mode */
4694 // result = -EINVAL;
4695 // goto end_unlock;
4696 // }
4699 adev->wep_enabled = (algorithm == ALG_WEP);
4701 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4703 if (algorithm & IW_ENCODE_OPEN) {
4704 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4705 adev->wep_restricted = 0;
4707 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4708 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4709 adev->wep_restricted = 1;
4712 // adev->auth_alg = algorithm;
4713 /* set flag to make sure the card WEP settings get updated */
4714 if (adev->wep_enabled) {
4715 SET_BIT(adev->set_mask, GETSET_WEP);
4716 acx_s_update_card_settings(adev);
4717 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4720 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4721 dwrq->length, extra, dwrq->flags);
4722 for (index = 0; index <= 3; index++) {
4723 if (adev->wep_keys[index].size) {
4724 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4725 adev->wep_keys[index].index,
4726 (int) adev->wep_keys[index].size,
4727 adev->wep_keys[index].key);
4731 result = -EINPROGRESS;
4732 acx_sem_unlock(adev);
4734 FN_EXIT1(result);
4735 return result;
4741 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4745 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4746 int acx_net_set_key(struct ieee80211_hw *ieee,
4747 set_key_cmd cmd,
4748 u8 * addr, struct ieee80211_key_conf *key, int aid)
4749 #else
4750 int acx_net_set_key(struct ieee80211_hw *ieee,
4751 enum set_key_cmd cmd, const u8 *local_addr,
4752 const u8 * addr, struct ieee80211_key_conf *key)
4753 #endif
4755 // return 0;
4756 struct acx_device *adev = ieee2adev(ieee);
4757 unsigned long flags;
4758 u8 algorithm;
4759 u8 index;
4760 int err = -EINVAL;
4761 FN_ENTER;
4762 // TODO();
4763 switch (key->alg) {
4764 default:
4765 /* case ALG_NONE:
4766 case ALG_NULL:
4767 algorithm = ACX_SEC_ALGO_NONE;
4768 break;
4769 */ case ALG_WEP:
4770 if (key->keylen == 5)
4771 algorithm = ACX_SEC_ALGO_WEP;
4772 else
4773 algorithm = ACX_SEC_ALGO_WEP104;
4774 break;
4775 case ALG_TKIP:
4776 algorithm = ACX_SEC_ALGO_TKIP;
4777 break;
4778 case ALG_CCMP:
4779 algorithm = ACX_SEC_ALGO_AES;
4780 break;
4783 index = (u8) (key->keyidx);
4784 if (index >= ARRAY_SIZE(adev->key))
4785 goto out;
4786 acx_lock(adev, flags);
4787 switch (cmd) {
4788 case SET_KEY:
4789 err = acx_key_write(adev, index, algorithm,
4790 key->key, key->keylen, addr);
4791 if (err)
4792 goto out_unlock;
4793 key->hw_key_idx = index;
4794 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4795 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4796 adev->default_key_idx = index;*/
4797 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4798 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4799 #endif
4800 adev->key[index].enabled = 1;
4801 break;
4802 case DISABLE_KEY:
4803 adev->key[index].enabled = 0;
4804 err = 0;
4805 break;
4806 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4807 case REMOVE_ALL_KEYS:
4808 acx_clear_keys(adev);
4809 err = 0;
4810 break;
4811 #endif
4812 /* case ENABLE_COMPRESSION:
4813 case DISABLE_COMPRESSION:
4814 err = 0;
4815 break; */
4817 out_unlock:
4818 acx_unlock(adev, flags);
4819 out:
4820 FN_EXIT0;
4821 return err;
4826 /***********************************************************************
4827 ** Common function to parse ALL configoption struct formats
4828 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4829 ** FIXME: logging should be removed here and added to a /proc file instead
4831 ** Look into bcm43xx
4833 void
4834 acx_s_parse_configoption(acx_device_t * adev,
4835 const acx111_ie_configoption_t * pcfg)
4837 const u8 *pEle;
4838 int i;
4839 int is_acx111 = IS_ACX111(adev);
4841 if (acx_debug & L_DEBUG) {
4842 printk("configoption struct content:\n");
4843 acx_dump_bytes(pcfg, sizeof(*pcfg));
4846 if ((is_acx111 && (adev->eeprom_version == 5))
4847 || (!is_acx111 && (adev->eeprom_version == 4))
4848 || (!is_acx111 && (adev->eeprom_version == 5))) {
4849 /* these versions are known to be supported */
4850 } else {
4851 printk("unknown chip and EEPROM version combination (%s, v%d), "
4852 "don't know how to parse config options yet. "
4853 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4854 adev->eeprom_version);
4855 return;
4858 /* first custom-parse the first part which has chip-specific layout */
4860 pEle = (const u8 *)pcfg;
4862 pEle += 4; /* skip (type,len) header */
4864 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4865 pEle += sizeof(adev->cfgopt_NVSv);
4867 if (is_acx111) {
4868 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4869 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4871 adev->cfgopt_probe_delay = 200; /* good default value? */
4872 pEle += 2; /* FIXME: unknown, value 0x0001 */
4873 } else {
4874 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4875 pEle += sizeof(adev->cfgopt_MAC);
4877 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4878 pEle += sizeof(adev->cfgopt_probe_delay);
4879 if ((adev->cfgopt_probe_delay < 100)
4880 || (adev->cfgopt_probe_delay > 500)) {
4881 printk("strange probe_delay value %d, "
4882 "tweaking to 200\n", adev->cfgopt_probe_delay);
4883 adev->cfgopt_probe_delay = 200;
4887 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4888 pEle += sizeof(adev->cfgopt_eof_memory);
4890 printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n",
4891 adev->cfgopt_NVS_vendor_offs,
4892 adev->cfgopt_probe_delay, adev->cfgopt_eof_memory);
4894 adev->cfgopt_dot11CCAModes = *pEle++;
4895 adev->cfgopt_dot11Diversity = *pEle++;
4896 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4897 adev->cfgopt_dot11PBCCOption = *pEle++;
4898 adev->cfgopt_dot11ChannelAgility = *pEle++;
4899 adev->cfgopt_dot11PhyType = *pEle++;
4900 adev->cfgopt_dot11TempType = *pEle++;
4901 printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4902 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4903 adev->cfgopt_dot11CCAModes,
4904 adev->cfgopt_dot11Diversity,
4905 adev->cfgopt_dot11ShortPreambleOption,
4906 adev->cfgopt_dot11PBCCOption,
4907 adev->cfgopt_dot11ChannelAgility,
4908 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4910 /* then use common parsing for next part which has common layout */
4912 pEle++; /* skip table_count (6) */
4914 adev->cfgopt_antennas.type = pEle[0];
4915 adev->cfgopt_antennas.len = pEle[1];
4916 printk("AntennaID:%02X Len:%02X Data:",
4917 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4918 for (i = 0; i < pEle[1]; i++) {
4919 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4920 printk("%02X ", pEle[i + 2]);
4922 printk("\n");
4924 pEle += pEle[1] + 2;
4925 adev->cfgopt_power_levels.type = pEle[0];
4926 adev->cfgopt_power_levels.len = pEle[1];
4927 printk("PowerLevelID:%02X Len:%02X Data:",
4928 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4929 for (i = 0; i < pEle[1]; i++) {
4930 adev->cfgopt_power_levels.list[i] =
4931 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4932 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4934 printk("\n");
4936 pEle += pEle[1] * 2 + 2;
4937 adev->cfgopt_data_rates.type = pEle[0];
4938 adev->cfgopt_data_rates.len = pEle[1];
4939 printk("DataRatesID:%02X Len:%02X Data:",
4940 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4941 for (i = 0; i < pEle[1]; i++) {
4942 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4943 printk("%02X ", pEle[i + 2]);
4945 printk("\n");
4947 pEle += pEle[1] + 2;
4948 adev->cfgopt_domains.type = pEle[0];
4949 adev->cfgopt_domains.len = pEle[1];
4950 printk("DomainID:%02X Len:%02X Data:",
4951 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4952 for (i = 0; i < pEle[1]; i++) {
4953 adev->cfgopt_domains.list[i] = pEle[i + 2];
4954 printk("%02X ", pEle[i + 2]);
4956 printk("\n");
4958 pEle += pEle[1] + 2;
4959 adev->cfgopt_product_id.type = pEle[0];
4960 adev->cfgopt_product_id.len = pEle[1];
4961 for (i = 0; i < pEle[1]; i++) {
4962 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4964 printk("ProductID:%02X Len:%02X Data:%.*s\n",
4965 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4966 adev->cfgopt_product_id.len,
4967 (char *)adev->cfgopt_product_id.list);
4969 pEle += pEle[1] + 2;
4970 adev->cfgopt_manufacturer.type = pEle[0];
4971 adev->cfgopt_manufacturer.len = pEle[1];
4972 for (i = 0; i < pEle[1]; i++) {
4973 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4975 printk("ManufacturerID:%02X Len:%02X Data:%.*s\n",
4976 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4977 adev->cfgopt_manufacturer.len,
4978 (char *)adev->cfgopt_manufacturer.list);
4980 printk("EEPROM part:\n");
4981 for (i=0; i<58; i++) {
4982 printk("%02X =======> 0x%02X\n",
4983 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4989 /***********************************************************************
4990 ** Linux Kernel Specific
4992 static int __init acx_e_init_module(void)
4994 int r1, r2;
4996 acx_struct_size_check();
4998 printk("acx: this driver is still EXPERIMENTAL\n"
4999 "acx: reading README file and/or Craig's HOWTO is "
5000 "recommended, visit http://acx100.sourceforge.net/wiki in case "
5001 "of further questions/discussion\n");
5003 #if defined(CONFIG_ACX_MAC80211_PCI)
5004 r1 = acxpci_e_init_module();
5005 #else
5006 r1 = -EINVAL;
5007 #endif
5008 #if defined(CONFIG_ACX_MAC80211_USB)
5009 r2 = acxusb_e_init_module();
5010 #else
5011 r2 = -EINVAL;
5012 #endif
5013 if (r2 && r1) /* both failed! */
5014 return r2 ? r2 : r1;
5015 /* return success if at least one succeeded */
5016 return 0;
5019 static void __exit acx_e_cleanup_module(void)
5021 #if defined(CONFIG_ACX_MAC80211_PCI)
5022 acxpci_e_cleanup_module();
5023 #endif
5024 #if defined(CONFIG_ACX_MAC80211_USB)
5025 acxusb_e_cleanup_module();
5026 #endif
5029 module_init(acx_e_init_module)
5030 module_exit(acx_e_cleanup_module)