fix return value of acx_key_write (it failed before)
[acx-mac80211.git] / common.c
blobb73420198e7bd5514f536f3cf9b4cbeaa31c85ca
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];
1599 /* from the zd1211rw driver: - do we need to do the same? */
1601 memcpy(mode->channels, channels, sizeof(channels));
1602 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1605 mode->mode = MODE_IEEE80211G;
1606 mode->num_channels = ARRAY_SIZE(channels);
1607 mode->num_rates = 12;
1608 mode->rates = acx_g_ratetable;
1609 } else {
1611 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1612 err = acx_setup_modes_bphy(adev);
1614 mode = &adev->modes[1];
1616 /* from the zd1211rw driver: - do we need to do the same? */
1618 memcpy(mode->channels, channels, sizeof(channels));
1619 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1622 mode->mode = MODE_IEEE80211B;
1623 mode->num_channels = ARRAY_SIZE(channels);
1624 mode->num_rates = 4;
1625 mode->rates = acx_b_ratetable;
1628 /* if (err && adev->modes)
1629 kfree(adev->modes);*/
1631 mode->channels = channels;
1632 err = ieee80211_register_hwmode(hw,mode);
1634 FN_EXIT1(err);
1635 return err;
1639 /***********************************************************************
1640 ** acx_fill_beacon_or_proberesp_template
1642 ** Origin: derived from rt2x00 project
1644 static int
1645 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1646 struct acx_template_beacon *templ,
1647 struct sk_buff* skb /* in host order! */)
1649 FN_ENTER;
1651 memcpy(templ,skb->data, skb->len);
1652 FN_EXIT1(skb->len);
1653 return skb->len;
1656 /***********************************************************************
1657 ** acx_s_set_beacon_template
1661 static int
1662 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1664 struct acx_template_beacon bcn;
1665 int len, result;
1667 FN_ENTER;
1668 printk("Size of template: %08X, Size of beacon: %08X\n",sizeof(struct acx_template_beacon),skb->len);
1669 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1670 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1672 FN_EXIT1(result);
1673 return result;
1676 /***********************************************************************
1677 ** acx_cmd_join_bssid
1679 ** Common code for both acx100 and acx111.
1681 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1682 static const u8 bitpos2genframe_txrate[] = {
1683 10, /* 0. 1 Mbit/s */
1684 20, /* 1. 2 Mbit/s */
1685 55, /* 2. 5.5 Mbit/s */
1686 0x0B, /* 3. 6 Mbit/s */
1687 0x0F, /* 4. 9 Mbit/s */
1688 110, /* 5. 11 Mbit/s */
1689 0x0A, /* 6. 12 Mbit/s */
1690 0x0E, /* 7. 18 Mbit/s */
1691 220, /* 8. 22 Mbit/s */
1692 0x09, /* 9. 24 Mbit/s */
1693 0x0D, /* 10. 36 Mbit/s */
1694 0x08, /* 11. 48 Mbit/s */
1695 0x0C, /* 12. 54 Mbit/s */
1696 10, /* 13. 1 Mbit/s, should never happen */
1697 10, /* 14. 1 Mbit/s, should never happen */
1698 10, /* 15. 1 Mbit/s, should never happen */
1701 /* Looks scary, eh?
1702 ** Actually, each one compiled into one AND and one SHIFT,
1703 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1704 static inline unsigned int rate111to5bits(unsigned int rate)
1706 return (rate & 0x7)
1707 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1708 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1712 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1714 acx_joinbss_t tmp;
1715 int dtim_interval;
1716 int i;
1718 if (mac_is_zero(bssid))
1719 return;
1721 FN_ENTER;
1723 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1724 1 : adev->dtim_interval;
1726 memset(&tmp, 0, sizeof(tmp));
1728 for (i = 0; i < ETH_ALEN; i++) {
1729 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1732 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1734 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1735 ** are sent with one of these rates */
1736 if (IS_ACX111(adev)) {
1737 /* It was experimentally determined that rates_basic
1738 ** can take 11g rates as well, not only rates
1739 ** defined with JOINBSS_RATES_BASIC111_nnn.
1740 ** Just use RATE111_nnn constants... */
1741 tmp.u.acx111.dtim_interval = dtim_interval;
1742 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1743 log(L_ASSOC, "rates_basic:%04X, rates_supported:%04X\n",
1744 adev->rate_basic, adev->rate_oper);
1745 } else {
1746 tmp.u.acx100.dtim_interval = dtim_interval;
1747 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1748 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1749 log(L_ASSOC, "rates_basic:%04X->%02X, "
1750 "rates_supported:%04X->%02X\n",
1751 adev->rate_basic, tmp.u.acx100.rates_basic,
1752 adev->rate_oper, tmp.u.acx100.rates_supported);
1755 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1756 ** will be sent (rate/modulation/preamble) */
1757 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1758 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1759 /* we can use short pre *if* all peers can understand it */
1760 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1762 /* we switch fw to STA mode in MONITOR mode, it seems to be
1763 ** the only mode where fw does not emit beacons by itself
1764 ** but allows us to send anything (we really want to retain
1765 ** ability to tx arbitrary frames in MONITOR mode)
1767 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1768 tmp.channel = adev->channel;
1769 tmp.essid_len = adev->essid_len;
1771 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1772 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1774 log(L_ASSOC|L_DEBUG, "BSS_Type = %u\n", tmp.macmode);
1775 acxlog_mac(L_ASSOC|L_DEBUG, "JoinBSSID MAC:", adev->bssid, "\n");
1777 /* acx_update_capabilities(adev); */
1778 FN_EXIT0;
1781 /***********************************************************************
1782 ** acxpci_i_set_multicast_list
1783 ** FIXME: most likely needs refinement
1786 void acx_i_set_multicast_list(struct ieee80211_hw *hw,
1787 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1788 unsigned short netflags, int mc_count)
1789 #else
1790 unsigned int changed_flags,
1791 unsigned int *total_flags,
1792 int mc_count, struct dev_addr_list *mc_list)
1793 #endif
1795 acx_device_t *adev = ieee2adev(hw);
1796 unsigned long flags;
1798 FN_ENTER;
1800 acx_lock(adev, flags);
1802 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
1803 changed_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1804 FIF_CONTROL | FIF_OTHER_BSS);
1805 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1806 FIF_CONTROL | FIF_OTHER_BSS);
1807 /* if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1808 return; */
1809 #endif
1811 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1812 if (netflags & (IFF_PROMISC | IFF_ALLMULTI)) {
1813 #else
1814 if (*total_flags) {
1815 #endif
1816 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1817 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1818 SET_BIT(adev->set_mask, SET_RXCONFIG);
1819 /* let kernel know in case *we* needed to set promiscuous */
1820 } else {
1821 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1822 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1823 SET_BIT(adev->set_mask, SET_RXCONFIG);
1826 /* cannot update card settings directly here, atomic context */
1827 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
1829 acx_unlock(adev, flags);
1831 FN_EXIT0;
1834 /***********************************************************************
1835 ** acx111 feature config
1837 ** Obvious
1839 static int
1840 acx111_s_get_feature_config(acx_device_t * adev,
1841 u32 * feature_options, u32 * data_flow_options)
1843 struct acx111_ie_feature_config feat;
1845 FN_ENTER;
1847 if (!IS_ACX111(adev)) {
1848 return NOT_OK;
1851 memset(&feat, 0, sizeof(feat));
1853 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1854 FN_EXIT1(NOT_OK);
1855 return NOT_OK;
1857 log(L_DEBUG,
1858 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1859 feat.feature_options, feat.data_flow_options);
1861 if (feature_options)
1862 *feature_options = le32_to_cpu(feat.feature_options);
1863 if (data_flow_options)
1864 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1866 FN_EXIT0;
1867 return OK;
1871 static int
1872 acx111_s_set_feature_config(acx_device_t * adev,
1873 u32 feature_options, u32 data_flow_options,
1874 unsigned int mode
1875 /* 0 == remove, 1 == add, 2 == set */ )
1877 struct acx111_ie_feature_config feat;
1879 FN_ENTER;
1881 if (!IS_ACX111(adev)) {
1882 FN_EXIT1(NOT_OK);
1883 return NOT_OK;
1886 if ((mode < 0) || (mode > 2)) {
1887 FN_EXIT1(NOT_OK);
1888 return NOT_OK;
1891 if (mode != 2)
1892 /* need to modify old data */
1893 acx111_s_get_feature_config(adev, &feat.feature_options,
1894 &feat.data_flow_options);
1895 else {
1896 /* need to set a completely new value */
1897 feat.feature_options = 0;
1898 feat.data_flow_options = 0;
1901 if (mode == 0) { /* remove */
1902 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1903 CLEAR_BIT(feat.data_flow_options,
1904 cpu_to_le32(data_flow_options));
1905 } else { /* add or set */
1906 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1907 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1910 log(L_DEBUG,
1911 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1912 "new: feature 0x%08X dataflow 0x%08X\n",
1913 feature_options, data_flow_options, mode,
1914 le32_to_cpu(feat.feature_options),
1915 le32_to_cpu(feat.data_flow_options));
1917 if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1918 FN_EXIT1(NOT_OK);
1919 return NOT_OK;
1922 FN_EXIT0;
1923 return OK;
1926 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1928 return acx111_s_set_feature_config(adev, f, d, 0);
1930 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1932 return acx111_s_set_feature_config(adev, f, d, 1);
1934 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1936 return acx111_s_set_feature_config(adev, f, d, 2);
1940 /***********************************************************************
1941 ** acx100_s_init_memory_pools
1943 static int
1944 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1946 acx100_ie_memblocksize_t MemoryBlockSize;
1947 acx100_ie_memconfigoption_t MemoryConfigOption;
1948 int TotalMemoryBlocks;
1949 int RxBlockNum;
1950 int TotalRxBlockSize;
1951 int TxBlockNum;
1952 int TotalTxBlockSize;
1954 FN_ENTER;
1956 /* Let's see if we can follow this:
1957 first we select our memory block size (which I think is
1958 completely arbitrary) */
1959 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1961 /* Then we alert the card to our decision of block size */
1962 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
1963 goto bad;
1966 /* We figure out how many total blocks we can create, using
1967 the block size we chose, and the beginning and ending
1968 memory pointers, i.e.: end-start/size */
1969 TotalMemoryBlocks =
1970 (le32_to_cpu(mmt->PoolEnd) -
1971 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1973 log(L_DEBUG, "TotalMemoryBlocks=%u (%u bytes)\n",
1974 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1976 /* MemoryConfigOption.DMA_config bitmask:
1977 access to ACX memory is to be done:
1978 0x00080000 using PCI conf space?!
1979 0x00040000 using IO instructions?
1980 0x00000000 using memory access instructions
1981 0x00020000 using local memory block linked list (else what?)
1982 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1984 if (IS_PCI(adev)) {
1985 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1986 /* Declare start of the Rx host pool */
1987 MemoryConfigOption.pRxHostDesc =
1988 cpu2acx(adev->rxhostdesc_startphy);
1989 log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
1990 acx2cpu(MemoryConfigOption.pRxHostDesc),
1991 (long)adev->rxhostdesc_startphy);
1992 } else {
1993 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1996 /* 50% of the allotment of memory blocks go to tx descriptors */
1997 TxBlockNum = TotalMemoryBlocks / 2;
1998 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
2000 /* and 50% go to the rx descriptors */
2001 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
2002 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
2004 /* size of the tx and rx descriptor queues */
2005 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
2006 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
2007 log(L_DEBUG, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u "
2008 "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum,
2009 TotalTxBlockSize, TotalRxBlockSize);
2012 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
2013 MemoryConfigOption.rx_mem =
2014 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
2016 /* align the rx descriptor queue to units of 0x20
2017 * and offset it by the tx descriptor queue */
2018 MemoryConfigOption.tx_mem =
2019 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
2020 0x1f) & ~0x1f);
2021 log(L_DEBUG, "rx_mem %08X rx_mem %08X\n", MemoryConfigOption.tx_mem,
2022 MemoryConfigOption.rx_mem);
2024 /* alert the device to our decision */
2025 if (OK !=
2026 acx_s_configure(adev, &MemoryConfigOption,
2027 ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
2028 goto bad;
2031 /* and tell the device to kick it into gear */
2032 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
2033 goto bad;
2035 FN_EXIT1(OK);
2036 return OK;
2037 bad:
2038 FN_EXIT1(NOT_OK);
2039 return NOT_OK;
2043 /***********************************************************************
2044 ** acx100_s_create_dma_regions
2046 ** Note that this fn messes up heavily with hardware, but we cannot
2047 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2049 static int acx100_s_create_dma_regions(acx_device_t * adev)
2051 acx100_ie_queueconfig_t queueconf;
2052 acx_ie_memmap_t memmap;
2053 int res = NOT_OK;
2054 u32 tx_queue_start, rx_queue_start;
2056 FN_ENTER;
2058 /* read out the acx100 physical start address for the queues */
2059 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2060 goto fail;
2063 tx_queue_start = le32_to_cpu(memmap.QueueStart);
2064 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
2066 log(L_DEBUG, "initializing Queue Indicator\n");
2068 memset(&queueconf, 0, sizeof(queueconf));
2070 /* Not needed for PCI, so we can avoid setting them altogether */
2071 if (IS_USB(adev)) {
2072 queueconf.NumTxDesc = USB_TX_CNT;
2073 queueconf.NumRxDesc = USB_RX_CNT;
2076 /* calculate size of queues */
2077 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
2078 RX_CNT * sizeof(rxdesc_t) + 8);
2079 queueconf.NumTxQueues = 1; /* number of tx queues */
2080 /* sets the beginning of the tx descriptor queue */
2081 queueconf.TxQueueStart = memmap.QueueStart;
2082 /* done by memset: queueconf.TxQueuePri = 0; */
2083 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
2084 queueconf.QueueOptions = 1; /* auto reset descriptor */
2085 /* sets the end of the rx descriptor queue */
2086 queueconf.QueueEnd =
2087 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
2089 /* sets the beginning of the next queue */
2090 queueconf.HostQueueEnd =
2091 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
2092 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
2093 goto fail;
2096 if (IS_PCI(adev)) {
2097 /* sets the beginning of the rx descriptor queue, after the tx descrs */
2098 if (OK != acxpci_s_create_hostdesc_queues(adev))
2099 goto fail;
2100 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2103 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2104 goto fail;
2107 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
2108 0x1f) & ~0x1f);
2110 if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2111 goto fail;
2114 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
2115 goto fail;
2118 res = OK;
2119 goto end;
2121 fail:
2122 acx_s_mwait(1000); /* ? */
2123 if (IS_PCI(adev))
2124 acxpci_free_desc_queues(adev);
2125 end:
2126 FN_EXIT1(res);
2127 return res;
2131 /***********************************************************************
2132 ** acx111_s_create_dma_regions
2134 ** Note that this fn messes heavily with hardware, but we cannot
2135 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2137 #define ACX111_PERCENT(percent) ((percent)/5)
2139 static int acx111_s_create_dma_regions(acx_device_t * adev)
2141 struct acx111_ie_memoryconfig memconf;
2142 struct acx111_ie_queueconfig queueconf;
2143 u32 tx_queue_start, rx_queue_start;
2145 FN_ENTER;
2147 /* Calculate memory positions and queue sizes */
2149 /* Set up our host descriptor pool + data pool */
2150 if (IS_PCI(adev)) {
2151 if (OK != acxpci_s_create_hostdesc_queues(adev))
2152 goto fail;
2155 memset(&memconf, 0, sizeof(memconf));
2156 /* the number of STAs (STA contexts) to support
2157 ** NB: was set to 1 and everything seemed to work nevertheless... */
2158 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
2159 /* specify the memory block size. Default is 256 */
2160 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
2161 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
2162 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
2163 /* set the count of our queues
2164 ** NB: struct acx111_ie_memoryconfig shall be modified
2165 ** if we ever will switch to more than one rx and/or tx queue */
2166 memconf.count_rx_queues = 1;
2167 memconf.count_tx_queues = 1;
2168 /* 0 == Busmaster Indirect Memory Organization, which is what we want
2169 * (using linked host descs with their allocated mem).
2170 * 2 == Generic Bus Slave */
2171 /* done by memset: memconf.options = 0; */
2172 /* let's use 25% for fragmentations and 75% for frame transfers
2173 * (specified in units of 5%) */
2174 memconf.fragmentation = ACX111_PERCENT(75);
2175 /* Rx descriptor queue config */
2176 memconf.rx_queue1_count_descs = RX_CNT;
2177 memconf.rx_queue1_type = 7; /* must be set to 7 */
2178 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2179 if (IS_PCI(adev)) {
2180 memconf.rx_queue1_host_rx_start =
2181 cpu2acx(adev->rxhostdesc_startphy);
2183 /* Tx descriptor queue config */
2184 memconf.tx_queue1_count_descs = TX_CNT;
2185 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2187 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
2188 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2189 ** But it is actually correct wrt IE numbers.
2190 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
2191 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2192 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2193 if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
2194 goto fail;
2197 acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
2199 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2200 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2202 log(L_INIT, "dump queue head (from card):\n"
2203 "len: %u\n"
2204 "tx_memory_block_address: %X\n"
2205 "rx_memory_block_address: %X\n"
2206 "tx1_queue address: %X\n"
2207 "rx1_queue address: %X\n",
2208 le16_to_cpu(queueconf.len),
2209 le32_to_cpu(queueconf.tx_memory_block_address),
2210 le32_to_cpu(queueconf.rx_memory_block_address),
2211 tx_queue_start, rx_queue_start);
2213 if (IS_PCI(adev))
2214 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2216 FN_EXIT1(OK);
2217 return OK;
2218 fail:
2219 if (IS_PCI(adev))
2220 acxpci_free_desc_queues(adev);
2222 FN_EXIT1(NOT_OK);
2223 return NOT_OK;
2227 /***********************************************************************
2229 static void acx_s_initialize_rx_config(acx_device_t * adev)
2231 struct {
2232 u16 id;
2233 u16 len;
2234 u16 rx_cfg1;
2235 u16 rx_cfg2;
2236 } ACX_PACKED cfg;
2237 switch (adev->mode) {
2238 case ACX_MODE_MONITOR:
2239 adev->rx_config_1 = (u16) (0
2240 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2241 /* | RX_CFG1_FILTER_SSID */
2242 /* | RX_CFG1_FILTER_BCAST */
2243 /* | RX_CFG1_RCV_MC_ADDR1 */
2244 /* | RX_CFG1_RCV_MC_ADDR0 */
2245 /* | RX_CFG1_FILTER_ALL_MULTI */
2246 /* | RX_CFG1_FILTER_BSSID */
2247 /* | RX_CFG1_FILTER_MAC */
2248 | RX_CFG1_RCV_PROMISCUOUS
2249 | RX_CFG1_INCLUDE_FCS
2250 /* | RX_CFG1_INCLUDE_PHY_HDR */
2252 adev->rx_config_2 = (u16) (0
2253 | RX_CFG2_RCV_ASSOC_REQ
2254 | RX_CFG2_RCV_AUTH_FRAMES
2255 | RX_CFG2_RCV_BEACON_FRAMES
2256 | RX_CFG2_RCV_CONTENTION_FREE
2257 | RX_CFG2_RCV_CTRL_FRAMES
2258 | RX_CFG2_RCV_DATA_FRAMES
2259 | RX_CFG2_RCV_BROKEN_FRAMES
2260 | RX_CFG2_RCV_MGMT_FRAMES
2261 | RX_CFG2_RCV_PROBE_REQ
2262 | RX_CFG2_RCV_PROBE_RESP
2263 | RX_CFG2_RCV_ACK_FRAMES
2264 | RX_CFG2_RCV_OTHER);
2265 break;
2266 default:
2267 adev->rx_config_1 = (u16) (0
2268 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2269 /* | RX_CFG1_FILTER_SSID */
2270 /* | RX_CFG1_FILTER_BCAST */
2271 /* | RX_CFG1_RCV_MC_ADDR1 */
2272 /* | RX_CFG1_RCV_MC_ADDR0 */
2273 /* | RX_CFG1_FILTER_ALL_MULTI */
2274 /* | RX_CFG1_FILTER_BSSID */
2275 /* | RX_CFG1_FILTER_MAC */
2276 | RX_CFG1_RCV_PROMISCUOUS
2277 /* | RX_CFG1_INCLUDE_FCS */
2278 /* | RX_CFG1_INCLUDE_PHY_HDR */
2280 adev->rx_config_2 = (u16) (0
2281 | RX_CFG2_RCV_ASSOC_REQ
2282 | RX_CFG2_RCV_AUTH_FRAMES
2283 | RX_CFG2_RCV_BEACON_FRAMES
2284 | RX_CFG2_RCV_CONTENTION_FREE
2285 | RX_CFG2_RCV_CTRL_FRAMES
2286 | RX_CFG2_RCV_DATA_FRAMES
2287 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2288 | RX_CFG2_RCV_MGMT_FRAMES
2289 | RX_CFG2_RCV_PROBE_REQ
2290 | RX_CFG2_RCV_PROBE_RESP
2291 | RX_CFG2_RCV_ACK_FRAMES
2292 | RX_CFG2_RCV_OTHER);
2293 break;
2295 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2297 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2298 || (adev->firmware_numver >= 0x02000000))
2299 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2300 else
2301 adev->phy_header_len = 0;
2303 log(L_INIT, "setting RXconfig to %04X:%04X\n",
2304 adev->rx_config_1, adev->rx_config_2);
2305 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2306 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2307 acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
2311 /***********************************************************************
2312 ** acx_s_set_defaults
2314 void acx_s_set_defaults(acx_device_t * adev)
2316 unsigned long flags;
2318 FN_ENTER;
2320 acx_lock(adev, flags);
2321 /* do it before getting settings, prevent bogus channel 0 warning */
2322 adev->channel = 1;
2324 /* query some settings from the card.
2325 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2326 * query is REQUIRED, otherwise the card won't work correctly! */
2327 adev->get_mask =
2328 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2329 GETSET_REG_DOMAIN;
2330 /* Only ACX100 supports ED and CCA */
2331 if (IS_ACX100(adev))
2332 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2334 acx_s_update_card_settings(adev);
2337 /* set our global interrupt mask */
2338 if (IS_PCI(adev))
2339 acxpci_set_interrupt_mask(adev);
2341 adev->led_power = 1; /* LED is active on startup */
2342 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2343 adev->brange_time_last_state_change = jiffies;
2345 /* copy the MAC address we just got from the card
2346 * into our MAC address used during current 802.11 session */
2347 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
2348 MAC_BCAST(adev->ap);
2350 adev->essid_len =
2351 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2352 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2353 adev->essid_active = 1;
2355 /* we have a nick field to waste, so why not abuse it
2356 * to announce the driver version? ;-) */
2357 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2359 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2360 /* first regulatory domain entry in EEPROM == default reg. domain */
2361 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2364 /* 0xffff would be better, but then we won't get a "scan complete"
2365 * interrupt, so our current infrastructure will fail: */
2366 adev->scan_count = 1;
2367 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2368 adev->scan_duration = 100;
2369 adev->scan_probe_delay = 200;
2370 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2371 adev->scan_rate = ACX_SCAN_RATE_1;
2374 adev->mode = ACX_MODE_2_STA;
2375 adev->listen_interval = 100;
2376 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2377 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2379 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2381 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2382 adev->frag_threshold = 2346;
2384 /* use standard default values for retry limits */
2385 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2386 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2388 adev->preamble_mode = 2; /* auto */
2389 adev->fallback_threshold = 3;
2390 adev->stepup_threshold = 10;
2391 adev->rate_bcast = RATE111_1;
2392 adev->rate_bcast100 = RATE100_1;
2393 adev->rate_basic = RATE111_1 | RATE111_2;
2394 adev->rate_auto = 1;
2395 if (IS_ACX111(adev)) {
2396 adev->rate_oper = RATE111_ALL;
2397 } else {
2398 adev->rate_oper = RATE111_ACX100_COMPAT;
2401 /* Supported Rates element - the rates here are given in units of
2402 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2403 acx_l_update_ratevector(adev);
2405 /* set some more defaults */
2406 if (IS_ACX111(adev)) {
2407 /* 30mW (15dBm) is default, at least in my acx111 card: */
2408 adev->tx_level_dbm = 15;
2409 } else {
2410 /* don't use max. level, since it might be dangerous
2411 * (e.g. WRT54G people experience
2412 * excessive Tx power damage!) */
2413 adev->tx_level_dbm = 18;
2415 /* adev->tx_level_auto = 1; */
2416 if (IS_ACX111(adev)) {
2417 /* start with sensitivity level 1 out of 3: */
2418 adev->sensitivity = 1;
2421 /* #define ENABLE_POWER_SAVE */
2422 #ifdef ENABLE_POWER_SAVE
2423 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2424 adev->ps_listen_interval = 1;
2425 adev->ps_options =
2426 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2427 adev->ps_hangover_period = 30;
2428 adev->ps_enhanced_transition_time = 0;
2429 #else
2430 adev->ps_wakeup_cfg = 0;
2431 adev->ps_listen_interval = 0;
2432 adev->ps_options = 0;
2433 adev->ps_hangover_period = 0;
2434 adev->ps_enhanced_transition_time = 0;
2435 #endif
2437 /* These settings will be set in fw on ifup */
2438 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2439 /* configure card to do rate fallback when in auto rate mode */
2440 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2441 /* better re-init the antenna value we got above */
2442 | GETSET_ANTENNA
2443 #if POWER_SAVE_80211
2444 | GETSET_POWER_80211
2445 #endif
2448 acx_unlock(adev, flags);
2449 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2451 acx_s_initialize_rx_config(adev);
2453 FN_EXIT0;
2457 /***********************************************************************
2458 ** FIXME: this should be solved in a general way for all radio types
2459 ** by decoding the radio firmware module,
2460 ** since it probably has some standard structure describing how to
2461 ** set the power level of the radio module which it controls.
2462 ** Or maybe not, since the radio module probably has a function interface
2463 ** instead which then manages Tx level programming :-\
2465 ** Obvious
2467 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2469 struct acx111_ie_tx_level tx_level;
2471 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2472 * 1 (30mW) [15dBm]
2473 * 2 (10mW) [10dBm]
2474 * For now, just assume all other acx111 cards have the same.
2475 * FIXME: Ideally we would query it here, but we first need a
2476 * standard way to query individual configoptions easily.
2477 * Well, now we have proper cfgopt txpower variables, but this still
2478 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2479 if (level_dbm <= 12) {
2480 tx_level.level = 2; /* 10 dBm */
2481 adev->tx_level_dbm = 10;
2482 } else {
2483 tx_level.level = 1; /* 15 dBm */
2484 adev->tx_level_dbm = 15;
2486 /* if (level_dbm != adev->tx_level_dbm)
2487 log(L_INIT, "acx111 firmware has specific "
2488 "power levels only: adjusted %d dBm to %d dBm!\n",
2489 level_dbm, adev->tx_level_dbm);
2491 return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
2494 static int acx_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2496 if (IS_ACX111(adev)) {
2497 return acx111_s_set_tx_level(adev, level_dbm);
2499 if (IS_PCI(adev)) {
2500 return acx100pci_s_set_tx_level(adev, level_dbm);
2502 return OK;
2505 /***********************************************************************
2506 ** acx_l_process_rxbuf
2508 ** NB: used by USB code also
2510 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2512 struct ieee80211_hdr *hdr;
2513 u16 fc, buf_len;
2514 hdr = acx_get_wlan_hdr(adev, rxbuf);
2515 fc = le16_to_cpu(hdr->frame_control);
2516 /* length of frame from control field to first byte of FCS */
2517 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2519 if (unlikely(acx_debug & L_DATA)) {
2520 printk("rx: 802.11 buf[%u]: \n", buf_len);
2521 acx_dump_bytes(hdr, buf_len);
2525 acx_l_rx(adev, rxbuf);
2526 /* Now check Rx quality level, AFTER processing packet.
2527 * I tried to figure out how to map these levels to dBm
2528 * values, but for the life of me I really didn't
2529 * manage to get it. Either these values are not meant to
2530 * be expressed in dBm, or it's some pretty complicated
2531 * calculation. */
2533 #ifdef FROM_SCAN_SOURCE_ONLY
2534 /* only consider packets originating from the MAC
2535 * address of the device that's managing our BSSID.
2536 * Disable it for now, since it removes information (levels
2537 * from different peers) and slows the Rx path. *//*
2538 if (adev->ap_client && mac_is_equal(hdr->a2, adev->ap_client->address)) {
2540 #endif
2544 /***********************************************************************
2545 ** acx_l_handle_txrate_auto
2547 ** Theory of operation:
2548 ** client->rate_cap is a bitmask of rates client is capable of.
2549 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2550 ** It is set as a result of iwconfig rate N [auto]
2551 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2552 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2553 ** auto (0x00ff == 18Mbit or any lower value),
2554 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2556 ** client->rate_cur is a value for rate111 field in tx descriptor.
2557 ** It is always set to txrate_cfg sans zero or more most significant
2558 ** bits. This routine handles selection of new rate_cur value depending on
2559 ** outcome of last tx event.
2561 ** client->rate_100 is a precalculated rate value for acx100
2562 ** (we can do without it, but will need to calculate it on each tx).
2564 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2565 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2566 ** In theory you can implement it, but so far it is considered not worth doing.
2568 ** 22Mbit, of course, is PBCC always. */
2570 /* maps acx100 tx descr rate field to acx111 one */
2572 static u16 rate100to111(u8 r)
2574 switch (r) {
2575 case RATE100_1:
2576 return RATE111_1;
2577 case RATE100_2:
2578 return RATE111_2;
2579 case RATE100_5:
2580 case (RATE100_5 | RATE100_PBCC511):
2581 return RATE111_5;
2582 case RATE100_11:
2583 case (RATE100_11 | RATE100_PBCC511):
2584 return RATE111_11;
2585 case RATE100_22:
2586 return RATE111_22;
2587 default:
2588 printk("acx: unexpected acx100 txrate: %u! "
2589 "Please report\n", r);
2590 return RATE111_1;
2597 acx_i_start_xmit(struct ieee80211_hw *hw,
2598 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2600 acx_device_t *adev = ieee2adev(hw);
2601 tx_t *tx;
2602 void *txbuf;
2603 unsigned long flags;
2605 int txresult = NOT_OK;
2607 FN_ENTER;
2609 if (unlikely(!skb)) {
2610 /* indicate success */
2611 txresult = OK;
2612 goto end_no_unlock;
2615 if (unlikely(!adev)) {
2616 goto end_no_unlock;
2620 acx_lock(adev, flags);
2622 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2623 goto end;
2625 if (unlikely(!adev->initialized)) {
2626 goto end;
2629 tx = acx_l_alloc_tx(adev);
2631 if (unlikely(!tx)) {
2632 printk_ratelimited("%s: start_xmit: txdesc ring is full, "
2633 "dropping tx\n", wiphy_name(adev->ieee->wiphy));
2634 txresult = NOT_OK;
2635 goto end;
2638 txbuf = acx_l_get_txbuf(adev, tx);
2640 if (unlikely(!txbuf)) {
2641 /* Card was removed */
2642 txresult = NOT_OK;
2643 acx_l_dealloc_tx(adev, tx);
2644 goto end;
2646 memcpy(txbuf, skb->data, skb->len);
2648 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2650 txresult = OK;
2651 adev->stats.tx_packets++;
2652 adev->stats.tx_bytes += skb->len;
2654 end:
2655 acx_unlock(adev, flags);
2657 end_no_unlock:
2659 FN_EXIT1(txresult);
2660 return txresult;
2662 /***********************************************************************
2663 ** acx_l_update_ratevector
2665 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2667 const u8 acx_bitpos2ratebyte[] = {
2668 DOT11RATEBYTE_1,
2669 DOT11RATEBYTE_2,
2670 DOT11RATEBYTE_5_5,
2671 DOT11RATEBYTE_6_G,
2672 DOT11RATEBYTE_9_G,
2673 DOT11RATEBYTE_11,
2674 DOT11RATEBYTE_12_G,
2675 DOT11RATEBYTE_18_G,
2676 DOT11RATEBYTE_22,
2677 DOT11RATEBYTE_24_G,
2678 DOT11RATEBYTE_36_G,
2679 DOT11RATEBYTE_48_G,
2680 DOT11RATEBYTE_54_G,
2683 void acx_l_update_ratevector(acx_device_t * adev)
2685 u16 bcfg = adev->rate_basic;
2686 u16 ocfg = adev->rate_oper;
2687 u8 *supp = adev->rate_supported;
2688 const u8 *dot11 = acx_bitpos2ratebyte;
2690 FN_ENTER;
2692 while (ocfg) {
2693 if (ocfg & 1) {
2694 *supp = *dot11;
2695 if (bcfg & 1) {
2696 *supp |= 0x80;
2698 supp++;
2700 dot11++;
2701 ocfg >>= 1;
2702 bcfg >>= 1;
2704 adev->rate_supported_len = supp - adev->rate_supported;
2705 if (acx_debug & L_ASSOC) {
2706 printk("new ratevector: ");
2707 acx_dump_bytes(adev->rate_supported, adev->rate_supported_len);
2709 FN_EXIT0;
2712 /***********************************************************************
2713 ** acx_i_timer
2715 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2717 ** Obvious
2719 void acx_i_timer(unsigned long address)
2721 unsigned long flags;
2722 acx_device_t *adev = (acx_device_t *) address;
2724 FN_ENTER;
2726 acx_lock(adev, flags);
2728 FIXME();
2729 /* We need calibration and stats gather tasks to perform here */
2731 acx_unlock(adev, flags);
2733 FN_EXIT0;
2737 /***********************************************************************
2738 ** acx_set_timer
2740 ** Sets the 802.11 state management timer's timeout.
2742 ** Linux derived
2744 void acx_set_timer(acx_device_t * adev, int timeout_us)
2746 FN_ENTER;
2748 log(L_DEBUG | L_IRQ, "%s(%u ms)\n", __func__, timeout_us / 1000);
2749 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2750 printk("attempt to set the timer "
2751 "when the card interface is not up!\n");
2752 goto end;
2755 /* first check if the timer was already initialized, THEN modify it */
2756 if (adev->mgmt_timer.function) {
2757 mod_timer(&adev->mgmt_timer,
2758 jiffies + (timeout_us * HZ / 1000000));
2760 end:
2761 FN_EXIT0;
2764 /** acx_plcp_get_bitrate_cck
2766 ** Obvious
2768 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2770 switch (plcp) {
2771 case 0x0A:
2772 return ACX_CCK_RATE_1MB;
2773 case 0x14:
2774 return ACX_CCK_RATE_2MB;
2775 case 0x37:
2776 return ACX_CCK_RATE_5MB;
2777 case 0x6E:
2778 return ACX_CCK_RATE_11MB;
2780 return 0;
2783 /* Extract the bitrate out of an OFDM PLCP header. */
2784 /** Obvious **/
2785 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2787 switch (plcp & 0xF) {
2788 case 0xB:
2789 return ACX_OFDM_RATE_6MB;
2790 case 0xF:
2791 return ACX_OFDM_RATE_9MB;
2792 case 0xA:
2793 return ACX_OFDM_RATE_12MB;
2794 case 0xE:
2795 return ACX_OFDM_RATE_18MB;
2796 case 0x9:
2797 return ACX_OFDM_RATE_24MB;
2798 case 0xD:
2799 return ACX_OFDM_RATE_36MB;
2800 case 0x8:
2801 return ACX_OFDM_RATE_48MB;
2802 case 0xC:
2803 return ACX_OFDM_RATE_54MB;
2805 return 0;
2809 /***********************************************************************
2810 ** acx_l_rx
2812 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2813 ** buffer and feeds it to the network stack via netif_rx().
2815 ** Look to bcm43xx or p54
2817 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2820 struct ieee80211_rx_status* status = &adev->rx_status;
2821 struct ieee80211_hdr *w_hdr;
2822 int buflen;
2823 FN_ENTER;
2825 if (likely(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2826 struct sk_buff *skb;
2827 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2828 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2829 skb = dev_alloc_skb(buflen + 2);
2830 skb_reserve(skb, 2);
2831 skb_put(skb, buflen);
2832 memcpy(skb->data, w_hdr, buflen);
2834 // memset(&status, 0, sizeof(status));
2836 if (likely(skb)) {
2837 adev->acx_stats.last_rx = jiffies;
2838 status->mactime = rxbuf->time;
2839 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2840 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr);
2841 status->flag = 0;
2842 status->rate = rxbuf->phy_plcp_signal;
2843 status->antenna = 1;
2845 #ifndef OLD_QUALITY
2846 qual = acx_signal_determine_quality(adev->wstats.qual.level,
2847 adev->wstats.qual.noise);
2848 #else
2849 qual = (adev->wstats.qual.noise <= 100) ?
2850 100 - adev->wstats.qual.noise : 0;
2851 #endif
2852 adev->wstats.qual.qual = qual;
2853 adev->wstats.qual.updated = 7; *//* all 3 indicators updated */
2855 #ifdef FROM_SCAN_SOURCE_ONLY
2857 #endif
2859 if (rxbuf->phy_stat_baseband & (1 << 3)) /* Uses OFDM */
2861 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2862 } else
2864 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2866 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2867 adev->stats.rx_packets++;
2868 adev->stats.rx_bytes += skb->len;
2871 FN_EXIT0;
2876 /***********************************************************************
2877 ** acx_s_read_fw
2879 ** Loads a firmware image
2881 ** Returns:
2882 ** 0 unable to load file
2883 ** pointer to firmware success
2885 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2886 u32 * size)
2888 firmware_image_t *res;
2889 const struct firmware *fw_entry;
2891 res = NULL;
2892 log(L_INIT, "requesting firmware image '%s'\n", file);
2893 if (!request_firmware(&fw_entry, file, dev)) {
2894 *size = 8;
2895 if (fw_entry->size >= 8)
2896 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2897 if (fw_entry->size != *size) {
2898 printk("acx: firmware size does not match "
2899 "firmware header: %d != %d, "
2900 "aborting fw upload\n",
2901 (int)fw_entry->size, (int)*size);
2902 goto release_ret;
2904 res = vmalloc(*size);
2905 if (!res) {
2906 printk("acx: no memory for firmware "
2907 "(%u bytes)\n", *size);
2908 goto release_ret;
2910 memcpy(res, fw_entry->data, fw_entry->size);
2911 release_ret:
2912 release_firmware(fw_entry);
2913 return res;
2915 printk("acx: firmware image '%s' was not provided. "
2916 "Check your hotplug scripts\n", file);
2918 /* checksum will be verified in write_fw, so don't bother here */
2919 return res;
2923 /***********************************************************************
2924 ** acx_s_set_wepkey
2926 static void acx100_s_set_wepkey(acx_device_t * adev)
2928 ie_dot11WEPDefaultKey_t dk;
2929 int i;
2931 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2932 if (adev->wep_keys[i].size != 0) {
2933 log(L_INIT, "setting WEP key: %d with "
2934 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2935 dk.action = 1;
2936 dk.keySize = adev->wep_keys[i].size;
2937 dk.defaultKeyNum = i;
2938 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2939 acx_s_configure(adev, &dk,
2940 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
2945 static void acx111_s_set_wepkey(acx_device_t * adev)
2947 acx111WEPDefaultKey_t dk;
2948 int i;
2950 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2951 if (adev->wep_keys[i].size != 0) {
2952 log(L_INIT, "setting WEP key: %d with "
2953 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2954 memset(&dk, 0, sizeof(dk));
2955 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2956 dk.keySize = adev->wep_keys[i].size;
2958 /* are these two lines necessary? */
2959 dk.type = 0; /* default WEP key */
2960 dk.index = 0; /* ignored when setting default key */
2962 dk.defaultKeyNum = i;
2963 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2964 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2965 sizeof(dk));
2969 /* Obvious */
2970 static void acx_s_set_wepkey(acx_device_t * adev)
2972 if (IS_ACX111(adev))
2973 acx111_s_set_wepkey(adev);
2974 else
2975 acx100_s_set_wepkey(adev);
2979 /***********************************************************************
2980 ** acx100_s_init_wep
2982 ** FIXME: this should probably be moved into the new card settings
2983 ** management, but since we're also modifying the memory map layout here
2984 ** due to the WEP key space we want, we should take care...
2986 static int acx100_s_init_wep(acx_device_t * adev)
2988 acx100_ie_wep_options_t options;
2989 ie_dot11WEPDefaultKeyID_t dk;
2990 acx_ie_memmap_t pt;
2991 int res = NOT_OK;
2993 FN_ENTER;
2995 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2996 goto fail;
2999 log(L_DEBUG, "CodeEnd:%X\n", pt.CodeEnd);
3001 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
3002 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
3004 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
3005 goto fail;
3008 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
3009 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3010 options.WEPOption = 0x00;
3012 log(L_ASSOC, "writing WEP options\n");
3013 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3015 acx100_s_set_wepkey(adev);
3017 if (adev->wep_keys[adev->wep_current_index].size != 0) {
3018 log(L_ASSOC, "setting active default WEP key number: %d\n",
3019 adev->wep_current_index);
3020 dk.KeyID = adev->wep_current_index;
3021 acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
3023 /* FIXME!!! wep_key_struct is filled nowhere! But adev
3024 * is initialized to 0, and we don't REALLY need those keys either */
3025 /* for (i = 0; i < 10; i++) {
3026 if (adev->wep_key_struct[i].len != 0) {
3027 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
3028 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
3029 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
3030 wep_mgmt.Action = cpu_to_le16(1);
3031 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
3032 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
3033 adev->wep_key_struct[i].index = i;
3039 /* now retrieve the updated WEPCacheEnd pointer... */
3040 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
3041 printk("%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
3042 wiphy_name(adev->ieee->wiphy));
3043 goto fail;
3045 /* ...and tell it to start allocating templates at that location */
3046 /* (no endianness conversion needed) */
3047 pt.PacketTemplateStart = pt.WEPCacheEnd;
3049 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
3050 printk("%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
3051 wiphy_name(adev->ieee->wiphy));
3052 goto fail;
3054 res = OK;
3056 fail:
3057 FN_EXIT1(res);
3058 return res;
3062 static int
3063 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
3064 unsigned int cmd)
3066 int res;
3067 union {
3068 acx_template_nullframe_t null;
3069 acx_template_beacon_t b;
3070 acx_template_tim_t tim;
3071 acx_template_probereq_t preq;
3072 acx_template_proberesp_t presp;
3073 } templ;
3075 memset(&templ, 0, len);
3076 templ.null.size = cpu_to_le16(len - 2);
3077 res = acx_s_issue_cmd(adev, cmd, &templ, len);
3078 return res;
3081 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
3083 return acx_s_init_max_template_generic(adev,
3084 sizeof(acx_template_nullframe_t),
3085 ACX1xx_CMD_CONFIG_NULL_DATA);
3088 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
3090 return acx_s_init_max_template_generic(adev,
3091 sizeof(acx_template_beacon_t),
3092 ACX1xx_CMD_CONFIG_BEACON);
3095 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
3097 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
3098 ACX1xx_CMD_CONFIG_TIM);
3101 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
3103 return acx_s_init_max_template_generic(adev,
3104 sizeof(acx_template_proberesp_t),
3105 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
3108 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
3110 return acx_s_init_max_template_generic(adev,
3111 sizeof(acx_template_probereq_t),
3112 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
3115 /***********************************************************************
3116 ** acx_s_set_tim_template
3118 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
3119 ** by calling this function
3120 ** (it can be done by irq handler on each DTIM irq or by timer...)
3122 [802.11 7.3.2.6] TIM information element:
3123 - 1 EID
3124 - 1 Length
3125 1 1 DTIM Count
3126 indicates how many beacons (including this) appear before next DTIM
3127 (0=this one is a DTIM)
3128 2 1 DTIM Period
3129 number of beacons between successive DTIMs
3130 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
3131 3 1 Bitmap Control
3132 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
3133 set to 1 in TIM elements with a value of 0 in the DTIM Count field
3134 when one or more broadcast or multicast frames are buffered at the AP.
3135 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
3136 4 n Partial Virtual Bitmap
3137 Visible part of traffic-indication bitmap.
3138 Full bitmap consists of 2008 bits (251 octets) such that bit number N
3139 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
3140 in octet number N/8 where the low-order bit of each octet is bit0,
3141 and the high order bit is bit7.
3142 Each set bit in virtual bitmap corresponds to traffic buffered by AP
3143 for a specific station (with corresponding AID?).
3144 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
3145 Bitmap Offset is a number of skipped zero octets (see above).
3146 'Missing' octets at the tail are also assumed to be zero.
3147 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
3148 This means that traffic-indication bitmap is:
3149 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
3150 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
3152 static int acx_s_set_tim_template(acx_device_t * adev)
3154 /* For now, configure smallish test bitmap, all zero ("no pending data") */
3155 enum { bitmap_size = 5 };
3157 acx_template_tim_t t;
3158 int result;
3160 FN_ENTER;
3162 memset(&t, 0, sizeof(t));
3163 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3164 t.tim_eid = WLAN_EID_TIM;
3165 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3166 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3167 FN_EXIT1(result);
3168 return result;
3174 #if POWER_SAVE_80211
3175 /***********************************************************************
3176 ** acx_s_set_null_data_template
3178 static int acx_s_set_null_data_template(acx_device_t * adev)
3180 struct acx_template_nullframe b;
3181 int result;
3183 FN_ENTER;
3185 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3187 b.size = cpu_to_le16(sizeof(b) - 2);
3188 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3189 b.hdr.dur = 0;
3190 MAC_BCAST(b.hdr.a1);
3191 MAC_COPY(b.hdr.a2, adev->dev_addr);
3192 MAC_COPY(b.hdr.a3, adev->bssid);
3193 b.hdr.seq = 0;
3195 result =
3196 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3198 FN_EXIT1(result);
3199 return result;
3201 #endif
3208 /***********************************************************************
3209 ** acx_s_init_packet_templates()
3211 ** NOTE: order is very important here, to have a correct memory layout!
3212 ** init templates: max Probe Request (station mode), max NULL data,
3213 ** max Beacon, max TIM, max Probe Response.
3215 static int acx_s_init_packet_templates(acx_device_t * adev)
3217 acx_ie_memmap_t mm; /* ACX100 only */
3218 int result = NOT_OK;
3220 FN_ENTER;
3222 log(L_DEBUG | L_INIT, "initializing max packet templates\n");
3224 if (OK != acx_s_init_max_probe_request_template(adev))
3225 goto failed;
3227 if (OK != acx_s_init_max_null_data_template(adev))
3228 goto failed;
3230 if (OK != acx_s_init_max_beacon_template(adev))
3231 goto failed;
3233 if (OK != acx_s_init_max_tim_template(adev))
3234 goto failed;
3236 if (OK != acx_s_init_max_probe_response_template(adev))
3237 goto failed;
3239 if (IS_ACX111(adev)) {
3240 /* ACX111 doesn't need the memory map magic below,
3241 * and the other templates will be set later (acx_start) */
3242 result = OK;
3243 goto success;
3246 /* ACX100 will have its TIM template set,
3247 * and we also need to update the memory map */
3249 if (OK != acx_s_set_tim_template(adev))
3250 goto failed_acx100;
3252 log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3254 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3255 goto failed_acx100;
3257 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3258 if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3259 goto failed_acx100;
3261 result = OK;
3262 goto success;
3264 failed_acx100:
3265 log(L_DEBUG | L_INIT,
3266 /* "cb=0x%X\n" */
3267 "ACXMemoryMap:\n"
3268 ".CodeStart=0x%X\n"
3269 ".CodeEnd=0x%X\n"
3270 ".WEPCacheStart=0x%X\n"
3271 ".WEPCacheEnd=0x%X\n"
3272 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3273 /* len, */
3274 le32_to_cpu(mm.CodeStart),
3275 le32_to_cpu(mm.CodeEnd),
3276 le32_to_cpu(mm.WEPCacheStart),
3277 le32_to_cpu(mm.WEPCacheEnd),
3278 le32_to_cpu(mm.PacketTemplateStart),
3279 le32_to_cpu(mm.PacketTemplateEnd));
3281 failed:
3282 printk("%s: %s() FAILED\n", wiphy_name(adev->ieee->wiphy), __func__);
3284 success:
3285 FN_EXIT1(result);
3286 return result;
3291 /***********************************************************************
3292 ** acx_s_init_mac
3294 int acx_s_init_mac(acx_device_t * adev)
3296 int result = NOT_OK;
3298 FN_ENTER;
3300 if (IS_ACX111(adev)) {
3301 adev->ie_len = acx111_ie_len;
3302 adev->ie_len_dot11 = acx111_ie_len_dot11;
3303 } else {
3304 adev->ie_len = acx100_ie_len;
3305 adev->ie_len_dot11 = acx100_ie_len_dot11;
3308 if (IS_PCI(adev)) {
3309 adev->memblocksize = 256; /* 256 is default */
3310 /* try to load radio for both ACX100 and ACX111, since both
3311 * chips have at least some firmware versions making use of an
3312 * external radio module */
3313 acxpci_s_upload_radio(adev);
3314 } else {
3315 adev->memblocksize = 128;
3318 if (IS_ACX111(adev)) {
3319 /* for ACX111, the order is different from ACX100
3320 1. init packet templates
3321 2. create station context and create dma regions
3322 3. init wep default keys
3324 if (OK != acx_s_init_packet_templates(adev))
3325 goto fail;
3326 if (OK != acx111_s_create_dma_regions(adev)) {
3327 printk("%s: acx111_create_dma_regions FAILED\n",
3328 wiphy_name(adev->ieee->wiphy));
3329 goto fail;
3331 } else {
3332 if (OK != acx100_s_init_wep(adev))
3333 goto fail;
3334 if (OK != acx_s_init_packet_templates(adev))
3335 goto fail;
3336 if (OK != acx100_s_create_dma_regions(adev)) {
3337 printk("%s: acx100_create_dma_regions FAILED\n",
3338 wiphy_name(adev->ieee->wiphy));
3339 goto fail;
3343 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3344 result = OK;
3346 fail:
3347 if (result)
3348 printk("acx: init_mac() FAILED\n");
3349 FN_EXIT1(result);
3350 return result;
3355 #if POWER_SAVE_80211
3356 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3358 /* merge both structs in a union to be able to have common code */
3359 union {
3360 acx111_ie_powersave_t acx111;
3361 acx100_ie_powersave_t acx100;
3362 } pm;
3364 /* change 802.11 power save mode settings */
3365 log(L_INIT, "updating 802.11 power save mode settings: "
3366 "wakeup_cfg 0x%02X, listen interval %u, "
3367 "options 0x%02X, hangover period %u, "
3368 "enhanced_ps_transition_time %u\n",
3369 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3370 adev->ps_options, adev->ps_hangover_period,
3371 adev->ps_enhanced_transition_time);
3372 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3373 log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, "
3374 "listen interval %u, options 0x%02X, "
3375 "hangover period %u, "
3376 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3377 pm.acx111.wakeup_cfg,
3378 pm.acx111.listen_interval,
3379 pm.acx111.options,
3380 pm.acx111.hangover_period,
3381 IS_ACX111(adev) ?
3382 pm.acx111.enhanced_ps_transition_time
3383 : pm.acx100.enhanced_ps_transition_time,
3384 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3385 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3386 pm.acx111.listen_interval = adev->ps_listen_interval;
3387 pm.acx111.options = adev->ps_options;
3388 pm.acx111.hangover_period = adev->ps_hangover_period;
3389 if (IS_ACX111(adev)) {
3390 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3391 pm.acx111.enhanced_ps_transition_time =
3392 cpu_to_le32(adev->ps_enhanced_transition_time);
3393 } else {
3394 pm.acx100.enhanced_ps_transition_time =
3395 cpu_to_le16(adev->ps_enhanced_transition_time);
3397 acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT);
3398 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3399 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3400 acx_s_mwait(40);
3401 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3402 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3403 log(L_INIT, "power save mode change %s\n",
3404 (pm.acx111.
3405 wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful");
3406 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3407 * that power save mode change was successful. */
3408 /* FIXME: we shouldn't trigger a scan immediately after
3409 * fiddling with power save mode (since the firmware is sending
3410 * a NULL frame then). */
3412 #endif
3415 /***********************************************************************
3416 ** acx_s_update_card_settings
3418 ** Applies accumulated changes in various adev->xxxx members
3419 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3420 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3422 void acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
3424 unsigned mask;
3426 unsigned int i;
3428 for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
3429 if (acx_reg_domain_ids[i] == adev->reg_dom_id)
3430 break;
3432 if (sizeof(acx_reg_domain_ids) == i) {
3433 log(L_INIT, "Invalid or unsupported regulatory domain"
3434 " 0x%02X specified, falling back to FCC (USA)!"
3435 " Please report if this sounds fishy!\n",
3436 adev->reg_dom_id);
3437 i = 0;
3438 adev->reg_dom_id = acx_reg_domain_ids[i];
3440 /* since there was a mismatch, we need to force updating */
3441 do_set = 1;
3444 if (do_set) {
3445 acx_ie_generic_t dom;
3446 dom.m.bytes[0] = adev->reg_dom_id;
3447 acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3450 adev->reg_dom_chanmask = reg_domain_channel_masks[i];
3452 mask = (1 << (adev->channel - 1));
3453 if (!(adev->reg_dom_chanmask & mask)) {
3454 /* hmm, need to adjust our channel to reside within domain */
3455 mask = 1;
3456 for (i = 1; i <= 14; i++) {
3457 if (adev->reg_dom_chanmask & mask) {
3458 printk("%s: adjusting selected channel from %d "
3459 "to %d due to new regulatory domain\n",
3460 wiphy_name(adev->ieee->wiphy), adev->channel, i);
3461 adev->channel = i;
3462 break;
3464 mask <<= 1;
3469 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3471 u32 feature1, feature2;
3473 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3474 printk("%s: invalid sensitivity setting (1..3), "
3475 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3476 adev->sensitivity = 1;
3478 acx111_s_get_feature_config(adev, &feature1, &feature2);
3479 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3480 if (adev->sensitivity > 1)
3481 SET_BIT(feature1, FEATURE1_LOW_RX);
3482 if (adev->sensitivity > 2)
3483 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3484 acx111_s_feature_set(adev, feature1, feature2);
3488 void acx_s_update_card_settings(acx_device_t *adev)
3490 unsigned long flags;
3491 unsigned int start_scan = 0;
3492 int i;
3494 FN_ENTER;
3496 log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3497 adev->get_mask, adev->set_mask);
3499 /* Track dependencies betweed various settings */
3501 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3502 log(L_INIT, "important setting has been changed. "
3503 "Need to update packet templates, too\n");
3504 SET_BIT(adev->set_mask, SET_TEMPLATES);
3506 if (adev->set_mask & GETSET_CHANNEL) {
3507 /* This will actually tune RX/TX to the channel */
3508 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3509 switch (adev->mode) {
3510 case ACX_MODE_0_ADHOC:
3511 case ACX_MODE_3_AP:
3512 /* Beacons contain channel# - update them */
3513 SET_BIT(adev->set_mask, SET_TEMPLATES);
3516 switch (adev->mode) {
3517 case ACX_MODE_0_ADHOC:
3518 case ACX_MODE_2_STA:
3519 start_scan = 1;
3523 /* Apply settings */
3526 if (adev->get_mask & GETSET_STATION_ID) {
3527 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3528 const u8 *paddr;
3530 acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3531 paddr = &stationID[4];
3532 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3533 for (i = 0; i < ETH_ALEN; i++) {
3534 /* we copy the MAC address (reversed in
3535 * the card) to the netdevice's MAC
3536 * address, and on ifup it will be
3537 * copied into iwadev->dev_addr */
3538 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3540 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3541 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3544 if (adev->get_mask & GETSET_SENSITIVITY) {
3545 if ((RADIO_RFMD_11 == adev->radio_type)
3546 || (RADIO_MAXIM_0D == adev->radio_type)
3547 || (RADIO_RALINK_15 == adev->radio_type)) {
3548 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3549 } else {
3550 log(L_INIT, "don't know how to get sensitivity "
3551 "for radio type 0x%02X\n", adev->radio_type);
3552 adev->sensitivity = 0;
3554 log(L_INIT, "got sensitivity value %u\n", adev->sensitivity);
3556 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3559 if (adev->get_mask & GETSET_ANTENNA) {
3560 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3562 memset(antenna, 0, sizeof(antenna));
3563 acx_s_interrogate(adev, antenna,
3564 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3565 adev->antenna = antenna[4];
3566 log(L_INIT, "got antenna value 0x%02X\n", adev->antenna);
3567 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3570 if (adev->get_mask & GETSET_ED_THRESH) {
3571 if (IS_ACX100(adev)) {
3572 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3574 memset(ed_threshold, 0, sizeof(ed_threshold));
3575 acx_s_interrogate(adev, ed_threshold,
3576 ACX100_IE_DOT11_ED_THRESHOLD);
3577 adev->ed_threshold = ed_threshold[4];
3578 } else {
3579 log(L_INIT, "acx111 doesn't support ED\n");
3580 adev->ed_threshold = 0;
3582 log(L_INIT, "got Energy Detect (ED) threshold %u\n",
3583 adev->ed_threshold);
3584 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3587 if (adev->get_mask & GETSET_CCA) {
3588 if (IS_ACX100(adev)) {
3589 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3591 memset(cca, 0, sizeof(adev->cca));
3592 acx_s_interrogate(adev, cca,
3593 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3594 adev->cca = cca[4];
3595 } else {
3596 log(L_INIT, "acx111 doesn't support CCA\n");
3597 adev->cca = 0;
3599 log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n",
3600 adev->cca);
3601 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3604 if (adev->get_mask & GETSET_REG_DOMAIN) {
3605 acx_ie_generic_t dom;
3607 acx_s_interrogate(adev, &dom,
3608 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3609 adev->reg_dom_id = dom.m.bytes[0];
3610 acx_s_set_sane_reg_domain(adev, 0);
3611 log(L_INIT, "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3612 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3615 if (adev->set_mask & GETSET_STATION_ID) {
3616 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3617 u8 *paddr;
3619 paddr = &stationID[4];
3620 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3621 for (i = 0; i < ETH_ALEN; i++) {
3622 /* copy the MAC address we obtained when we noticed
3623 * that the ethernet iface's MAC changed
3624 * to the card (reversed in
3625 * the card!) */
3626 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3628 acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3629 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3632 if (adev->set_mask & SET_STA_LIST) {
3633 acx_lock(adev, flags);
3634 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3635 acx_unlock(adev, flags);
3637 if (adev->set_mask & SET_RATE_FALLBACK) {
3638 u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
3640 /* configure to not do fallbacks when not in auto rate mode */
3641 rate[4] =
3642 (adev->
3643 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3644 log(L_INIT, "updating Tx fallback to %u retries\n", rate[4]);
3645 acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK);
3646 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3648 if (adev->set_mask & GETSET_TXPOWER) {
3649 log(L_INIT, "updating transmit power: %u dBm\n",
3650 adev->tx_level_dbm);
3651 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3652 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3655 if (adev->set_mask & GETSET_SENSITIVITY) {
3656 log(L_INIT, "updating sensitivity value: %u\n",
3657 adev->sensitivity);
3658 switch (adev->radio_type) {
3659 case RADIO_RFMD_11:
3660 case RADIO_MAXIM_0D:
3661 case RADIO_RALINK_15:
3662 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3663 break;
3664 case RADIO_RADIA_16:
3665 case RADIO_UNKNOWN_17:
3666 acx111_s_sens_radio_16_17(adev);
3667 break;
3668 default:
3669 log(L_INIT, "don't know how to modify sensitivity "
3670 "for radio type 0x%02X\n", adev->radio_type);
3672 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3675 if (adev->set_mask & GETSET_ANTENNA) {
3676 /* antenna */
3677 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3679 memset(antenna, 0, sizeof(antenna));
3680 antenna[4] = adev->antenna;
3681 log(L_INIT, "updating antenna value: 0x%02X\n", adev->antenna);
3682 acx_s_configure(adev, &antenna,
3683 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3684 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3687 if (adev->set_mask & GETSET_ED_THRESH) {
3688 /* ed_threshold */
3689 log(L_INIT, "updating Energy Detect (ED) threshold: %u\n",
3690 adev->ed_threshold);
3691 if (IS_ACX100(adev)) {
3692 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3694 memset(ed_threshold, 0, sizeof(ed_threshold));
3695 ed_threshold[4] = adev->ed_threshold;
3696 acx_s_configure(adev, &ed_threshold,
3697 ACX100_IE_DOT11_ED_THRESHOLD);
3698 } else
3699 log(L_INIT, "acx111 doesn't support ED!\n");
3700 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3703 if (adev->set_mask & GETSET_CCA) {
3704 /* CCA value */
3705 log(L_INIT, "updating Channel Clear Assessment "
3706 "(CCA) value: 0x%02X\n", adev->cca);
3707 if (IS_ACX100(adev)) {
3708 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3710 memset(cca, 0, sizeof(cca));
3711 cca[4] = adev->cca;
3712 acx_s_configure(adev, &cca,
3713 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3714 } else
3715 log(L_INIT, "acx111 doesn't support CCA!\n");
3716 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3719 if (adev->set_mask & GETSET_LED_POWER) {
3720 /* Enable Tx */
3721 log(L_INIT, "updating power LED status: %u\n", adev->led_power);
3723 acx_lock(adev, flags);
3724 if (IS_PCI(adev))
3725 acxpci_l_power_led(adev, adev->led_power);
3726 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3727 acx_unlock(adev, flags);
3730 if (adev->set_mask & GETSET_POWER_80211) {
3731 #if POWER_SAVE_80211
3732 acx_s_update_80211_powersave_mode(adev);
3733 #endif
3734 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3737 if (adev->set_mask & GETSET_CHANNEL) {
3738 /* channel */
3739 log(L_INIT, "updating channel to: %u\n", adev->channel);
3740 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3743 if (adev->set_mask & GETSET_TX) {
3744 /* set Tx */
3745 log(L_INIT, "updating: %s Tx\n",
3746 adev->tx_disabled ? "disable" : "enable");
3747 if (adev->tx_disabled)
3748 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3749 else {
3750 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3751 &adev->channel, 1);
3752 FIXME();
3753 /* This needs to be keyed on WEP? */
3754 /* acx111_s_feature_on(adev, 0,
3755 FEATURE2_NO_TXCRYPT |
3756 FEATURE2_SNIFFER); */
3757 acx_wake_queue(adev->ieee, NULL);
3759 CLEAR_BIT(adev->set_mask, GETSET_TX);
3762 if (adev->set_mask & GETSET_RX) {
3763 /* Enable Rx */
3764 log(L_INIT, "updating: enable Rx on channel: %u\n",
3765 adev->channel);
3766 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3767 CLEAR_BIT(adev->set_mask, GETSET_RX);
3770 if (adev->set_mask & GETSET_RETRY) {
3771 u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
3772 u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
3774 log(L_INIT,
3775 "updating short retry limit: %u, long retry limit: %u\n",
3776 adev->short_retry, adev->long_retry);
3777 short_retry[0x4] = adev->short_retry;
3778 long_retry[0x4] = adev->long_retry;
3779 acx_s_configure(adev, &short_retry,
3780 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
3781 acx_s_configure(adev, &long_retry,
3782 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
3783 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3786 if (adev->set_mask & SET_MSDU_LIFETIME) {
3787 u8 xmt_msdu_lifetime[4 +
3788 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3790 log(L_INIT, "updating tx MSDU lifetime: %u\n",
3791 adev->msdu_lifetime);
3792 *(u32 *) & xmt_msdu_lifetime[4] =
3793 cpu_to_le32((u32) adev->msdu_lifetime);
3794 acx_s_configure(adev, &xmt_msdu_lifetime,
3795 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
3796 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3799 if (adev->set_mask & GETSET_REG_DOMAIN) {
3800 log(L_INIT, "updating regulatory domain: 0x%02X\n",
3801 adev->reg_dom_id);
3802 acx_s_set_sane_reg_domain(adev, 1);
3803 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3805 if (adev->set_mask & GETSET_MODE ) {
3806 acx111_s_feature_on(adev, 0,
3807 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3808 switch (adev->mode) {
3809 case ACX_MODE_3_AP:
3810 adev->aid = 0;
3811 //acx111_s_feature_off(adev, 0,
3812 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3813 MAC_COPY(adev->bssid,adev->dev_addr);
3814 acx_s_cmd_join_bssid(adev,adev->dev_addr);
3815 break;
3816 case ACX_MODE_MONITOR:
3817 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3818 break;
3819 case ACX_MODE_0_ADHOC:
3820 case ACX_MODE_2_STA:
3821 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3822 break;
3823 default:
3824 break;
3826 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3828 if (adev->set_mask & SET_TEMPLATES) {
3829 switch (adev->mode)
3831 case ACX_MODE_3_AP:
3832 acx_s_set_tim_template(adev);
3833 break;
3834 default:
3835 break;
3837 if (adev->beacon_cache)
3839 acx_s_set_beacon_template(adev, adev->beacon_cache);
3840 dev_kfree_skb(adev->beacon_cache);
3841 adev->beacon_cache = NULL;
3843 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3846 if (adev->set_mask & SET_RXCONFIG) {
3847 acx_s_initialize_rx_config(adev);
3848 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3851 if (adev->set_mask & GETSET_RESCAN) {
3852 /* switch (adev->mode) {
3853 case ACX_MODE_0_ADHOC:
3854 case ACX_MODE_2_STA:
3855 start_scan = 1;
3856 break;
3858 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3861 if (adev->set_mask & GETSET_WEP) {
3862 /* encode */
3864 ie_dot11WEPDefaultKeyID_t dkey;
3865 #ifdef DEBUG_WEP
3866 struct {
3867 u16 type;
3868 u16 len;
3869 u8 val;
3870 } ACX_PACKED keyindic;
3871 #endif
3872 log(L_INIT, "updating WEP key settings\n");
3874 acx_s_set_wepkey(adev);
3875 if (adev->wep_enabled) {
3876 dkey.KeyID = adev->wep_current_index;
3877 log(L_INIT, "setting WEP key %u as default\n",
3878 dkey.KeyID);
3879 acx_s_configure(adev, &dkey,
3880 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
3881 #ifdef DEBUG_WEP
3882 keyindic.val = 3;
3883 acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
3884 #endif
3887 // start_scan = 1;
3888 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3891 if (adev->set_mask & SET_WEP_OPTIONS) {
3892 acx100_ie_wep_options_t options;
3894 if (IS_ACX111(adev)) {
3895 log(L_DEBUG,
3896 "setting WEP Options for acx111 is not supported\n");
3897 } else {
3898 log(L_INIT, "setting WEP Options\n");
3900 /* let's choose maximum setting: 4 default keys,
3901 * plus 10 other keys: */
3902 options.NumKeys =
3903 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3904 /* don't decrypt default key only,
3905 * don't override decryption: */
3906 options.WEPOption = 0;
3907 if (adev->mode == ACX_MODE_3_AP) {
3908 /* don't decrypt default key only,
3909 * override decryption mechanism: */
3910 options.WEPOption = 2;
3913 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3915 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3919 /* debug, rate, and nick don't need any handling */
3920 /* what about sniffing mode?? */
3922 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3923 adev->get_mask, adev->set_mask);
3925 /* end: */
3926 FN_EXIT0;
3929 #if 0
3930 /***********************************************************************
3931 ** acx_e_after_interrupt_task
3933 static int acx_s_recalib_radio(acx_device_t * adev)
3935 if (IS_ACX111(adev)) {
3936 acx111_cmd_radiocalib_t cal;
3938 /* automatic recalibration, choose all methods: */
3939 cal.methods = cpu_to_le32(0x8000000f);
3940 /* automatic recalibration every 60 seconds (value in TUs)
3941 * I wonder what the firmware default here is? */
3942 cal.interval = cpu_to_le32(58594);
3943 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3944 &cal, sizeof(cal),
3945 CMD_TIMEOUT_MS(100));
3946 } else {
3947 /* On ACX100, we need to recalibrate the radio
3948 * by issuing a GETSET_TX|GETSET_RX */
3949 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3950 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3951 (OK ==
3952 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3953 &adev->channel, 1))
3954 && (OK ==
3955 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3956 &adev->channel, 1)))
3957 return OK;
3958 return NOT_OK;
3961 #endif // if 0
3962 #if 0
3963 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3965 int res;
3967 /* this helps with ACX100 at least;
3968 * hopefully ACX111 also does a
3969 * recalibration here */
3971 /* clear flag beforehand, since we want to make sure
3972 * it's cleared; then only set it again on specific circumstances */
3973 CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3975 /* better wait a bit between recalibrations to
3976 * prevent overheating due to torturing the card
3977 * into working too long despite high temperature
3978 * (just a safety measure) */
3979 if (adev->recalib_time_last_success
3980 && time_before(jiffies, adev->recalib_time_last_success
3981 + RECALIB_PAUSE * 60 * HZ)) {
3982 if (adev->recalib_msg_ratelimit <= 4) {
3983 printk("%s: less than " STRING(RECALIB_PAUSE)
3984 " minutes since last radio recalibration, "
3985 "not recalibrating (maybe card is too hot?)\n",
3986 wiphy_name(adev->ieee->wiphy));
3987 adev->recalib_msg_ratelimit++;
3988 if (adev->recalib_msg_ratelimit == 5)
3989 printk("disabling above message until next recalib\n");
3991 return;
3994 adev->recalib_msg_ratelimit = 0;
3996 /* note that commands sometimes fail (card busy),
3997 * so only clear flag if we were fully successful */
3998 res = acx_s_recalib_radio(adev);
3999 if (res == OK) {
4000 printk("%s: successfully recalibrated radio\n",
4001 wiphy_name(adev->ieee->wiphy));
4002 adev->recalib_time_last_success = jiffies;
4003 adev->recalib_failure_count = 0;
4004 } else {
4005 /* failed: resubmit, but only limited
4006 * amount of times within some time range
4007 * to prevent endless loop */
4009 adev->recalib_time_last_success = 0; /* we failed */
4011 /* if some time passed between last
4012 * attempts, then reset failure retry counter
4013 * to be able to do next recalib attempt */
4014 if (time_after
4015 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
4016 adev->recalib_failure_count = 0;
4018 if (adev->recalib_failure_count < 5) {
4019 /* increment inside only, for speedup of outside path */
4020 adev->recalib_failure_count++;
4021 adev->recalib_time_last_attempt = jiffies;
4022 acx_schedule_task(adev,
4023 ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
4027 #endif // if 0
4029 void acx_e_after_interrupt_task(struct work_struct *work)
4031 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
4032 unsigned long flags;
4034 FN_ENTER;
4036 acx_lock(adev, flags);
4038 if (!adev->after_interrupt_jobs || !adev->initialized)
4039 goto end; /* no jobs to do */
4041 /* we see lotsa tx errors */
4042 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) {
4043 // acx_s_after_interrupt_recalib(adev);
4046 /* a poor interrupt code wanted to do update_card_settings() */
4047 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) {
4048 if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
4049 acx_unlock(adev, flags);
4050 acx_s_update_card_settings(adev);
4051 acx_lock(adev, flags);
4053 CLEAR_BIT(adev->after_interrupt_jobs,
4054 ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4057 /* 1) we detected that no Scan_Complete IRQ came from fw, or
4058 ** 2) we found too many STAs */
4059 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) {
4060 log(L_IRQ, "sending a stop scan cmd...\n");
4061 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
4062 /* HACK: set the IRQ bit, since we won't get a
4063 * scan complete IRQ any more on ACX111 (works on ACX100!),
4064 * since _we_, not a fw, have stopped the scan */
4065 SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
4066 CLEAR_BIT(adev->after_interrupt_jobs,
4067 ACX_AFTER_IRQ_CMD_STOP_SCAN);
4070 /* either fw sent Scan_Complete or we detected that
4071 ** no Scan_Complete IRQ came from fw. Finish scanning,
4072 ** pick join partner if any */
4073 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) {
4074 /* + scan kills current join status - restore it
4075 ** (do we need it for STA?) */
4076 /* + does it happen only with active scans?
4077 ** active and passive scans? ALL scans including
4078 ** background one? */
4079 /* + was not verified that everything is restored
4080 ** (but at least we start to emit beacons again) */
4081 CLEAR_BIT(adev->after_interrupt_jobs,
4082 ACX_AFTER_IRQ_COMPLETE_SCAN);
4085 /* STA auth or assoc timed out, start over again */
4087 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) {
4088 log(L_IRQ, "sending a start_scan cmd...\n");
4089 CLEAR_BIT(adev->after_interrupt_jobs,
4090 ACX_AFTER_IRQ_RESTART_SCAN);
4093 /* whee, we got positive assoc response! 8) */
4094 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) {
4095 CLEAR_BIT(adev->after_interrupt_jobs,
4096 ACX_AFTER_IRQ_CMD_ASSOCIATE);
4098 end:
4099 if(adev->after_interrupt_jobs)
4101 printk("Jobs still to be run: %x\n",adev->after_interrupt_jobs);
4102 adev->after_interrupt_jobs = 0;
4104 acx_unlock(adev, flags);
4105 // acx_sem_unlock(adev);
4106 FN_EXIT0;
4110 /***********************************************************************
4111 ** acx_schedule_task
4113 ** Schedule the call of the after_interrupt method after leaving
4114 ** the interrupt context.
4116 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
4118 if (!adev->after_interrupt_jobs)
4120 SET_BIT(adev->after_interrupt_jobs, set_flag);
4121 schedule_work(&adev->after_interrupt_task);
4126 /***********************************************************************
4128 void acx_init_task_scheduler(acx_device_t * adev)
4130 /* configure task scheduler */
4131 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4135 /***********************************************************************
4136 ** acx_s_start
4138 void acx_s_start(acx_device_t * adev)
4140 FN_ENTER;
4143 * Ok, now we do everything that can possibly be done with ioctl
4144 * calls to make sure that when it was called before the card
4145 * was up we get the changes asked for
4148 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4149 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4150 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4151 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4153 log(L_INIT, "updating initial settings on iface activation\n");
4154 acx_s_update_card_settings(adev);
4156 FN_EXIT0;
4160 /***********************************************************************
4161 ** acx_update_capabilities
4162 *//*
4163 void acx_update_capabilities(acx_device_t * adev)
4165 u16 cap = 0;
4167 switch (adev->mode) {
4168 case ACX_MODE_3_AP:
4169 SET_BIT(cap, WF_MGMT_CAP_ESS);
4170 break;
4171 case ACX_MODE_0_ADHOC:
4172 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4173 break;
4174 */ /* other types of stations do not emit beacons */
4175 /* }
4177 if (adev->wep_restricted) {
4178 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4180 if (adev->cfgopt_dot11ShortPreambleOption) {
4181 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4183 if (adev->cfgopt_dot11PBCCOption) {
4184 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4186 if (adev->cfgopt_dot11ChannelAgility) {
4187 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4189 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4190 adev->capabilities, cap);
4191 adev->capabilities = cap;
4195 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4198 static void acx_select_opmode(acx_device_t * adev)
4200 int changed = 0;
4201 FN_ENTER;
4203 if (adev->interface.operating) {
4204 switch (adev->interface.type) {
4205 case IEEE80211_IF_TYPE_AP:
4206 if (adev->mode != ACX_MODE_3_AP)
4208 adev->mode = ACX_MODE_3_AP;
4209 changed = 1;
4211 break;
4212 case IEEE80211_IF_TYPE_IBSS:
4213 if (adev->mode != ACX_MODE_0_ADHOC)
4215 adev->mode = ACX_MODE_0_ADHOC;
4216 changed = 1;
4218 break;
4219 case IEEE80211_IF_TYPE_STA:
4220 if (adev->mode != ACX_MODE_2_STA)
4222 adev->mode = ACX_MODE_2_STA;
4223 changed = 1;
4225 break;
4226 case IEEE80211_IF_TYPE_WDS:
4227 default:
4228 if (adev->mode != ACX_MODE_OFF)
4230 adev->mode = ACX_MODE_OFF;
4231 changed = 1;
4233 break;
4235 } else {
4236 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4238 if (adev->mode != ACX_MODE_MONITOR)
4240 adev->mode = ACX_MODE_MONITOR;
4241 changed = 1;
4244 else
4246 if (adev->mode != ACX_MODE_OFF)
4248 adev->mode = ACX_MODE_OFF;
4249 changed = 1;
4253 if (changed)
4255 SET_BIT(adev->set_mask, GETSET_MODE);
4256 acx_s_update_card_settings(adev);
4257 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4260 FN_EXIT0;
4264 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4268 int acx_add_interface(struct ieee80211_hw *ieee,
4269 struct ieee80211_if_init_conf *conf)
4271 acx_device_t *adev = ieee2adev(ieee);
4272 unsigned long flags;
4273 int err = -EOPNOTSUPP;
4275 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4276 DECLARE_MAC_BUF(mac);
4277 #endif
4279 FN_ENTER;
4280 acx_lock(adev, flags);
4282 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4283 adev->interface.monitor++;
4284 } else {
4285 if (adev->interface.operating)
4286 goto out_unlock;
4287 adev->interface.operating = 1;
4288 /* for 2.6.25 or later */
4290 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4291 adev->interface.if_id = conf->if_id;
4292 #else
4293 adev->vif = conf->vif;
4294 #endif
4296 adev->interface.if_id = conf->if_id;
4297 adev->interface.mac_addr = conf->mac_addr;
4298 adev->interface.type = conf->type;
4300 // adev->mode = conf->type;
4301 if (adev->initialized)
4302 acx_select_opmode(adev);
4303 err = 0;
4305 printk(KERN_INFO "Virtual interface added "
4306 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4307 "(type: 0x%08X, ID: %d, MAC: "
4308 MAC_FMT ")\n",
4309 conf->type,
4310 conf->if_id,
4311 MAC_ARG(conf->mac_addr));
4312 #else
4313 "(type: 0x%08X), ID: %d, MAC: %s\n",
4314 conf->type,
4315 conf->if_id, /* use conf->vif, and %pd here on 2.6.25 or later */
4316 print_mac(mac, conf->mac_addr));
4317 #endif
4319 out_unlock:
4320 acx_unlock(adev, flags);
4322 FN_EXIT0;
4323 return err;
4326 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4330 void acx_remove_interface(struct ieee80211_hw *hw,
4331 struct ieee80211_if_init_conf *conf)
4333 acx_device_t *adev = ieee2adev(hw);
4334 unsigned long flags;
4336 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4337 DECLARE_MAC_BUF(mac);
4338 #endif
4340 FN_ENTER;
4342 acx_lock(adev, flags);
4343 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4344 adev->interface.monitor--;
4345 // assert(bcm->interface.monitor >= 0);
4346 } else
4347 adev->interface.operating = 0;
4348 printk("Removing interface: %d %d\n", adev->interface.operating, conf->type);
4349 if (adev->initialized)
4350 acx_select_opmode(adev);
4351 flush_scheduled_work();
4352 acx_unlock(adev, flags);
4354 printk(KERN_INFO "Virtual interface removed "
4355 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4356 "(type: 0x%08X, ID: %d, MAC: "
4357 MAC_FMT ")\n",
4358 conf->type, conf->if_id, MAC_ARG(conf->mac_addr));
4359 #else
4360 "(type: 0x%08X, ID: %d, MAC: %s)\n",
4361 conf->type,
4362 conf->if_id, /* use conf->vif, and %pd here on 2.6.25 or later */
4363 print_mac(mac, conf->mac_addr));
4364 #endif
4365 FN_EXIT0;
4368 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4372 int acx_net_reset(struct ieee80211_hw *ieee)
4374 acx_device_t *adev = ieee2adev(ieee);
4375 FN_ENTER;
4376 if (IS_PCI(adev))
4377 acxpci_s_reset_dev(adev);
4378 else
4379 TODO();
4381 FN_EXIT0;
4382 return 0;
4386 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4389 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4391 int result;
4393 FN_ENTER;
4395 acx_sem_lock(adev);
4396 adev->rx_status.channel = channel;
4397 adev->rx_status.freq = freq;
4399 adev->channel = channel;
4400 /* hmm, the following code part is strange, but this is how
4401 * it was being done before... */
4402 log(L_IOCTL, "Changing to channel %d\n", channel);
4403 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4404 result = -EINPROGRESS; /* need to call commit handler */
4406 acx_sem_unlock(adev);
4407 FN_EXIT1(result);
4408 return result;
4412 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4415 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4417 acx_device_t *adev = ieee2adev(hw);
4418 unsigned long flags;
4419 #if 0
4420 int change = 0;
4421 #endif
4422 FN_ENTER;
4424 acx_lock(adev, flags);
4425 //FIXME();
4426 if (!adev->initialized) {
4427 acx_unlock(adev, flags);
4428 return 0;
4430 if (conf->beacon_int != adev->beacon_interval)
4431 adev->beacon_interval = conf->beacon_int;
4432 if (conf->channel != adev->channel) {
4433 acx_unlock(adev, flags);
4434 acx_selectchannel(adev, conf->channel,conf->freq);
4435 acx_lock(adev, flags);
4436 /* acx_schedule_task(adev,
4437 ACX_AFTER_IRQ_UPDATE_CARD_CFG
4438 */ /*+ ACX_AFTER_IRQ_RESTART_SCAN */ /*);*/
4441 if (conf->short_slot_time != adev->short_slot) {
4442 // assert(phy->type == BCM43xx_PHYTYPE_G);
4443 if (conf->short_slot_time)
4444 acx_short_slot_timing_enable(adev);
4445 else
4446 acx_short_slot_timing_disable(adev);
4447 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4450 adev->tx_disabled = !conf->radio_enabled;
4451 if (conf->power_level != 0 && adev->tx_level_dbm > 15){
4452 adev->tx_level_dbm = conf->power_level;
4453 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4454 //acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4457 //FIXME: This does not seem to wake up:
4458 #if 0
4459 if (conf->power_level == 0) {
4460 if (radio->enabled)
4461 bcm43xx_radio_turn_off(bcm);
4462 } else {
4463 if (!radio->enabled)
4464 bcm43xx_radio_turn_on(bcm);
4466 #endif
4468 //TODO: phymode
4469 //TODO: antennas
4470 if (adev->set_mask > 0) {
4471 acx_unlock(adev, flags);
4472 acx_s_update_card_settings(adev);
4473 acx_lock(adev, flags);
4475 acx_unlock(adev, flags);
4477 FN_EXIT0;
4478 return 0;
4482 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4486 //#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) (see below)
4487 int acx_config_interface(struct ieee80211_hw* ieee, int if_id,
4488 struct ieee80211_if_conf *conf)
4490 acx_device_t *adev = ieee2adev(ieee);
4491 unsigned long flags;
4492 int err = -ENODEV;
4493 FN_ENTER;
4494 if (!adev->interface.operating)
4495 goto err_out;
4496 acx_lock(adev, flags);
4498 if (adev->initialized)
4499 acx_select_opmode(adev);
4501 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4502 && (adev->interface.if_id == if_id)) {
4503 if (conf->bssid)
4505 adev->interface.bssid = conf->bssid;
4506 MAC_COPY(adev->bssid,conf->bssid);
4509 if ((conf->type == IEEE80211_IF_TYPE_AP)
4510 && (adev->interface.if_id == if_id)) {
4511 /* for 2.6.25 or later */
4513 #else
4514 extern int acx_config_interface(struct ieee80211_hw* ieee,
4515 struct ieee80211_vif *vif,
4516 struct ieee80211_if_conf *conf)
4518 acx_device_t *adev = ieee2adev(ieee);
4519 unsigned long flags;
4520 int err = -ENODEV;
4521 FN_ENTER;
4522 if (!adev->interface.operating)
4523 goto err_out;
4524 acx_lock(adev, flags);
4526 if (adev->initialized)
4527 acx_select_opmode(adev);
4529 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4530 && (adev->vif == vif)) {
4531 if (conf->bssid)
4533 adev->interface.bssid = conf->bssid;
4534 MAC_COPY(adev->bssid,conf->bssid);
4537 if ((conf->type == IEEE80211_IF_TYPE_AP)
4538 && (adev->vif == vif)) {
4539 #endif
4541 if ((conf->ssid_len > 0) && conf->ssid)
4543 adev->essid_len = conf->ssid_len;
4544 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4545 SET_BIT(adev->set_mask, SET_TEMPLATES);
4548 if (conf->beacon != 0)
4550 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4551 adev->beacon_cache = conf->beacon;
4552 SET_BIT(adev->set_mask, SET_TEMPLATES);
4554 if (adev->set_mask != 0)
4555 acx_s_update_card_settings(adev);
4556 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4557 acx_unlock(adev, flags);
4558 err = 0;
4559 err_out:
4560 FN_EXIT1(err);
4561 return err;
4565 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4569 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4570 struct ieee80211_tx_queue_stats *stats)
4572 // acx_device_t *adev = ndev2adev(net_dev);
4573 struct ieee80211_tx_queue_stats_data *data;
4574 int err = -ENODEV;
4576 FN_ENTER;
4578 // acx_lock(adev, flags);
4579 data = &(stats->data[0]);
4580 data->len = 0;
4581 data->limit = TX_CNT;
4582 data->count = 0;
4583 // acx_unlock(adev, flags);
4585 FN_EXIT0;
4586 return err;
4589 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4593 int acx_net_conf_tx(struct ieee80211_hw *hw,
4594 int queue, const struct ieee80211_tx_queue_params *params)
4596 FN_ENTER;
4597 // TODO();
4598 FN_EXIT0;
4599 return 0;
4602 static void keymac_write(acx_device_t * adev, u16 index, const u32 * addr)
4604 /* for keys 0-3 there is no associated mac address */
4605 if (index < 4)
4606 return;
4608 index -= 4;
4609 if (1) {
4610 TODO();
4612 bcm43xx_shm_write32(bcm,
4613 BCM43xx_SHM_HWMAC,
4614 index * 2,
4615 cpu_to_be32(*addr));
4616 bcm43xx_shm_write16(bcm,
4617 BCM43xx_SHM_HWMAC,
4618 (index * 2) + 1,
4619 cpu_to_be16(*((u16 *)(addr + 1))));
4621 } else {
4622 if (index < 8) {
4623 TODO(); /* Put them in the macaddress filter */
4624 } else {
4625 TODO();
4626 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4627 Keep in mind to update the count of keymacs in 0x003 */
4633 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4637 int acx_clear_keys(acx_device_t * adev)
4639 static const u32 zero_mac[2] = { 0 };
4640 unsigned int i, j, nr_keys = 54;
4641 u16 offset;
4643 /* FixMe:Check for Number of Keys available */
4645 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4647 for (i = 0; i < nr_keys; i++) {
4648 adev->key[i].enabled = 0;
4649 /* returns for i < 4 immediately */
4650 keymac_write(adev, i, zero_mac);
4652 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4653 0x100 + (i * 2), 0x0000);
4655 for (j = 0; j < 8; j++) {
4656 offset =
4657 adev->security_offset + (j * 4) +
4658 (i * ACX_SEC_KEYSIZE);
4660 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4661 offset, 0x0000);
4665 return 1;
4669 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4673 int acx_key_write(acx_device_t * adev,
4674 u16 index, u8 algorithm,
4675 const struct ieee80211_key_conf *key, const u8 * mac_addr)
4677 // struct iw_point *dwrq = &wrqu->encoding;
4678 int result;
4680 FN_ENTER;
4682 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4683 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4685 // acx_sem_lock(adev);
4687 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4688 if (key->keylen > 0) {
4689 /* if index is 0 or invalid, use default key */
4690 if (index > 3)
4691 index = (int)adev->wep_current_index;
4692 if ((algorithm == ACX_SEC_ALGO_WEP) ||
4693 (algorithm == ACX_SEC_ALGO_WEP104)) {
4694 switch(key->keylen) {
4695 case 40 / 8:
4696 /* WEP 40-bit =
4697 40-bit entered key + 24 bit IV = 64-bit */
4698 adev->wep_keys[index].size = 13;
4699 break;
4700 case 104 / 8:
4701 /* WEP 104-bit =
4702 104-bit entered key + 24-bit IV = 128-bit */
4703 adev->wep_keys[index].size = 29;
4704 break;
4705 case 128 / 8:
4706 /* WEP 128-bit =
4707 128-bit entered key + 24 bit IV = 152-bit */
4708 adev->wep_keys[index].size = 16;
4709 break;
4710 default:
4711 adev->wep_keys[index].size = 0;
4712 return -EINVAL; /* shouldn't happen */
4715 memset(adev->wep_keys[index].key, 0,
4716 sizeof(adev->wep_keys[index].key));
4717 memcpy(adev->wep_keys[index].key, key, key->keylen);
4718 } else {
4719 /* set transmit key */
4720 if (index <= 3)
4721 adev->wep_current_index = index;
4722 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4723 /* complain if we were not just setting
4724 * the key mode */
4725 // result = -EINVAL;
4726 // goto end_unlock;
4727 // }
4731 adev->wep_enabled = (algorithm == ALG_WEP);
4733 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4735 if (algorithm & IW_ENCODE_OPEN) {
4736 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4737 adev->wep_restricted = 0;
4739 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4740 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4741 adev->wep_restricted = 1;
4744 // adev->auth_alg = algorithm;
4745 /* set flag to make sure the card WEP settings get updated */
4746 if (adev->wep_enabled) {
4747 SET_BIT(adev->set_mask, GETSET_WEP);
4748 acx_s_update_card_settings(adev);
4749 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4752 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4753 dwrq->length, extra, dwrq->flags);
4754 for (index = 0; index <= 3; index++) {
4755 if (adev->wep_keys[index].size) {
4756 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4757 adev->wep_keys[index].index,
4758 (int) adev->wep_keys[index].size,
4759 adev->wep_keys[index].key);
4763 result = -EINPROGRESS;
4764 // acx_sem_unlock(adev);
4766 FN_EXIT1(result);
4767 return result;
4773 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4777 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4778 int acx_net_set_key(struct ieee80211_hw *ieee,
4779 set_key_cmd cmd,
4780 u8 * addr, struct ieee80211_key_conf *key, int aid)
4781 #else
4782 int acx_net_set_key(struct ieee80211_hw *ieee,
4783 enum set_key_cmd cmd, const u8 *local_addr,
4784 const u8 * addr, struct ieee80211_key_conf *key)
4785 #endif
4787 // return 0;
4788 struct acx_device *adev = ieee2adev(ieee);
4789 unsigned long flags;
4790 u8 algorithm;
4791 u16 index;
4792 int err = -EINVAL;
4793 FN_ENTER;
4794 // TODO();
4795 switch (key->alg) {
4796 default:
4797 /* case ALG_NONE:
4798 case ALG_NULL:
4799 algorithm = ACX_SEC_ALGO_NONE;
4800 break;
4801 */ case ALG_WEP:
4802 if (key->keylen == 5)
4803 algorithm = ACX_SEC_ALGO_WEP;
4804 else
4805 algorithm = ACX_SEC_ALGO_WEP104;
4806 break;
4807 case ALG_TKIP:
4808 algorithm = ACX_SEC_ALGO_TKIP;
4809 break;
4810 case ALG_CCMP:
4811 algorithm = ACX_SEC_ALGO_AES;
4812 break;
4815 index = (u8) (key->keyidx);
4816 if (index >= ARRAY_SIZE(adev->key))
4817 goto out;
4818 acx_lock(adev, flags);
4819 switch (cmd) {
4820 case SET_KEY:
4821 err = acx_key_write(adev, index, algorithm, key, addr);
4822 if (err)
4823 goto out_unlock;
4824 key->hw_key_idx = index;
4825 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4826 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4827 adev->default_key_idx = index;*/
4828 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4829 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4830 #endif
4831 adev->key[index].enabled = 1;
4832 break;
4833 case DISABLE_KEY:
4834 adev->key[index].enabled = 0;
4835 err = 0;
4836 break;
4837 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4838 case REMOVE_ALL_KEYS:
4839 acx_clear_keys(adev);
4840 err = 0;
4841 break;
4842 #endif
4843 /* case ENABLE_COMPRESSION:
4844 case DISABLE_COMPRESSION:
4845 err = 0;
4846 break; */
4848 out_unlock:
4849 acx_unlock(adev, flags);
4850 out:
4851 FN_EXIT0;
4852 return err;
4857 /***********************************************************************
4858 ** Common function to parse ALL configoption struct formats
4859 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4860 ** FIXME: logging should be removed here and added to a /proc file instead
4862 ** Look into bcm43xx
4864 void
4865 acx_s_parse_configoption(acx_device_t * adev,
4866 const acx111_ie_configoption_t * pcfg)
4868 const u8 *pEle;
4869 int i;
4870 int is_acx111 = IS_ACX111(adev);
4872 if (acx_debug & L_DEBUG) {
4873 printk("configoption struct content:\n");
4874 acx_dump_bytes(pcfg, sizeof(*pcfg));
4877 if ((is_acx111 && (adev->eeprom_version == 5))
4878 || (!is_acx111 && (adev->eeprom_version == 4))
4879 || (!is_acx111 && (adev->eeprom_version == 5))) {
4880 /* these versions are known to be supported */
4881 } else {
4882 printk("unknown chip and EEPROM version combination (%s, v%d), "
4883 "don't know how to parse config options yet. "
4884 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4885 adev->eeprom_version);
4886 return;
4889 /* first custom-parse the first part which has chip-specific layout */
4891 pEle = (const u8 *)pcfg;
4893 pEle += 4; /* skip (type,len) header */
4895 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4896 pEle += sizeof(adev->cfgopt_NVSv);
4898 if (is_acx111) {
4899 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4900 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4902 adev->cfgopt_probe_delay = 200; /* good default value? */
4903 pEle += 2; /* FIXME: unknown, value 0x0001 */
4904 } else {
4905 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4906 pEle += sizeof(adev->cfgopt_MAC);
4908 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4909 pEle += sizeof(adev->cfgopt_probe_delay);
4910 if ((adev->cfgopt_probe_delay < 100)
4911 || (adev->cfgopt_probe_delay > 500)) {
4912 printk("strange probe_delay value %d, "
4913 "tweaking to 200\n", adev->cfgopt_probe_delay);
4914 adev->cfgopt_probe_delay = 200;
4918 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4919 pEle += sizeof(adev->cfgopt_eof_memory);
4921 printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n",
4922 adev->cfgopt_NVS_vendor_offs,
4923 adev->cfgopt_probe_delay, adev->cfgopt_eof_memory);
4925 adev->cfgopt_dot11CCAModes = *pEle++;
4926 adev->cfgopt_dot11Diversity = *pEle++;
4927 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4928 adev->cfgopt_dot11PBCCOption = *pEle++;
4929 adev->cfgopt_dot11ChannelAgility = *pEle++;
4930 adev->cfgopt_dot11PhyType = *pEle++;
4931 adev->cfgopt_dot11TempType = *pEle++;
4932 printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4933 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4934 adev->cfgopt_dot11CCAModes,
4935 adev->cfgopt_dot11Diversity,
4936 adev->cfgopt_dot11ShortPreambleOption,
4937 adev->cfgopt_dot11PBCCOption,
4938 adev->cfgopt_dot11ChannelAgility,
4939 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4941 /* then use common parsing for next part which has common layout */
4943 pEle++; /* skip table_count (6) */
4945 adev->cfgopt_antennas.type = pEle[0];
4946 adev->cfgopt_antennas.len = pEle[1];
4947 printk("AntennaID:%02X Len:%02X Data:",
4948 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4949 for (i = 0; i < pEle[1]; i++) {
4950 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4951 printk("%02X ", pEle[i + 2]);
4953 printk("\n");
4955 pEle += pEle[1] + 2;
4956 adev->cfgopt_power_levels.type = pEle[0];
4957 adev->cfgopt_power_levels.len = pEle[1];
4958 printk("PowerLevelID:%02X Len:%02X Data:",
4959 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4960 for (i = 0; i < pEle[1]; i++) {
4961 adev->cfgopt_power_levels.list[i] =
4962 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4963 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4965 printk("\n");
4967 pEle += pEle[1] * 2 + 2;
4968 adev->cfgopt_data_rates.type = pEle[0];
4969 adev->cfgopt_data_rates.len = pEle[1];
4970 printk("DataRatesID:%02X Len:%02X Data:",
4971 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4972 for (i = 0; i < pEle[1]; i++) {
4973 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4974 printk("%02X ", pEle[i + 2]);
4976 printk("\n");
4978 pEle += pEle[1] + 2;
4979 adev->cfgopt_domains.type = pEle[0];
4980 adev->cfgopt_domains.len = pEle[1];
4981 printk("DomainID:%02X Len:%02X Data:",
4982 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4983 for (i = 0; i < pEle[1]; i++) {
4984 adev->cfgopt_domains.list[i] = pEle[i + 2];
4985 printk("%02X ", pEle[i + 2]);
4987 printk("\n");
4989 pEle += pEle[1] + 2;
4990 adev->cfgopt_product_id.type = pEle[0];
4991 adev->cfgopt_product_id.len = pEle[1];
4992 for (i = 0; i < pEle[1]; i++) {
4993 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4995 printk("ProductID:%02X Len:%02X Data:%.*s\n",
4996 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4997 adev->cfgopt_product_id.len,
4998 (char *)adev->cfgopt_product_id.list);
5000 pEle += pEle[1] + 2;
5001 adev->cfgopt_manufacturer.type = pEle[0];
5002 adev->cfgopt_manufacturer.len = pEle[1];
5003 for (i = 0; i < pEle[1]; i++) {
5004 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
5006 printk("ManufacturerID:%02X Len:%02X Data:%.*s\n",
5007 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
5008 adev->cfgopt_manufacturer.len,
5009 (char *)adev->cfgopt_manufacturer.list);
5011 printk("EEPROM part:\n");
5012 for (i=0; i<58; i++) {
5013 printk("%02X =======> 0x%02X\n",
5014 i, (u8 *)adev->cfgopt_NVSv[i-2]);
5020 /***********************************************************************
5021 ** Linux Kernel Specific
5023 static int __init acx_e_init_module(void)
5025 int r1, r2;
5027 acx_struct_size_check();
5029 printk("acx: this driver is still EXPERIMENTAL\n"
5030 "acx: reading README file and/or Craig's HOWTO is "
5031 "recommended, visit http://acx100.sourceforge.net/wiki in case "
5032 "of further questions/discussion\n");
5034 #if defined(CONFIG_ACX_MAC80211_PCI)
5035 r1 = acxpci_e_init_module();
5036 #else
5037 r1 = -EINVAL;
5038 #endif
5039 #if defined(CONFIG_ACX_MAC80211_USB)
5040 r2 = acxusb_e_init_module();
5041 #else
5042 r2 = -EINVAL;
5043 #endif
5044 if (r2 && r1) /* both failed! */
5045 return r2 ? r2 : r1;
5046 /* return success if at least one succeeded */
5047 return 0;
5050 static void __exit acx_e_cleanup_module(void)
5052 #if defined(CONFIG_ACX_MAC80211_PCI)
5053 acxpci_e_cleanup_module();
5054 #endif
5055 #if defined(CONFIG_ACX_MAC80211_USB)
5056 acxusb_e_cleanup_module();
5057 #endif
5060 module_init(acx_e_init_module)
5061 module_exit(acx_e_cleanup_module)