Squashed commit of the following:
[acx-mac80211.git] / common.c
bloba3c32a838e021fb3825056513eec590a315139ac
1 /**** (legal) claimer in README
2 ** Copyright (C) 2003 ACX100 Open Source Project
3 */
5 #include <linux/version.h>
6 #include <linux/module.h>
7 #include <linux/kernel.h>
8 #include <linux/sched.h>
9 #include <linux/types.h>
10 #include <linux/slab.h>
11 #include <linux/delay.h>
12 #include <linux/proc_fs.h>
13 #include <linux/if_arp.h>
14 #include <linux/rtnetlink.h>
15 #include <linux/netdevice.h>
16 #include <linux/etherdevice.h>
17 #include <linux/wireless.h>
18 #include <linux/pm.h>
19 #include <linux/vmalloc.h>
20 #include <linux/firmware.h>
21 //#include <net/iw_handler.h>
22 #include <linux/ethtool.h>
23 //#include <linux/utsrelease.h>
25 #include "acx.h"
28 /***********************************************************************
31 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf);
35 /***********************************************************************
37 #if ACX_DEBUG
38 unsigned int acx_debug /* will add __read_mostly later */ = ACX_DEFAULT_MSG;
39 /* parameter is 'debug', corresponding var is acx_debug */
40 module_param_named(debug, acx_debug, uint, 0);
41 MODULE_PARM_DESC(debug, "Debug level mask (see L_xxx constants)");
42 #endif
44 #ifdef MODULE_LICENSE
45 MODULE_LICENSE("Dual MPL/GPL");
46 #endif
47 /* USB had this: MODULE_AUTHOR("Martin Wawro <martin.wawro AT uni-dortmund.de>"); */
48 MODULE_AUTHOR("ACX100 Open Source Driver development team");
49 MODULE_DESCRIPTION
50 ("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)");
52 MODULE_VERSION(ACX_RELEASE);
54 /***********************************************************************
56 /* Probably a number of acx's intermediate buffers for USB transfers,
57 ** not to be confused with number of descriptors in tx/rx rings
58 ** (which are not directly accessible to host in USB devices) */
59 #define USB_RX_CNT 10
60 #define USB_TX_CNT 10
63 /***********************************************************************
66 /* minutes to wait until next radio recalibration: */
67 #define RECALIB_PAUSE 5
69 /* Please keep acx_reg_domain_ids_len in sync... */
70 const u8 acx_reg_domain_ids[acx_reg_domain_ids_len] =
71 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 };
72 static const u16 reg_domain_channel_masks[acx_reg_domain_ids_len] =
73 { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc };
74 const char *const
75 acx_reg_domain_strings[] = {
76 /* 0 */ " 1-11 FCC (USA)",
77 /* 1 */ " 1-11 DOC/IC (Canada)",
78 /* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */
79 /* 2 */ " 1-13 ETSI (Europe)",
80 /* 3 */ "10-11 Spain",
81 /* 4 */ "10-13 France",
82 /* 5 */ " 14 MKK (Japan)",
83 /* 6 */ " 1-14 MKK1",
84 /* 7 */ " 3-9 Israel (not all firmware versions)",
85 NULL /* needs to remain as last entry */
90 /***********************************************************************
91 ** Debugging support
93 #ifdef PARANOID_LOCKING
94 static unsigned max_lock_time;
95 static unsigned max_sem_time;
97 /* Obvious or linux kernel specific derived code follows: */
99 void acx_lock_unhold()
101 max_lock_time = 0;
104 void acx_sem_unhold()
106 max_sem_time = 0;
109 static inline const char *sanitize_str(const char *s)
111 const char *t = strrchr(s, '/');
112 if (t)
113 return t + 1;
114 return s;
117 void acx_lock_debug(acx_device_t * adev, const char *where)
119 unsigned int count = 100 * 1000 * 1000;
120 where = sanitize_str(where);
121 while (--count) {
122 if (!spin_is_locked(&adev->spinlock))
123 break;
124 cpu_relax();
126 if (!count) {
127 printk(KERN_EMERG "LOCKUP: already taken at %s!\n",
128 adev->last_lock);
129 BUG();
131 adev->last_lock = where;
132 rdtscl(adev->lock_time);
135 void acx_unlock_debug(acx_device_t * adev, const char *where)
137 #ifdef SMP
138 if (!spin_is_locked(&adev->spinlock)) {
139 where = sanitize_str(where);
140 printk(KERN_EMERG "STRAY UNLOCK at %s!\n", where);
141 BUG();
143 #endif
144 if (acx_debug & L_LOCK) {
145 unsigned long diff;
146 rdtscl(diff);
147 diff -= adev->lock_time;
148 if (diff > max_lock_time) {
149 where = sanitize_str(where);
150 printk("max lock hold time %ld CPU ticks from %s "
151 "to %s\n", diff, adev->last_lock, where);
152 max_lock_time = diff;
156 #endif /* PARANOID_LOCKING */
159 /***********************************************************************
161 #if ACX_DEBUG > 1
163 static int acx_debug_func_indent;
164 #define DEBUG_TSC 0
165 #define FUNC_INDENT_INCREMENT 2
167 #if DEBUG_TSC
168 #define TIMESTAMP(d) unsigned long d; rdtscl(d)
169 #else
170 #define TIMESTAMP(d) unsigned long d = jiffies
171 #endif
173 static const char spaces[] = " " " "; /* Nx10 spaces */
175 void log_fn_enter(const char *funcname)
177 int indent;
178 TIMESTAMP(d);
180 indent = acx_debug_func_indent;
181 if (indent >= sizeof(spaces))
182 indent = sizeof(spaces) - 1;
184 printk("%08ld %s==> %s\n",
185 d % 100000000, spaces + (sizeof(spaces) - 1) - indent, funcname);
187 acx_debug_func_indent += FUNC_INDENT_INCREMENT;
189 void log_fn_exit(const char *funcname)
191 int indent;
192 TIMESTAMP(d);
194 acx_debug_func_indent -= FUNC_INDENT_INCREMENT;
196 indent = acx_debug_func_indent;
197 if (indent >= sizeof(spaces))
198 indent = sizeof(spaces) - 1;
200 printk("%08ld %s<== %s\n",
201 d % 100000000, spaces + (sizeof(spaces) - 1) - indent, funcname);
203 void log_fn_exit_v(const char *funcname, int v)
205 int indent;
206 TIMESTAMP(d);
208 acx_debug_func_indent -= FUNC_INDENT_INCREMENT;
210 indent = acx_debug_func_indent;
211 if (indent >= sizeof(spaces))
212 indent = sizeof(spaces) - 1;
214 printk("%08ld %s<== %s: %08X\n",
215 d % 100000000,
216 spaces + (sizeof(spaces) - 1) - indent, funcname, v);
218 #endif /* ACX_DEBUG > 1 */
221 /***********************************************************************
222 ** Basically a mdelay/msleep with logging
224 void acx_s_mwait(int ms)
226 FN_ENTER;
227 msleep(ms);
228 FN_EXIT0;
231 /***********************************************************************
232 ** Not inlined: it's larger than it seems
234 void acx_print_mac(const char *head, const u8 * mac, const char *tail)
236 printk("%s" MACSTR "%s", head, MAC(mac), tail);
239 /***********************************************************************
240 ** acx_cmd_status_str
242 const char *acx_cmd_status_str(unsigned int state)
244 static const char *const cmd_error_strings[] = {
245 "Idle",
246 "Success",
247 "Unknown Command",
248 "Invalid Information Element",
249 "Channel rejected",
250 "Channel invalid in current regulatory domain",
251 "MAC invalid",
252 "Command rejected (read-only information element)",
253 "Command rejected",
254 "Already asleep",
255 "TX in progress",
256 "Already awake",
257 "Write only",
258 "RX in progress",
259 "Invalid parameter",
260 "Scan in progress",
261 "Failed"
263 return state < ARRAY_SIZE(cmd_error_strings) ?
264 cmd_error_strings[state] : "?";
267 /***********************************************************************
269 #if ACX_DEBUG
270 void acx_dump_bytes(const void *data, int num)
272 const u8 *ptr = (const u8 *)data;
274 FN_ENTER;
276 if (num <= 0) {
277 printk("\n");
278 return;
281 while (num >= 16) {
282 printk("%02X %02X %02X %02X %02X %02X %02X %02X "
283 "%02X %02X %02X %02X %02X %02X %02X %02X\n",
284 ptr[0], ptr[1], ptr[2], ptr[3],
285 ptr[4], ptr[5], ptr[6], ptr[7],
286 ptr[8], ptr[9], ptr[10], ptr[11],
287 ptr[12], ptr[13], ptr[14], ptr[15]);
288 num -= 16;
289 ptr += 16;
291 if (num > 0) {
292 while (--num > 0)
293 printk("%02X ", *ptr++);
294 printk("%02X\n", *ptr);
297 FN_EXIT0;
300 #endif
303 /***********************************************************************
304 ** acx_s_get_firmware_version
306 ** Obvious
308 void acx_s_get_firmware_version(acx_device_t * adev)
310 fw_ver_t fw;
311 u8 hexarr[4] = { 0, 0, 0, 0 };
312 int hexidx = 0, val = 0;
313 const char *num;
314 char c;
316 FN_ENTER;
318 memset(fw.fw_id, 'E', FW_ID_SIZE);
319 acx_s_query(adev, &fw, ACX1xx_REG_FWREV);
320 memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE);
321 adev->firmware_version[FW_ID_SIZE] = '\0';
323 log(L_DEBUG, "fw_ver: fw_id='%s' hw_id=%08X\n",
324 adev->firmware_version, fw.hw_id);
326 if (strncmp(fw.fw_id, "Rev ", 4) != 0) {
327 printk("acx: strange firmware version string "
328 "'%s', please report\n", adev->firmware_version);
329 adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */
330 } else {
331 num = &fw.fw_id[4];
332 while (1) {
333 c = *num++;
334 if ((c == '.') || (c == '\0')) {
335 hexarr[hexidx++] = val;
336 if ((hexidx > 3) || (c == '\0')) /* end? */
337 break;
338 val = 0;
339 continue;
341 if ((c >= '0') && (c <= '9'))
342 c -= '0';
343 else
344 c = c - 'a' + (char)10;
345 val = val * 16 + c;
348 adev->firmware_numver = (u32) ((hexarr[0] << 24) |
349 (hexarr[1] << 16)
350 | (hexarr[2] << 8) | hexarr[3]);
351 log(L_DEBUG, "firmware_numver 0x%08X\n", adev->firmware_numver);
353 if (IS_ACX111(adev)) {
354 if (adev->firmware_numver == 0x00010011) {
355 /* This one does not survive floodpinging */
356 printk("acx: firmware '%s' is known to be buggy, "
357 "please upgrade\n", adev->firmware_version);
361 adev->firmware_id = le32_to_cpu(fw.hw_id);
363 /* we're able to find out more detailed chip names now */
364 switch (adev->firmware_id & 0xffff0000) {
365 case 0x01010000:
366 case 0x01020000:
367 adev->chip_name = "TNETW1100A";
368 break;
369 case 0x01030000:
370 adev->chip_name = "TNETW1100B";
371 break;
372 case 0x03000000:
373 case 0x03010000:
374 adev->chip_name = "TNETW1130";
375 break;
376 case 0x04030000: /* 0x04030101 is TNETW1450 */
377 adev->chip_name = "TNETW1450";
378 break;
379 default:
380 printk("acx: unknown chip ID 0x%08X, "
381 "please report\n", adev->firmware_id);
382 break;
385 FN_EXIT0;
389 /***********************************************************************
390 ** acx_display_hardware_details
392 ** Displays hw/fw version, radio type etc...
394 ** Obvious
396 void acx_display_hardware_details(acx_device_t * adev)
398 const char *radio_str, *form_str;
400 FN_ENTER;
402 switch (adev->radio_type) {
403 case RADIO_MAXIM_0D:
404 radio_str = "Maxim";
405 break;
406 case RADIO_RFMD_11:
407 radio_str = "RFMD";
408 break;
409 case RADIO_RALINK_15:
410 radio_str = "Ralink";
411 break;
412 case RADIO_RADIA_16:
413 radio_str = "Radia";
414 break;
415 case RADIO_UNKNOWN_17:
416 /* TI seems to have a radio which is
417 * additionally 802.11a capable, too */
418 radio_str = "802.11a/b/g radio?! Please report";
419 break;
420 case RADIO_UNKNOWN_19:
421 radio_str = "A radio used by Safecom cards?! Please report";
422 break;
423 case RADIO_UNKNOWN_1B:
424 radio_str = "An unknown radio used by TNETW1450 USB adapters";
425 break;
426 default:
427 radio_str = "UNKNOWN, please report radio type name!";
428 break;
431 switch (adev->form_factor) {
432 case 0x00:
433 form_str = "unspecified";
434 break;
435 case 0x01:
436 form_str = "(mini-)PCI / CardBus";
437 break;
438 case 0x02:
439 form_str = "USB";
440 break;
441 case 0x03:
442 form_str = "Compact Flash";
443 break;
444 default:
445 form_str = "UNKNOWN, please report";
446 break;
449 printk("acx: chipset %s, radio type 0x%02X (%s), "
450 "form factor 0x%02X (%s), EEPROM version 0x%02X, "
451 "uploaded firmware '%s'\n",
452 adev->chip_name, adev->radio_type, radio_str,
453 adev->form_factor, form_str, adev->eeprom_version,
454 adev->firmware_version);
456 FN_EXIT0;
460 /***********************************************************************
461 ** acx_e_get_stats, acx_e_get_wireless_stats
464 acx_e_get_stats(struct ieee80211_hw *hw,
465 struct ieee80211_low_level_stats *stats)
467 acx_device_t *adev = ieee2adev(hw);
468 unsigned long flags;
469 acx_lock(adev, flags);
470 memcpy(stats, &adev->ieee_stats, sizeof(*stats));
471 acx_unlock(adev, flags);
472 return 0;
476 /***********************************************************************
477 ** maps acx111 tx descr rate field to acx100 one
479 const u8 acx_bitpos2rate100[] = {
480 RATE100_1, /* 0 */
481 RATE100_2, /* 1 */
482 RATE100_5, /* 2 */
483 RATE100_2, /* 3, should not happen */
484 RATE100_2, /* 4, should not happen */
485 RATE100_11, /* 5 */
486 RATE100_2, /* 6, should not happen */
487 RATE100_2, /* 7, should not happen */
488 RATE100_22, /* 8 */
489 RATE100_2, /* 9, should not happen */
490 RATE100_2, /* 10, should not happen */
491 RATE100_2, /* 11, should not happen */
492 RATE100_2, /* 12, should not happen */
493 RATE100_2, /* 13, should not happen */
494 RATE100_2, /* 14, should not happen */
495 RATE100_2, /* 15, should not happen */
498 u8 acx_rate111to100(u16 r)
500 return acx_bitpos2rate100[highest_bit(r)];
504 /***********************************************************************
505 ** Calculate level like the feb 2003 windows driver seems to do
507 static u8 acx_signal_to_winlevel(u8 rawlevel)
509 /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
510 u8 winlevel = ((4 + (rawlevel * 5)) / 8);
512 if (winlevel > 100)
513 winlevel = 100;
514 return winlevel;
517 u8 acx_signal_determine_quality(u8 signal, u8 noise)
519 int qual;
521 qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2;
523 if (qual > 100)
524 return 100;
525 if (qual < 0)
526 return 0;
527 return qual;
531 /***********************************************************************
532 ** Interrogate/configure commands
535 /* FIXME: the lengths given here probably aren't always correct.
536 * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4",
537 * unless the firmware actually expects a different length than the struct length */
538 static const u16 acx100_ie_len[] = {
540 ACX100_REG_ACX_TIMER_LEN,
541 sizeof(acx100_ie_powersave_t) - 4, /* is that 6 or 8??? */
542 ACX1xx_REG_QUEUE_CONFIG_LEN,
543 ACX100_REG_BLOCK_SIZE_LEN,
544 ACX1xx_REG_MEMORY_CONFIG_OPTIONS_LEN,
545 ACX1xx_REG_RATE_FALLBACK_LEN,
546 ACX100_REG_WEP_OPTIONS_LEN,
547 ACX1xx_REG_MEMORY_MAP_LEN, /* ACX1xx_REG_SSID_LEN, */
549 ACX1xx_REG_ASSOC_ID_LEN,
551 ACX111_REG_CONFIG_OPTIONS_LEN,
552 ACX1xx_REG_FWREV_LEN,
553 ACX1xx_REG_FCS_ERROR_COUNT_LEN,
554 ACX1xx_REG_MEDIUM_USAGE_LEN,
555 ACX1xx_REG_RXCONFIG_LEN,
558 sizeof(fw_stats_t) - 4,
560 ACX1xx_REG_FEATURE_CONFIG_LEN,
561 ACX111_REG_KEY_CHOOSE_LEN,
562 ACX1FF_REG_MISC_CONFIG_TABLE_LEN,
563 ACX1FF_REG_WONE_CONFIG_LEN,
565 ACX1FF_REG_TID_CONFIG_LEN,
569 ACX1FF_REG_CALIB_ASSESSMENT_LEN,
570 ACX1FF_REG_BEACON_FILTER_OPTIONS_LEN,
571 ACX1FF_REG_LOW_RSSI_THRESH_OPT_LEN,
572 ACX1FF_REG_NOISE_HISTOGRAM_RESULTS_LEN,
574 ACX1FF_REG_PACKET_DETECT_THRESH_LEN,
575 ACX1FF_REG_TX_CONFIG_OPTIONS_LEN,
576 ACX1FF_REG_CCA_THRESHOLD_LEN,
577 ACX1FF_REG_EVENT_MASK_LEN,
578 ACX1FF_REG_DTIM_PERIOD_LEN,
580 ACX1FF_REG_ACI_CONFIG_SET_LEN,
587 ACX1FF_REG_EEPROM_VER_LEN,
590 static const u16 acx100_ie_len_dot11[] = {
592 ACX1xx_REG_DOT11_STATION_ID_LEN,
594 ACX100_REG_DOT11_BEACON_PERIOD_LEN,
595 ACX1xx_REG_DOT11_DTIM_PERIOD_LEN,
596 ACX1xx_REG_DOT11_SHORT_RETRY_LIMIT_LEN,
597 ACX1xx_REG_DOT11_LONG_RETRY_LIMIT_LEN,
598 ACX100_REG_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
599 ACX1xx_REG_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
601 ACX1xx_REG_DOT11_CURRENT_REG_DOMAIN_LEN,
602 ACX1xx_REG_DOT11_CURRENT_ANTENNA_LEN,
604 ACX1xx_REG_DOT11_TX_POWER_LEVEL_LEN,
605 ACX1xx_REG_DOT11_CURRENT_CCA_MODE_LEN,
606 ACX100_REG_DOT11_ED_THRESHOLD_LEN,
607 ACX1xx_REG_DOT11_WEP_DEFAULT_KEY_SET_LEN,
613 static const u16 acx111_ie_len[] = {
615 ACX100_REG_ACX_TIMER_LEN,
616 sizeof(acx111_ie_powersave_t) - 4,
617 ACX1xx_REG_QUEUE_CONFIG_LEN,
618 ACX100_REG_BLOCK_SIZE_LEN,
619 ACX1xx_REG_MEMORY_CONFIG_OPTIONS_LEN,
620 ACX1xx_REG_RATE_FALLBACK_LEN,
621 ACX100_REG_WEP_OPTIONS_LEN,
622 ACX1xx_REG_MEMORY_MAP_LEN, /* ACX1xx_REG_SSID_LEN, */
624 ACX1xx_REG_ASSOC_ID_LEN,
626 ACX111_REG_CONFIG_OPTIONS_LEN,
627 ACX1xx_REG_FWREV_LEN,
628 ACX1xx_REG_FCS_ERROR_COUNT_LEN,
629 ACX1xx_REG_MEDIUM_USAGE_LEN,
630 ACX1xx_REG_RXCONFIG_LEN,
633 sizeof(fw_stats_t) - 4,
635 ACX1xx_REG_FEATURE_CONFIG_LEN,
636 ACX111_REG_KEY_CHOOSE_LEN,
637 ACX1FF_REG_MISC_CONFIG_TABLE_LEN,
638 ACX1FF_REG_WONE_CONFIG_LEN,
640 ACX1FF_REG_TID_CONFIG_LEN,
644 ACX1FF_REG_CALIB_ASSESSMENT_LEN,
645 ACX1FF_REG_BEACON_FILTER_OPTIONS_LEN,
646 ACX1FF_REG_LOW_RSSI_THRESH_OPT_LEN,
647 ACX1FF_REG_NOISE_HISTOGRAM_RESULTS_LEN,
649 ACX1FF_REG_PACKET_DETECT_THRESH_LEN,
650 ACX1FF_REG_TX_CONFIG_OPTIONS_LEN,
651 ACX1FF_REG_CCA_THRESHOLD_LEN,
652 ACX1FF_REG_EVENT_MASK_LEN,
653 ACX1FF_REG_DTIM_PERIOD_LEN,
655 ACX1FF_REG_ACI_CONFIG_SET_LEN,
662 ACX1FF_REG_EEPROM_VER_LEN,
665 static const u16 acx111_ie_len_dot11[] = {
667 ACX1xx_REG_DOT11_STATION_ID_LEN,
669 ACX100_REG_DOT11_BEACON_PERIOD_LEN,
670 ACX1xx_REG_DOT11_DTIM_PERIOD_LEN,
671 ACX1xx_REG_DOT11_SHORT_RETRY_LIMIT_LEN,
672 ACX1xx_REG_DOT11_LONG_RETRY_LIMIT_LEN,
673 ACX100_REG_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
674 ACX1xx_REG_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
676 ACX1xx_REG_DOT11_CURRENT_REG_DOMAIN_LEN,
677 ACX1xx_REG_DOT11_CURRENT_ANTENNA_LEN,
679 ACX1xx_REG_DOT11_TX_POWER_LEVEL_LEN,
680 ACX1xx_REG_DOT11_CURRENT_CCA_MODE_LEN,
681 ACX100_REG_DOT11_ED_THRESHOLD_LEN,
682 ACX1xx_REG_DOT11_WEP_DEFAULT_KEY_SET_LEN,
689 #undef FUNC
690 #define FUNC "configure"
691 #if !ACX_DEBUG
692 int acx_s_configure(acx_device_t * adev, void *pdr, int type)
694 #else
696 acx_s_configure_debug(acx_device_t * adev, void *pdr, int type,
697 const char *typestr)
699 #endif
700 u16 len;
701 int res;
703 if (type < 0x1000)
704 len = adev->ie_len[type];
705 else
706 len = adev->ie_len_dot11[type - 0x1000];
708 log(L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
709 if (unlikely(!len)) {
710 log(L_DEBUG, "zero-length type %s?!\n", typestr);
713 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
714 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
715 res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4);
716 if (unlikely(OK != res)) {
717 #if ACX_DEBUG
718 printk("%s: " FUNC "(type:%s) FAILED\n", wiphy_name(adev->ieee->wiphy),
719 typestr);
720 #else
721 printk("%s: " FUNC "(type:0x%X) FAILED\n", wiphy_name(adev->ieee->wiphy),
722 type);
723 #endif
724 /* dump_stack() is already done in issue_cmd() */
726 return res;
729 #undef FUNC
730 #define FUNC "interrogate"
731 #if !ACX_DEBUG
732 int acx_s_query(acx_device_t * adev, void *pdr, int type)
734 #else
736 acx_s_query_debug(acx_device_t * adev, void *pdr, int type,
737 const char *typestr)
739 #endif
740 u16 len;
741 int res;
743 FN_ENTER;
745 /* FIXME: no check whether this exceeds the array yet.
746 * We should probably remember the number of entries... */
747 if (type < 0x1000)
748 len = adev->ie_len[type];
749 else
750 len = adev->ie_len_dot11[type - 0x1000];
752 log(L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
754 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
755 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
756 res = acx_s_issue_cmd(adev, ACX1xx_CMD_QUERY, pdr, len + 4);
757 if (unlikely(OK != res)) {
758 #if ACX_DEBUG
759 printk("%s: " FUNC "(type:%s) FAILED\n", wiphy_name(adev->ieee->wiphy),
760 typestr);
761 #else
762 printk("%s: " FUNC "(type:0x%X) FAILED\n", wiphy_name(adev->ieee->wiphy),
763 type);
764 #endif
765 /* dump_stack() is already done in issue_cmd() */
768 FN_EXIT1(res);
769 return res;
772 #if CMD_DISCOVERY
773 void great_inquisitor(acx_device_t * adev)
775 static struct {
776 u16 type;
777 u16 len;
778 /* 0x200 was too large here: */
779 u8 data[0x100 - 4];
780 } ACX_PACKED ie;
781 u16 type;
783 FN_ENTER;
785 /* 0..0x20, 0x1000..0x1020 */
786 for (type = 0; type <= 0x1020; type++) {
787 if (type == 0x21)
788 type = 0x1000;
789 ie.type = cpu_to_le16(type);
790 ie.len = cpu_to_le16(sizeof(ie) - 4);
791 acx_s_issue_cmd(adev, ACX1xx_CMD_QUERY, &ie, sizeof(ie));
793 FN_EXIT0;
795 #endif
798 #ifdef CONFIG_PROC_FS
799 /***********************************************************************
800 ** /proc files
802 /***********************************************************************
803 ** acx_l_proc_output
804 ** Generate content for our /proc entry
806 ** Arguments:
807 ** buf is a pointer to write output to
808 ** adev is the usual pointer to our private struct acx_device
809 ** Returns:
810 ** number of bytes actually written to buf
811 ** Side effects:
812 ** none
814 static int acx_l_proc_output(char *buf, acx_device_t * adev)
816 char *p = buf;
818 FN_ENTER;
820 p += sprintf(p,
821 "acx driver version:\t\t" ACX_RELEASE "\n"
822 "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n"
823 "chip name:\t\t\t%s (0x%08X)\n"
824 "radio type:\t\t\t0x%02X\n"
825 "form factor:\t\t\t0x%02X\n"
826 "EEPROM version:\t\t\t0x%02X\n"
827 "firmware version:\t\t%s (0x%08X)\n",
828 adev->chip_name, adev->firmware_id,
829 adev->radio_type,
830 adev->form_factor,
831 adev->eeprom_version,
832 adev->firmware_version, adev->firmware_numver);
834 FN_EXIT1(p - buf);
835 return p - buf;
839 /***********************************************************************
841 static int acx_s_proc_diag_output(char *buf, acx_device_t * adev)
843 char *p = buf;
844 unsigned long flags;
845 ssize_t len = 0, partlen;
846 u32 temp1, temp2;
847 u8 *st, *st_end;
848 #ifdef __BIG_ENDIAN
849 u8 *st2;
850 #endif
851 fw_stats_t *fw_stats;
852 char *part_str = NULL;
853 fw_stats_tx_t *tx = NULL;
854 fw_stats_rx_t *rx = NULL;
855 fw_stats_dma_t *dma = NULL;
856 fw_stats_irq_t *irq = NULL;
857 fw_stats_wep_t *wep = NULL;
858 fw_stats_pwr_t *pwr = NULL;
859 fw_stats_mic_t *mic = NULL;
860 fw_stats_aes_t *aes = NULL;
861 fw_stats_event_t *evt = NULL;
863 FN_ENTER;
865 acx_lock(adev, flags);
867 if (IS_PCI(adev))
868 p = acxpci_s_proc_diag_output(p, adev);
870 p += sprintf(p,
871 "\n"
872 "** network status **\n"
873 "dev_state_mask 0x%04X\n"
874 "mode %u, channel %u, "
875 "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
876 adev->dev_state_mask,
877 adev->mode, adev->channel,
878 adev->reg_dom_id, adev->reg_dom_chanmask);
879 p += sprintf(p,
880 "ESSID \"%s\", essid_active %d, essid_len %d, "
881 "essid_for_assoc \"%s\", nick \"%s\"\n"
882 "WEP ena %d, restricted %d, idx %d\n",
883 adev->essid, adev->essid_active, (int)adev->essid_len,
884 adev->essid_for_assoc, adev->nick,
885 adev->wep_enabled, adev->wep_restricted,
886 adev->wep_current_index);
887 p += sprintf(p, "dev_addr " MACSTR "\n", MAC(adev->dev_addr));
888 p += sprintf(p, "bssid " MACSTR "\n", MAC(adev->bssid));
889 p += sprintf(p, "ap_filter " MACSTR "\n", MAC(adev->ap));
891 p += sprintf(p, "\n" "** PHY status **\n"
892 "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
893 "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
894 "rate_basic 0x%04X, rate_oper 0x%04X\n"
895 "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
896 "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
897 adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */
898 adev->sensitivity, adev->antenna, adev->ed_threshold,
899 adev->cca, adev->preamble_mode, adev->rate_basic, adev->rate_oper, adev->rts_threshold,
900 adev->frag_threshold, adev->short_retry, adev->long_retry,
901 adev->msdu_lifetime, adev->listen_interval,
902 adev->beacon_interval);
904 acx_unlock(adev, flags);
906 p += sprintf(p,
907 "\n"
908 "** Firmware **\n"
909 "NOTE: version dependent statistics layout, "
910 "please report if you suspect wrong parsing!\n"
911 "\n" "version \"%s\"\n", adev->firmware_version);
913 /* TODO: may replace kmalloc/memset with kzalloc once
914 * Linux 2.6.14 is widespread */
915 fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL);
916 if (!fw_stats) {
917 FN_EXIT1(0);
918 return 0;
920 memset(fw_stats, 0, sizeof(*fw_stats));
922 st = (u8 *) fw_stats;
924 part_str = "statistics query command";
926 if (OK != acx_s_query(adev, st, ACX1xx_REG_FIRMWARE_STATISTICS))
927 goto fw_stats_end;
929 st += sizeof(u16);
930 len = *(u16 *) st;
932 if (len > sizeof(*fw_stats)) {
933 p += sprintf(p,
934 "firmware version with bigger fw_stats struct detected\n"
935 "(%zu vs. %zu), please report\n", len, sizeof(fw_stats_t));
936 if (len > sizeof(*fw_stats)) {
937 p += sprintf(p, "struct size exceeded allocation!\n");
938 len = sizeof(*fw_stats);
941 st += sizeof(u16);
942 st_end = st - 2 * sizeof(u16) + len;
944 #ifdef __BIG_ENDIAN
945 /* let's make one bold assumption here:
946 * (hopefully!) *all* statistics fields are u32 only,
947 * thus if we need to make endianness corrections
948 * we can simply do them in one go, in advance */
949 st2 = (u8 *) fw_stats;
950 for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4)
951 *(u32 *) st2 = le32_to_cpu(*(u32 *) st2);
952 #endif
954 part_str = "Rx/Tx";
956 /* directly at end of a struct part? --> no error! */
957 if (st == st_end)
958 goto fw_stats_end;
960 tx = (fw_stats_tx_t *) st;
961 st += sizeof(fw_stats_tx_t);
962 rx = (fw_stats_rx_t *) st;
963 st += sizeof(fw_stats_rx_t);
964 partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t);
966 if (IS_ACX100(adev)) {
967 /* at least ACX100 PCI F/W 1.9.8.b
968 * and ACX100 USB F/W 1.0.7-USB
969 * don't have those two fields... */
970 st -= 2 * sizeof(u32);
972 /* our parsing doesn't quite match this firmware yet,
973 * log failure */
974 if (st > st_end)
975 goto fw_stats_fail;
976 temp1 = temp2 = 999999999;
977 } else {
978 if (st > st_end)
979 goto fw_stats_fail;
980 temp1 = rx->rx_aci_events;
981 temp2 = rx->rx_aci_resets;
984 p += sprintf(p,
985 "%s:\n"
986 " tx_desc_overfl %u\n"
987 " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
988 " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n"
989 " rx_aci_events %u, rx_aci_resets %u\n",
990 part_str,
991 tx->tx_desc_of,
992 rx->rx_oom,
993 rx->rx_hdr_of,
994 rx->rx_hw_stuck,
995 rx->rx_dropped_frame,
996 rx->rx_frame_ptr_err, rx->rx_xfr_hint_trig, temp1, temp2);
998 part_str = "DMA";
1000 if (st == st_end)
1001 goto fw_stats_end;
1003 dma = (fw_stats_dma_t *) st;
1004 partlen = sizeof(fw_stats_dma_t);
1005 st += partlen;
1007 if (st > st_end)
1008 goto fw_stats_fail;
1010 p += sprintf(p,
1011 "%s:\n"
1012 " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n",
1013 part_str,
1014 dma->rx_dma_req,
1015 dma->rx_dma_err, dma->tx_dma_req, dma->tx_dma_err);
1017 part_str = "IRQ";
1019 if (st == st_end)
1020 goto fw_stats_end;
1022 irq = (fw_stats_irq_t *) st;
1023 partlen = sizeof(fw_stats_irq_t);
1024 st += partlen;
1026 if (st > st_end)
1027 goto fw_stats_fail;
1029 p += sprintf(p,
1030 "%s:\n"
1031 " cmd_cplt %u, fiq %u\n"
1032 " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
1033 " irqs %u, tx_procs %u, decrypt_done %u\n"
1034 " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
1035 " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
1036 " host_acks %u, pci_pm %u, acm_wakeups %u\n",
1037 part_str,
1038 irq->cmd_cplt,
1039 irq->fiq,
1040 irq->rx_hdrs,
1041 irq->rx_cmplt,
1042 irq->rx_mem_of,
1043 irq->rx_rdys,
1044 irq->irqs,
1045 irq->tx_procs,
1046 irq->decrypt_done,
1047 irq->dma_0_done,
1048 irq->dma_1_done,
1049 irq->tx_exch_complet,
1050 irq->commands,
1051 irq->rx_procs,
1052 irq->hw_pm_mode_changes,
1053 irq->host_acks, irq->pci_pm, irq->acm_wakeups);
1055 part_str = "WEP";
1057 if (st == st_end)
1058 goto fw_stats_end;
1060 wep = (fw_stats_wep_t *) st;
1061 partlen = sizeof(fw_stats_wep_t);
1062 st += partlen;
1064 if (IS_ACX100(adev)) {
1065 /* at least ACX100 PCI F/W 1.9.8.b
1066 * and ACX100 USB F/W 1.0.7-USB
1067 * don't have those two fields... */
1068 st -= 2 * sizeof(u32);
1069 if (st > st_end)
1070 goto fw_stats_fail;
1071 temp1 = temp2 = 999999999;
1072 } else {
1073 if (st > st_end)
1074 goto fw_stats_fail;
1075 temp1 = wep->wep_pkt_decrypt;
1076 temp2 = wep->wep_decrypt_irqs;
1079 p += sprintf(p,
1080 "%s:\n"
1081 " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
1082 " wep_key_not_found %u, wep_decrypt_fail %u\n"
1083 " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
1084 part_str,
1085 wep->wep_key_count,
1086 wep->wep_default_key_count,
1087 wep->dot11_def_key_mib,
1088 wep->wep_key_not_found,
1089 wep->wep_decrypt_fail, temp1, temp2);
1091 part_str = "power";
1093 if (st == st_end)
1094 goto fw_stats_end;
1096 pwr = (fw_stats_pwr_t *) st;
1097 partlen = sizeof(fw_stats_pwr_t);
1098 st += partlen;
1100 if (st > st_end)
1101 goto fw_stats_fail;
1103 p += sprintf(p,
1104 "%s:\n"
1105 " tx_start_ctr %u, no_ps_tx_too_short %u\n"
1106 " rx_start_ctr %u, no_ps_rx_too_short %u\n"
1107 " lppd_started %u\n"
1108 " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n",
1109 part_str,
1110 pwr->tx_start_ctr,
1111 pwr->no_ps_tx_too_short,
1112 pwr->rx_start_ctr,
1113 pwr->no_ps_rx_too_short,
1114 pwr->lppd_started,
1115 pwr->no_lppd_too_noisy,
1116 pwr->no_lppd_too_short, pwr->no_lppd_matching_frame);
1118 part_str = "MIC";
1120 if (st == st_end)
1121 goto fw_stats_end;
1123 mic = (fw_stats_mic_t *) st;
1124 partlen = sizeof(fw_stats_mic_t);
1125 st += partlen;
1127 if (st > st_end)
1128 goto fw_stats_fail;
1130 p += sprintf(p,
1131 "%s:\n"
1132 " mic_rx_pkts %u, mic_calc_fail %u\n",
1133 part_str, mic->mic_rx_pkts, mic->mic_calc_fail);
1135 part_str = "AES";
1137 if (st == st_end)
1138 goto fw_stats_end;
1140 aes = (fw_stats_aes_t *) st;
1141 partlen = sizeof(fw_stats_aes_t);
1142 st += partlen;
1144 if (st > st_end)
1145 goto fw_stats_fail;
1147 p += sprintf(p,
1148 "%s:\n"
1149 " aes_enc_fail %u, aes_dec_fail %u\n"
1150 " aes_enc_pkts %u, aes_dec_pkts %u\n"
1151 " aes_enc_irq %u, aes_dec_irq %u\n",
1152 part_str,
1153 aes->aes_enc_fail,
1154 aes->aes_dec_fail,
1155 aes->aes_enc_pkts,
1156 aes->aes_dec_pkts, aes->aes_enc_irq, aes->aes_dec_irq);
1158 part_str = "event";
1160 if (st == st_end)
1161 goto fw_stats_end;
1163 evt = (fw_stats_event_t *) st;
1164 partlen = sizeof(fw_stats_event_t);
1165 st += partlen;
1167 if (st > st_end)
1168 goto fw_stats_fail;
1170 p += sprintf(p,
1171 "%s:\n"
1172 " heartbeat %u, calibration %u\n"
1173 " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
1174 " oom_late %u\n"
1175 " phy_tx_err %u, tx_stuck %u\n",
1176 part_str,
1177 evt->heartbeat,
1178 evt->calibration,
1179 evt->rx_mismatch,
1180 evt->rx_mem_empty,
1181 evt->rx_pool,
1182 evt->oom_late, evt->phy_tx_err, evt->tx_stuck);
1184 if (st < st_end)
1185 goto fw_stats_bigger;
1187 goto fw_stats_end;
1189 fw_stats_fail:
1190 st -= partlen;
1191 p += sprintf(p,
1192 "failed at %s part (size %zu), offset %zu (struct size %zu), "
1193 "please report\n", part_str, partlen,
1194 ((void *)st - (void *)fw_stats), len);
1196 fw_stats_bigger:
1197 for (; st < st_end; st += 4)
1198 p += sprintf(p,
1199 "UNKN%3d: %u\n",
1200 (int)((void *)st - (void *)fw_stats), *(u32 *) st);
1202 fw_stats_end:
1203 kfree(fw_stats);
1205 FN_EXIT1(p - buf);
1206 return p - buf;
1210 /***********************************************************************
1212 static int acx_s_proc_phy_output(char *buf, acx_device_t * adev)
1214 char *p = buf;
1215 int i;
1217 FN_ENTER;
1220 if (RADIO_RFMD_11 != adev->radio_type) {
1221 printk("sorry, not yet adapted for radio types "
1222 "other than RFMD, please verify "
1223 "PHY size etc. first!\n");
1224 goto end;
1228 /* The PHY area is only 0x80 bytes long; further pages after that
1229 * only have some page number registers with altered value,
1230 * all other registers remain the same. */
1231 for (i = 0; i < 0x80; i++) {
1232 acx_s_read_phy_reg(adev, i, p++);
1235 FN_EXIT1(p - buf);
1236 return p - buf;
1240 /***********************************************************************
1241 ** acx_e_read_proc_XXXX
1242 ** Handle our /proc entry
1244 ** Arguments:
1245 ** standard kernel read_proc interface
1246 ** Returns:
1247 ** number of bytes written to buf
1248 ** Side effects:
1249 ** none
1251 static int
1252 acx_e_read_proc(char *buf, char **start, off_t offset, int count,
1253 int *eof, void *data)
1255 acx_device_t *adev = (acx_device_t *) data;
1256 unsigned long flags;
1257 int length;
1259 FN_ENTER;
1261 acx_sem_lock(adev);
1262 acx_lock(adev, flags);
1263 /* fill buf */
1264 length = acx_l_proc_output(buf, adev);
1265 acx_unlock(adev, flags);
1266 acx_sem_unlock(adev);
1268 /* housekeeping */
1269 if (length <= offset + count)
1270 *eof = 1;
1271 *start = buf + offset;
1272 length -= offset;
1273 if (length > count)
1274 length = count;
1275 if (length < 0)
1276 length = 0;
1277 FN_EXIT1(length);
1278 return length;
1281 static int
1282 acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count,
1283 int *eof, void *data)
1285 acx_device_t *adev = (acx_device_t *) data;
1286 int length;
1288 FN_ENTER;
1290 acx_sem_lock(adev);
1291 /* fill buf */
1292 length = acx_s_proc_diag_output(buf, adev);
1293 acx_sem_unlock(adev);
1295 /* housekeeping */
1296 if (length <= offset + count)
1297 *eof = 1;
1298 *start = buf + offset;
1299 length -= offset;
1300 if (length > count)
1301 length = count;
1302 if (length < 0)
1303 length = 0;
1304 FN_EXIT1(length);
1305 return length;
1308 static int
1309 acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count,
1310 int *eof, void *data)
1312 acx_device_t *adev = (acx_device_t *) data;
1313 int length;
1315 FN_ENTER;
1317 /* fill buf */
1318 length = 0;
1319 if (IS_PCI(adev)) {
1320 acx_sem_lock(adev);
1321 length = acxpci_proc_eeprom_output(buf, adev);
1322 acx_sem_unlock(adev);
1325 /* housekeeping */
1326 if (length <= offset + count)
1327 *eof = 1;
1328 *start = buf + offset;
1329 length -= offset;
1330 if (length > count)
1331 length = count;
1332 if (length < 0)
1333 length = 0;
1334 FN_EXIT1(length);
1335 return length;
1338 static int
1339 acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count,
1340 int *eof, void *data)
1342 acx_device_t *adev = (acx_device_t *) data;
1343 int length;
1345 FN_ENTER;
1347 acx_sem_lock(adev);
1348 /* fill buf */
1349 length = acx_s_proc_phy_output(buf, adev);
1350 acx_sem_unlock(adev);
1352 /* housekeeping */
1353 if (length <= offset + count)
1354 *eof = 1;
1355 *start = buf + offset;
1356 length -= offset;
1357 if (length > count)
1358 length = count;
1359 if (length < 0)
1360 length = 0;
1361 FN_EXIT1(length);
1362 return length;
1366 /***********************************************************************
1367 ** /proc files registration
1369 static const char *const
1370 proc_files[] = { "", "_diag", "_eeprom", "_phy" };
1372 static read_proc_t *const
1373 proc_funcs[] = {
1374 acx_e_read_proc,
1375 acx_e_read_proc_diag,
1376 acx_e_read_proc_eeprom,
1377 acx_e_read_proc_phy
1380 static int manage_proc_entries(struct ieee80211_hw *hw, int remove)
1382 acx_device_t *adev = ieee2adev(hw);
1383 char procbuf[80];
1384 int i;
1386 FN_ENTER;
1388 for (i = 0; i < ARRAY_SIZE(proc_files); i++) {
1389 snprintf(procbuf, sizeof(procbuf),
1390 "driver/acx%s", proc_files[i]);
1391 log(L_INIT, "%sing /proc entry %s\n",
1392 remove ? "remov" : "creat", procbuf);
1393 if (!remove) {
1394 if (!create_proc_read_entry
1395 (procbuf, 0, NULL, proc_funcs[i], adev)) {
1396 printk("acx: cannot register /proc entry %s\n",
1397 procbuf);
1398 FN_EXIT1(NOT_OK);
1399 return NOT_OK;
1401 } else {
1402 remove_proc_entry(procbuf, NULL);
1405 FN_EXIT0;
1406 return OK;
1409 int acx_proc_register_entries(struct ieee80211_hw *ieee)
1411 return manage_proc_entries(ieee, 0);
1414 int acx_proc_unregister_entries(struct ieee80211_hw *ieee)
1416 return manage_proc_entries(ieee, 1);
1418 #endif /* CONFIG_PROC_FS */
1420 /****
1421 ** Gathered From rt2x00 and bcm43xx_mac80211 projects
1423 void acx_free_modes(acx_device_t * adev)
1426 // kfree(adev->modes);
1427 // adev->modes = NULL;
1431 #define RATETAB_ENT(_rate, _rateid, _flags) \
1433 .rate = (_rate), \
1434 .val = (_rateid), \
1435 .val2 = (_rateid), \
1436 .flags = (_flags), \
1440 static struct ieee80211_rate __acx_rates[] = {
1441 { .rate = 10,
1442 .val = RATE111_1,
1443 .flags = IEEE80211_RATE_CCK },
1444 { .rate = 20,
1445 .val = RATE111_2,
1446 .flags = IEEE80211_RATE_CCK },
1447 { .rate = 55,
1448 .val = RATE111_5,
1449 .flags = IEEE80211_RATE_CCK },
1450 { .rate = 110,
1451 .val = RATE111_11,
1452 .flags = IEEE80211_RATE_CCK },
1453 { .rate = 60,
1454 .val = RATE111_6,
1455 .flags = IEEE80211_RATE_OFDM },
1456 { .rate = 90,
1457 .val = RATE111_9,
1458 .flags = IEEE80211_RATE_OFDM },
1459 { .rate = 120,
1460 .val = RATE111_12,
1461 .flags = IEEE80211_RATE_OFDM },
1462 { .rate = 180,
1463 .val = RATE111_18,
1464 .flags = IEEE80211_RATE_OFDM },
1465 { .rate = 240,
1466 .val = RATE111_24,
1467 .flags = IEEE80211_RATE_OFDM },
1468 { .rate = 360,
1469 .val = RATE111_36,
1470 .flags = IEEE80211_RATE_OFDM },
1471 { .rate = 480,
1472 .val = RATE111_48,
1473 .flags = IEEE80211_RATE_OFDM },
1474 { .rate = 540,
1475 .val = RATE111_54,
1476 .flags = IEEE80211_RATE_OFDM },
1479 static struct ieee80211_channel channels[] = {
1480 { .chan = 1,
1481 .freq = 2412},
1482 { .chan = 2,
1483 .freq = 2417},
1484 { .chan = 3,
1485 .freq = 2422},
1486 { .chan = 4,
1487 .freq = 2427},
1488 { .chan = 5,
1489 .freq = 2432},
1490 { .chan = 6,
1491 .freq = 2437},
1492 { .chan = 7,
1493 .freq = 2442},
1494 { .chan = 8,
1495 .freq = 2447},
1496 { .chan = 9,
1497 .freq = 2452},
1498 { .chan = 10,
1499 .freq = 2457},
1500 { .chan = 11,
1501 .freq = 2462},
1502 { .chan = 12,
1503 .freq = 2467},
1504 { .chan = 13,
1505 .freq = 2472},
1508 int acx_setup_modes(acx_device_t * adev)
1510 struct ieee80211_hw *hw = adev->ieee;
1511 struct ieee80211_hw_mode *mode;
1512 int err = -ENOMEM;
1514 FN_ENTER;
1516 if (IS_ACX111(adev)) {
1518 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);
1519 err = acx_setup_modes_gphy(adev);
1521 mode = &adev->modes[0];
1523 /* from the zd1211rw driver: - do we need to do the same? */
1525 memcpy(mode->channels, channels, sizeof(channels));
1526 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1529 mode->mode = MODE_IEEE80211G;
1530 mode->num_channels = ARRAY_SIZE(channels);
1531 mode->num_rates = 12;
1532 mode->rates = __acx_rates;
1533 } else {
1535 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1536 err = acx_setup_modes_bphy(adev);
1538 mode = &adev->modes[1];
1540 /* from the zd1211rw driver: - do we need to do the same? */
1542 memcpy(mode->channels, channels, sizeof(channels));
1543 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1546 mode->mode = MODE_IEEE80211B;
1547 mode->num_channels = ARRAY_SIZE(channels);
1548 mode->num_rates = 4;
1549 mode->rates = __acx_rates;
1552 /* if (err && adev->modes)
1553 kfree(adev->modes);*/
1555 mode->channels = channels;
1556 err = ieee80211_register_hwmode(hw, mode);
1558 FN_EXIT1(err);
1559 return err;
1563 /***********************************************************************
1564 ** acx_fill_beacon_or_proberesp_template
1566 ** Origin: derived from rt2x00 project
1568 static int
1569 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1570 struct acx_template_beacon *templ,
1571 struct sk_buff* skb /* in host order! */)
1573 FN_ENTER;
1575 memcpy(templ,skb->data, skb->len);
1576 FN_EXIT1(skb->len);
1577 return skb->len;
1580 /***********************************************************************
1581 ** acx_s_set_beacon_template
1585 static int
1586 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1588 struct acx_template_beacon bcn;
1589 int len, result;
1591 FN_ENTER;
1592 printk("Size of template: %08zX, Size of beacon: %08X\n", sizeof(struct acx_template_beacon),skb->len);
1593 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1594 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1596 FN_EXIT1(result);
1597 return result;
1600 /***********************************************************************
1601 ** acx_cmd_join_bssid
1603 ** Common code for both acx100 and acx111.
1605 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1606 static const u8 bitpos2genframe_txrate[] = {
1607 10, /* 0. 1 Mbit/s */
1608 20, /* 1. 2 Mbit/s */
1609 55, /* 2. 5.5 Mbit/s */
1610 0x0B, /* 3. 6 Mbit/s */
1611 0x0F, /* 4. 9 Mbit/s */
1612 110, /* 5. 11 Mbit/s */
1613 0x0A, /* 6. 12 Mbit/s */
1614 0x0E, /* 7. 18 Mbit/s */
1615 220, /* 8. 22 Mbit/s */
1616 0x09, /* 9. 24 Mbit/s */
1617 0x0D, /* 10. 36 Mbit/s */
1618 0x08, /* 11. 48 Mbit/s */
1619 0x0C, /* 12. 54 Mbit/s */
1620 10, /* 13. 1 Mbit/s, should never happen */
1621 10, /* 14. 1 Mbit/s, should never happen */
1622 10, /* 15. 1 Mbit/s, should never happen */
1625 /* Looks scary, eh?
1626 ** Actually, each one compiled into one AND and one SHIFT,
1627 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1628 static inline unsigned int rate111to5bits(unsigned int rate)
1630 return (rate & 0x7)
1631 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1632 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1636 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1638 acx_joinbss_t tmp;
1639 int dtim_interval;
1640 int i;
1642 if (mac_is_zero(bssid))
1643 return;
1645 FN_ENTER;
1647 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1648 1 : adev->dtim_interval;
1650 memset(&tmp, 0, sizeof(tmp));
1652 for (i = 0; i < ETH_ALEN; i++) {
1653 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1656 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1658 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1659 ** are sent with one of these rates */
1660 if (IS_ACX111(adev)) {
1661 /* It was experimentally determined that rates_basic
1662 ** can take 11g rates as well, not only rates
1663 ** defined with JOINBSS_RATES_BASIC111_nnn.
1664 ** Just use RATE111_nnn constants... */
1665 tmp.u.acx111.dtim_interval = dtim_interval;
1666 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1667 log(L_ASSOC, "rates_basic:%04X, rates_supported:%04X\n",
1668 adev->rate_basic, adev->rate_oper);
1669 } else {
1670 tmp.u.acx100.dtim_interval = dtim_interval;
1671 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1672 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1673 log(L_ASSOC, "rates_basic:%04X->%02X, "
1674 "rates_supported:%04X->%02X\n",
1675 adev->rate_basic, tmp.u.acx100.rates_basic,
1676 adev->rate_oper, tmp.u.acx100.rates_supported);
1679 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1680 ** will be sent (rate/modulation/preamble) */
1681 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1682 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1683 /* we can use short pre *if* all peers can understand it */
1684 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1686 /* we switch fw to STA mode in MONITOR mode, it seems to be
1687 ** the only mode where fw does not emit beacons by itself
1688 ** but allows us to send anything (we really want to retain
1689 ** ability to tx arbitrary frames in MONITOR mode)
1691 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1692 tmp.channel = adev->channel;
1693 tmp.essid_len = adev->essid_len;
1695 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1696 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1698 log(L_ASSOC|L_DEBUG, "BSS_Type = %u\n", tmp.macmode);
1699 acxlog_mac(L_ASSOC|L_DEBUG, "JoinBSSID MAC:", adev->bssid, "\n");
1701 /* acx_update_capabilities(adev); */
1702 FN_EXIT0;
1705 /***********************************************************************
1706 ** acxpci_i_set_multicast_list
1707 ** FIXME: most likely needs refinement
1710 void acx_i_set_multicast_list(struct ieee80211_hw *hw,
1711 unsigned int changed_flags,
1712 unsigned int *total_flags,
1713 int mc_count, struct dev_addr_list *mc_list)
1715 acx_device_t *adev = ieee2adev(hw);
1716 unsigned long flags;
1718 FN_ENTER;
1720 acx_lock(adev, flags);
1722 changed_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1723 FIF_CONTROL | FIF_OTHER_BSS);
1724 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1725 FIF_CONTROL | FIF_OTHER_BSS);
1726 /* if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1727 return; */
1729 if (*total_flags) {
1730 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1731 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1732 SET_BIT(adev->set_mask, SET_RXCONFIG);
1733 /* let kernel know in case *we* needed to set promiscuous */
1734 } else {
1735 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1736 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1737 SET_BIT(adev->set_mask, SET_RXCONFIG);
1740 /* cannot update card settings directly here, atomic context */
1741 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
1743 acx_unlock(adev, flags);
1745 FN_EXIT0;
1748 /***********************************************************************
1749 ** acx111 feature config
1751 ** Obvious
1753 static int
1754 acx111_s_get_feature_config(acx_device_t * adev,
1755 u32 * feature_options, u32 * data_flow_options)
1757 struct acx111_ie_feature_config feat;
1759 FN_ENTER;
1761 if (!IS_ACX111(adev)) {
1762 return NOT_OK;
1765 memset(&feat, 0, sizeof(feat));
1767 if (OK != acx_s_query(adev, &feat, ACX1xx_REG_FEATURE_CONFIG)) {
1768 FN_EXIT1(NOT_OK);
1769 return NOT_OK;
1771 log(L_DEBUG,
1772 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1773 feat.feature_options, feat.data_flow_options);
1775 if (feature_options)
1776 *feature_options = le32_to_cpu(feat.feature_options);
1777 if (data_flow_options)
1778 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1780 FN_EXIT0;
1781 return OK;
1785 static int
1786 acx111_s_set_feature_config(acx_device_t * adev,
1787 u32 feature_options, u32 data_flow_options,
1788 unsigned int mode
1789 /* 0 == remove, 1 == add, 2 == set */ )
1791 struct acx111_ie_feature_config feat;
1793 FN_ENTER;
1795 if (!IS_ACX111(adev)) {
1796 FN_EXIT1(NOT_OK);
1797 return NOT_OK;
1800 if ((mode < 0) || (mode > 2)) {
1801 FN_EXIT1(NOT_OK);
1802 return NOT_OK;
1805 if (mode != 2)
1806 /* need to modify old data */
1807 acx111_s_get_feature_config(adev, &feat.feature_options,
1808 &feat.data_flow_options);
1809 else {
1810 /* need to set a completely new value */
1811 feat.feature_options = 0;
1812 feat.data_flow_options = 0;
1815 if (mode == 0) { /* remove */
1816 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1817 CLEAR_BIT(feat.data_flow_options,
1818 cpu_to_le32(data_flow_options));
1819 } else { /* add or set */
1820 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1821 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1824 log(L_DEBUG,
1825 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1826 "new: feature 0x%08X dataflow 0x%08X\n",
1827 feature_options, data_flow_options, mode,
1828 le32_to_cpu(feat.feature_options),
1829 le32_to_cpu(feat.data_flow_options));
1831 if (OK != acx_s_configure(adev, &feat, ACX1xx_REG_FEATURE_CONFIG)) {
1832 FN_EXIT1(NOT_OK);
1833 return NOT_OK;
1836 FN_EXIT0;
1837 return OK;
1840 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1842 return acx111_s_set_feature_config(adev, f, d, 0);
1844 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1846 return acx111_s_set_feature_config(adev, f, d, 1);
1848 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1850 return acx111_s_set_feature_config(adev, f, d, 2);
1854 /***********************************************************************
1855 ** acx100_s_init_memory_pools
1857 static int
1858 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1860 acx100_ie_memblocksize_t MemoryBlockSize;
1861 acx100_ie_memconfigoption_t MemoryConfigOption;
1862 int TotalMemoryBlocks;
1863 int RxBlockNum;
1864 int TotalRxBlockSize;
1865 int TxBlockNum;
1866 int TotalTxBlockSize;
1868 FN_ENTER;
1870 /* Let's see if we can follow this:
1871 first we select our memory block size (which I think is
1872 completely arbitrary) */
1873 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1875 /* Then we alert the card to our decision of block size */
1876 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_REG_BLOCK_SIZE)) {
1877 goto bad;
1880 /* We figure out how many total blocks we can create, using
1881 the block size we chose, and the beginning and ending
1882 memory pointers, i.e.: end-start/size */
1883 TotalMemoryBlocks =
1884 (le32_to_cpu(mmt->PoolEnd) -
1885 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1887 log(L_DEBUG, "TotalMemoryBlocks=%u (%u bytes)\n",
1888 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1890 /* MemoryConfigOption.DMA_config bitmask:
1891 access to ACX memory is to be done:
1892 0x00080000 using PCI conf space?!
1893 0x00040000 using IO instructions?
1894 0x00000000 using memory access instructions
1895 0x00020000 using local memory block linked list (else what?)
1896 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1898 if (IS_PCI(adev)) {
1899 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1900 /* Declare start of the Rx host pool */
1901 MemoryConfigOption.pRxHostDesc =
1902 cpu2acx(adev->rxhostdesc_startphy);
1903 log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
1904 acx2cpu(MemoryConfigOption.pRxHostDesc),
1905 (long)adev->rxhostdesc_startphy);
1906 } else {
1907 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1910 /* 50% of the allotment of memory blocks go to tx descriptors */
1911 TxBlockNum = TotalMemoryBlocks / 2;
1912 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1914 /* and 50% go to the rx descriptors */
1915 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1916 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1918 /* size of the tx and rx descriptor queues */
1919 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1920 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1921 log(L_DEBUG, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u "
1922 "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum,
1923 TotalTxBlockSize, TotalRxBlockSize);
1926 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1927 MemoryConfigOption.rx_mem =
1928 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1930 /* align the rx descriptor queue to units of 0x20
1931 * and offset it by the tx descriptor queue */
1932 MemoryConfigOption.tx_mem =
1933 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
1934 0x1f) & ~0x1f);
1935 log(L_DEBUG, "rx_mem %08X rx_mem %08X\n", MemoryConfigOption.tx_mem,
1936 MemoryConfigOption.rx_mem);
1938 /* alert the device to our decision */
1939 if (OK !=
1940 acx_s_configure(adev, &MemoryConfigOption,
1941 ACX1xx_REG_MEMORY_CONFIG_OPTIONS)) {
1942 goto bad;
1945 /* and tell the device to kick it into gear */
1946 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
1947 goto bad;
1949 FN_EXIT1(OK);
1950 return OK;
1951 bad:
1952 FN_EXIT1(NOT_OK);
1953 return NOT_OK;
1957 /***********************************************************************
1958 ** acx100_s_create_dma_regions
1960 ** Note that this fn messes up heavily with hardware, but we cannot
1961 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1963 /* OLD CODE? - let's rewrite it! */
1964 static int acx100_s_create_dma_regions(acx_device_t * adev)
1966 acx100_ie_queueconfig_t queueconf;
1967 acx_ie_memmap_t memmap;
1968 int res = NOT_OK;
1969 u32 tx_queue_start, rx_queue_start;
1971 FN_ENTER;
1973 /* read out the acx100 physical start address for the queues */
1974 if (OK != acx_s_query(adev, &memmap, ACX1xx_REG_MEMORY_MAP)) {
1975 goto fail;
1978 tx_queue_start = le32_to_cpu(memmap.QueueStart);
1979 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
1981 log(L_DEBUG, "initializing Queue Indicator\n");
1983 memset(&queueconf, 0, sizeof(queueconf));
1985 /* Not needed for PCI, so we can avoid setting them altogether */
1986 if (IS_USB(adev)) {
1987 queueconf.NumTxDesc = USB_TX_CNT;
1988 queueconf.NumRxDesc = USB_RX_CNT;
1991 /* calculate size of queues */
1992 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
1993 RX_CNT * sizeof(rxdesc_t) + 8);
1994 queueconf.NumTxQueues = 1; /* number of tx queues */
1995 /* sets the beginning of the tx descriptor queue */
1996 queueconf.TxQueueStart = memmap.QueueStart;
1997 /* done by memset: queueconf.TxQueuePri = 0; */
1998 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
1999 queueconf.QueueOptions = 1; /* auto reset descriptor */
2000 /* sets the end of the rx descriptor queue */
2001 queueconf.QueueEnd =
2002 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
2004 /* sets the beginning of the next queue */
2005 queueconf.HostQueueEnd =
2006 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
2007 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_REG_QUEUE_CONFIG)) {
2008 goto fail;
2011 if (IS_PCI(adev)) {
2012 /* sets the beginning of the rx descriptor queue, after the tx descrs */
2013 if (OK != acxpci_s_create_hostdesc_queues(adev))
2014 goto fail;
2015 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2018 if (OK != acx_s_query(adev, &memmap, ACX1xx_REG_MEMORY_MAP)) {
2019 goto fail;
2022 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
2023 0x1f) & ~0x1f);
2025 if (OK != acx_s_configure(adev, &memmap, ACX1xx_REG_MEMORY_MAP)) {
2026 goto fail;
2029 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
2030 goto fail;
2033 res = OK;
2034 goto end;
2036 fail:
2037 acx_s_mwait(1000); /* ? */
2038 if (IS_PCI(adev))
2039 acxpci_free_desc_queues(adev);
2040 end:
2041 FN_EXIT1(res);
2042 return res;
2046 /***********************************************************************
2047 ** acx111_s_create_dma_regions
2049 ** Note that this fn messes heavily with hardware, but we cannot
2050 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2052 #define ACX111_PERCENT(percent) ((percent)/5)
2054 static int acx111_s_create_dma_regions(acx_device_t * adev)
2056 struct acx111_ie_memoryconfig memconf;
2057 struct acx111_ie_queueconfig queueconf;
2058 u32 tx_queue_start, rx_queue_start;
2060 FN_ENTER;
2062 /* Calculate memory positions and queue sizes */
2064 /* Set up our host descriptor pool + data pool */
2065 if (IS_PCI(adev)) {
2066 if (OK != acxpci_s_create_hostdesc_queues(adev))
2067 goto fail;
2070 memset(&memconf, 0, sizeof(memconf));
2071 /* the number of STAs (STA contexts) to support
2072 ** NB: was set to 1 and everything seemed to work nevertheless... */
2073 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
2074 /* specify the memory block size. Default is 256 */
2075 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
2076 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
2077 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
2078 /* set the count of our queues
2079 ** NB: struct acx111_ie_memoryconfig shall be modified
2080 ** if we ever will switch to more than one rx and/or tx queue */
2081 memconf.count_rx_queues = 1;
2082 memconf.count_tx_queues = 1;
2083 /* 0 == Busmaster Indirect Memory Organization, which is what we want
2084 * (using linked host descs with their allocated mem).
2085 * 2 == Generic Bus Slave */
2086 /* done by memset: memconf.options = 0; */
2087 /* let's use 25% for fragmentations and 75% for frame transfers
2088 * (specified in units of 5%) */
2089 memconf.fragmentation = ACX111_PERCENT(75);
2090 /* Rx descriptor queue config */
2091 memconf.rx_queue1_count_descs = RX_CNT;
2092 memconf.rx_queue1_type = 7; /* must be set to 7 */
2093 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2094 if (IS_PCI(adev)) {
2095 memconf.rx_queue1_host_rx_start =
2096 cpu2acx(adev->rxhostdesc_startphy);
2098 /* Tx descriptor queue config */
2099 memconf.tx_queue1_count_descs = TX_CNT;
2100 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2102 /* NB1: this looks wrong: (memconf,ACX1xx_REG_QUEUE_CONFIG),
2103 ** (queueconf,ACX1xx_REG_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2104 ** But it is actually correct wrt IE numbers.
2105 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_REG_QUEUE_CONFIG)
2106 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2107 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2108 if (OK != acx_s_configure(adev, &memconf, ACX1xx_REG_QUEUE_CONFIG)) {
2109 goto fail;
2112 acx_s_query(adev, &queueconf, ACX1xx_REG_MEMORY_CONFIG_OPTIONS);
2114 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2115 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2117 log(L_INIT, "dump queue head (from card):\n"
2118 "len: %u\n"
2119 "tx_memory_block_address: %X\n"
2120 "rx_memory_block_address: %X\n"
2121 "tx1_queue address: %X\n"
2122 "rx1_queue address: %X\n",
2123 le16_to_cpu(queueconf.len),
2124 le32_to_cpu(queueconf.tx_memory_block_address),
2125 le32_to_cpu(queueconf.rx_memory_block_address),
2126 tx_queue_start, rx_queue_start);
2128 if (IS_PCI(adev))
2129 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2131 FN_EXIT1(OK);
2132 return OK;
2133 fail:
2134 if (IS_PCI(adev))
2135 acxpci_free_desc_queues(adev);
2137 FN_EXIT1(NOT_OK);
2138 return NOT_OK;
2142 /***********************************************************************
2144 static void acx_s_initialize_rx_config(acx_device_t * adev)
2146 struct {
2147 u16 id;
2148 u16 len;
2149 u16 rx_cfg1;
2150 u16 rx_cfg2;
2151 } ACX_PACKED cfg;
2152 switch (adev->mode) {
2153 case ACX_MODE_MONITOR:
2154 adev->rx_config_1 = (u16) (0
2155 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2156 /* | RX_CFG1_FILTER_SSID */
2157 /* | RX_CFG1_FILTER_BCAST */
2158 /* | RX_CFG1_RCV_MC_ADDR1 */
2159 /* | RX_CFG1_RCV_MC_ADDR0 */
2160 /* | RX_CFG1_FILTER_ALL_MULTI */
2161 /* | RX_CFG1_FILTER_BSSID */
2162 /* | RX_CFG1_FILTER_MAC */
2163 | RX_CFG1_RCV_PROMISCUOUS
2164 | RX_CFG1_INCLUDE_FCS
2165 /* | RX_CFG1_INCLUDE_PHY_HDR */
2167 adev->rx_config_2 = (u16) (0
2168 | RX_CFG2_RCV_ASSOC_REQ
2169 | RX_CFG2_RCV_AUTH_FRAMES
2170 | RX_CFG2_RCV_BEACON_FRAMES
2171 | RX_CFG2_RCV_CONTENTION_FREE
2172 | RX_CFG2_RCV_CTRL_FRAMES
2173 | RX_CFG2_RCV_DATA_FRAMES
2174 | RX_CFG2_RCV_BROKEN_FRAMES
2175 | RX_CFG2_RCV_MGMT_FRAMES
2176 | RX_CFG2_RCV_PROBE_REQ
2177 | RX_CFG2_RCV_PROBE_RESP
2178 | RX_CFG2_RCV_ACK_FRAMES
2179 | RX_CFG2_RCV_OTHER);
2180 break;
2181 default:
2182 adev->rx_config_1 = (u16) (0
2183 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2184 /* | RX_CFG1_FILTER_SSID */
2185 /* | RX_CFG1_FILTER_BCAST */
2186 /* | RX_CFG1_RCV_MC_ADDR1 */
2187 /* | RX_CFG1_RCV_MC_ADDR0 */
2188 /* | RX_CFG1_FILTER_ALL_MULTI */
2189 /* | RX_CFG1_FILTER_BSSID */
2190 /* | RX_CFG1_FILTER_MAC */
2191 | RX_CFG1_RCV_PROMISCUOUS
2192 /* | RX_CFG1_INCLUDE_FCS */
2193 /* | RX_CFG1_INCLUDE_PHY_HDR */
2195 adev->rx_config_2 = (u16) (0
2196 | RX_CFG2_RCV_ASSOC_REQ
2197 | RX_CFG2_RCV_AUTH_FRAMES
2198 | RX_CFG2_RCV_BEACON_FRAMES
2199 | RX_CFG2_RCV_CONTENTION_FREE
2200 | RX_CFG2_RCV_CTRL_FRAMES
2201 | RX_CFG2_RCV_DATA_FRAMES
2202 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2203 | RX_CFG2_RCV_MGMT_FRAMES
2204 | RX_CFG2_RCV_PROBE_REQ
2205 | RX_CFG2_RCV_PROBE_RESP
2206 | RX_CFG2_RCV_ACK_FRAMES
2207 | RX_CFG2_RCV_OTHER);
2208 break;
2210 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2212 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2213 || (adev->firmware_numver >= 0x02000000))
2214 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2215 else
2216 adev->phy_header_len = 0;
2218 log(L_INIT, "setting RXconfig to %04X:%04X\n",
2219 adev->rx_config_1, adev->rx_config_2);
2220 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2221 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2222 acx_s_configure(adev, &cfg, ACX1xx_REG_RXCONFIG);
2226 /***********************************************************************
2227 ** FIXME: this should be solved in a general way for all radio types
2228 ** by decoding the radio firmware module,
2229 ** since it probably has some standard structure describing how to
2230 ** set the power level of the radio module which it controls.
2231 ** Or maybe not, since the radio module probably has a function interface
2232 ** instead which then manages Tx level programming :-\
2234 ** Obvious
2236 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2238 struct acx111_ie_tx_level tx_level;
2240 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2241 * 1 (30mW) [15dBm]
2242 * 2 (10mW) [10dBm]
2243 * For now, just assume all other acx111 cards have the same.
2244 * FIXME: Ideally we would query it here, but we first need a
2245 * standard way to query individual configoptions easily.
2246 * Well, now we have proper cfgopt txpower variables, but this still
2247 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2248 if (level_dbm <= 12) {
2249 tx_level.level = 2; /* 10 dBm */
2250 adev->tx_level_dbm = 10;
2251 } else {
2252 tx_level.level = 1; /* 15 dBm */
2253 adev->tx_level_dbm = 15;
2255 if (level_dbm != adev->tx_level_dbm)
2256 log(L_INIT, "acx111 firmware has specific "
2257 "power levels only: adjusted %d dBm to %d dBm!\n",
2258 level_dbm, adev->tx_level_dbm);
2260 return acx_s_configure(adev, &tx_level, ACX1xx_REG_DOT11_TX_POWER_LEVEL);
2263 static int acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
2265 if (IS_ACX111(adev)) {
2266 return acx111_s_set_tx_level(adev, level_dbm);
2268 if (IS_PCI(adev)) {
2269 return acx100pci_s_set_tx_level(adev, level_dbm);
2272 return OK;
2276 /***********************************************************************
2277 ** acx_s_set_defaults
2279 void acx_s_set_defaults(acx_device_t * adev)
2281 struct ieee80211_conf *conf = &adev->ieee->conf;
2282 unsigned long flags;
2284 FN_ENTER;
2286 acx_lock(adev, flags);
2287 /* do it before getting settings, prevent bogus channel 0 warning */
2288 adev->channel = 1;
2290 /* query some settings from the card.
2291 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2292 * query is REQUIRED, otherwise the card won't work correctly! */
2293 adev->get_mask =
2294 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2295 GETSET_REG_DOMAIN;
2296 /* Only ACX100 supports ED and CCA */
2297 if (IS_ACX100(adev))
2298 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2300 acx_unlock(adev, flags);
2302 acx_s_update_card_settings(adev);
2304 acx_lock(adev, flags);
2306 /* set our global interrupt mask */
2307 if (IS_PCI(adev))
2308 acxpci_set_interrupt_mask(adev);
2310 adev->led_power = 1; /* LED is active on startup */
2311 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2312 adev->brange_time_last_state_change = jiffies;
2314 /* copy the MAC address we just got from the card
2315 * into our MAC address used during current 802.11 session */
2316 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
2317 MAC_BCAST(adev->ap);
2319 adev->essid_len =
2320 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2321 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2322 adev->essid_active = 1;
2324 /* we have a nick field to waste, so why not abuse it
2325 * to announce the driver version? ;-) */
2326 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2328 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2329 /* first regulatory domain entry in EEPROM == default reg. domain */
2330 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2333 /* 0xffff would be better, but then we won't get a "scan complete"
2334 * interrupt, so our current infrastructure will fail: */
2335 adev->scan_count = 1;
2336 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2337 adev->scan_duration = 100;
2338 adev->scan_probe_delay = 200;
2339 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2340 adev->scan_rate = ACX_SCAN_RATE_1;
2343 adev->mode = ACX_MODE_2_STA;
2344 adev->listen_interval = 100;
2345 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2346 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2348 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2350 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2351 adev->frag_threshold = 2346;
2353 /* use standard default values for retry limits */
2354 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2355 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2357 adev->preamble_mode = 2; /* auto */
2358 adev->fallback_threshold = 3;
2359 adev->stepup_threshold = 10;
2360 adev->rate_bcast = RATE111_1;
2361 adev->rate_bcast100 = RATE100_1;
2362 adev->rate_basic = RATE111_1 | RATE111_2;
2363 adev->rate_auto = 1;
2364 if (IS_ACX111(adev)) {
2365 adev->rate_oper = RATE111_ALL;
2366 } else {
2367 adev->rate_oper = RATE111_ACX100_COMPAT;
2370 /* Supported Rates element - the rates here are given in units of
2371 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2372 acx_l_update_ratevector(adev);
2374 /* set some more defaults */
2375 if (IS_ACX111(adev)) {
2376 /* 30mW (15dBm) is default, at least in my acx111 card: */
2377 adev->tx_level_dbm = 15;
2378 conf->power_level = adev->tx_level_dbm;
2379 acx_unlock(adev, flags);
2380 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2381 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2382 acx_lock(adev, flags);
2383 } else {
2384 /* don't use max. level, since it might be dangerous
2385 * (e.g. WRT54G people experience
2386 * excessive Tx power damage!) */
2387 adev->tx_level_dbm = 18;
2388 conf->power_level = adev->tx_level_dbm;
2389 acx_unlock(adev, flags);
2390 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2391 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2392 acx_lock(adev, flags);
2395 /* adev->tx_level_auto = 1; */
2396 if (IS_ACX111(adev)) {
2397 /* start with sensitivity level 1 out of 3: */
2398 adev->sensitivity = 1;
2401 /* #define ENABLE_POWER_SAVE */
2402 #ifdef ENABLE_POWER_SAVE
2403 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2404 adev->ps_listen_interval = 1;
2405 adev->ps_options =
2406 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2407 adev->ps_hangover_period = 30;
2408 adev->ps_enhanced_transition_time = 0;
2409 #else
2410 adev->ps_wakeup_cfg = 0;
2411 adev->ps_listen_interval = 0;
2412 adev->ps_options = 0;
2413 adev->ps_hangover_period = 0;
2414 adev->ps_enhanced_transition_time = 0;
2415 #endif
2417 /* These settings will be set in fw on ifup */
2418 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2419 /* configure card to do rate fallback when in auto rate mode */
2420 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2421 /* better re-init the antenna value we got above */
2422 | GETSET_ANTENNA
2423 #if POWER_SAVE_80211
2424 | GETSET_POWER_80211
2425 #endif
2428 acx_unlock(adev, flags);
2429 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2431 acx_s_initialize_rx_config(adev);
2433 FN_EXIT0;
2437 /***********************************************************************
2438 ** acx_l_process_rxbuf
2440 ** NB: used by USB code also
2442 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2444 struct ieee80211_hdr *hdr;
2445 u16 fc, buf_len;
2447 FN_ENTER;
2449 hdr = acx_get_wlan_hdr(adev, rxbuf);
2450 fc = le16_to_cpu(hdr->frame_control);
2451 /* length of frame from control field to first byte of FCS */
2452 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2454 if (unlikely(acx_debug & L_DATA)) {
2455 printk("rx: 802.11 buf[%u]: \n", buf_len);
2456 acx_dump_bytes(hdr, buf_len);
2460 acx_l_rx(adev, rxbuf);
2461 /* Now check Rx quality level, AFTER processing packet.
2462 * I tried to figure out how to map these levels to dBm
2463 * values, but for the life of me I really didn't
2464 * manage to get it. Either these values are not meant to
2465 * be expressed in dBm, or it's some pretty complicated
2466 * calculation. */
2468 #ifdef FROM_SCAN_SOURCE_ONLY
2469 /* only consider packets originating from the MAC
2470 * address of the device that's managing our BSSID.
2471 * Disable it for now, since it removes information (levels
2472 * from different peers) and slows the Rx path. *//*
2473 if (adev->ap_client && mac_is_equal(hdr->a2, adev->ap_client->address)) {
2475 #endif
2477 FN_EXIT0;
2481 /***********************************************************************
2482 ** acx_l_handle_txrate_auto
2484 ** Theory of operation:
2485 ** client->rate_cap is a bitmask of rates client is capable of.
2486 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2487 ** It is set as a result of iwconfig rate N [auto]
2488 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2489 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2490 ** auto (0x00ff == 18Mbit or any lower value),
2491 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2493 ** client->rate_cur is a value for rate111 field in tx descriptor.
2494 ** It is always set to txrate_cfg sans zero or more most significant
2495 ** bits. This routine handles selection of new rate_cur value depending on
2496 ** outcome of last tx event.
2498 ** client->rate_100 is a precalculated rate value for acx100
2499 ** (we can do without it, but will need to calculate it on each tx).
2501 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2502 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2503 ** In theory you can implement it, but so far it is considered not worth doing.
2505 ** 22Mbit, of course, is PBCC always. */
2507 /* maps acx100 tx descr rate field to acx111 one */
2509 static u16 rate100to111(u8 r)
2511 switch (r) {
2512 case RATE100_1:
2513 return RATE111_1;
2514 case RATE100_2:
2515 return RATE111_2;
2516 case RATE100_5:
2517 case (RATE100_5 | RATE100_PBCC511):
2518 return RATE111_5;
2519 case RATE100_11:
2520 case (RATE100_11 | RATE100_PBCC511):
2521 return RATE111_11;
2522 case RATE100_22:
2523 return RATE111_22;
2524 default:
2525 printk("acx: unexpected acx100 txrate: %u! "
2526 "Please report\n", r);
2527 return RATE111_1;
2534 acx_i_start_xmit(struct ieee80211_hw *hw,
2535 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2537 acx_device_t *adev = ieee2adev(hw);
2538 tx_t *tx;
2539 void *txbuf;
2540 unsigned long flags;
2542 int txresult = NOT_OK;
2544 FN_ENTER;
2546 if (unlikely(!skb)) {
2547 /* indicate success */
2548 txresult = OK;
2549 goto out;
2552 if (unlikely(!adev)) {
2553 goto out;
2556 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2557 goto out;
2559 if (unlikely(!adev->initialized)) {
2560 goto out;
2563 acx_lock(adev, flags);
2565 tx = acx_l_alloc_tx(adev);
2567 if (unlikely(!tx)) {
2568 printk_ratelimited("%s: start_xmit: txdesc ring is full, "
2569 "dropping tx\n", wiphy_name(adev->ieee->wiphy));
2570 txresult = NOT_OK;
2571 goto out_unlock;
2574 txbuf = acx_l_get_txbuf(adev, tx);
2576 if (unlikely(!txbuf)) {
2577 /* Card was removed */
2578 txresult = NOT_OK;
2579 acx_l_dealloc_tx(adev, tx);
2580 goto out_unlock;
2582 memcpy(txbuf, skb->data, skb->len);
2584 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2586 txresult = OK;
2587 adev->stats.tx_packets++;
2588 adev->stats.tx_bytes += skb->len;
2590 out_unlock:
2591 acx_unlock(adev, flags);
2593 out:
2594 FN_EXIT1(txresult);
2595 return txresult;
2597 /***********************************************************************
2598 ** acx_l_update_ratevector
2600 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2602 const u8 acx_bitpos2ratebyte[] = {
2603 DOT11RATEBYTE_1,
2604 DOT11RATEBYTE_2,
2605 DOT11RATEBYTE_5_5,
2606 DOT11RATEBYTE_6_G,
2607 DOT11RATEBYTE_9_G,
2608 DOT11RATEBYTE_11,
2609 DOT11RATEBYTE_12_G,
2610 DOT11RATEBYTE_18_G,
2611 DOT11RATEBYTE_22,
2612 DOT11RATEBYTE_24_G,
2613 DOT11RATEBYTE_36_G,
2614 DOT11RATEBYTE_48_G,
2615 DOT11RATEBYTE_54_G,
2618 void acx_l_update_ratevector(acx_device_t * adev)
2620 u16 bcfg = adev->rate_basic;
2621 u16 ocfg = adev->rate_oper;
2622 u8 *supp = adev->rate_supported;
2623 const u8 *dot11 = acx_bitpos2ratebyte;
2625 FN_ENTER;
2627 while (ocfg) {
2628 if (ocfg & 1) {
2629 *supp = *dot11;
2630 if (bcfg & 1) {
2631 *supp |= 0x80;
2633 supp++;
2635 dot11++;
2636 ocfg >>= 1;
2637 bcfg >>= 1;
2639 adev->rate_supported_len = supp - adev->rate_supported;
2640 if (acx_debug & L_ASSOC) {
2641 printk("new ratevector: ");
2642 acx_dump_bytes(adev->rate_supported, adev->rate_supported_len);
2644 FN_EXIT0;
2647 /***********************************************************************
2648 ** acx_i_timer
2650 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2652 ** Obvious
2654 void acx_i_timer(unsigned long address)
2656 unsigned long flags;
2657 acx_device_t *adev = (acx_device_t *) address;
2659 FN_ENTER;
2661 acx_lock(adev, flags);
2663 FIXME();
2664 /* We need calibration and stats gather tasks to perform here */
2666 acx_unlock(adev, flags);
2668 FN_EXIT0;
2672 /***********************************************************************
2673 ** acx_set_timer
2675 ** Sets the 802.11 state management timer's timeout.
2677 ** Linux derived
2679 void acx_set_timer(acx_device_t * adev, int timeout_us)
2681 FN_ENTER;
2683 log(L_DEBUG | L_IRQ, "%s(%u ms)\n", __func__, timeout_us / 1000);
2684 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2685 printk("attempt to set the timer "
2686 "when the card interface is not up!\n");
2687 goto end;
2690 /* first check if the timer was already initialized, THEN modify it */
2691 if (adev->mgmt_timer.function) {
2692 mod_timer(&adev->mgmt_timer,
2693 jiffies + (timeout_us * HZ / 1000000));
2695 end:
2696 FN_EXIT0;
2699 /** acx_plcp_get_bitrate_cck
2701 ** Obvious
2703 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2705 switch (plcp) {
2706 case 0x0A:
2707 return ACX_CCK_RATE_1MB;
2708 case 0x14:
2709 return ACX_CCK_RATE_2MB;
2710 case 0x37:
2711 return ACX_CCK_RATE_5MB;
2712 case 0x6E:
2713 return ACX_CCK_RATE_11MB;
2715 return 0;
2718 /* Extract the bitrate out of an OFDM PLCP header. */
2719 /** Obvious **/
2720 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2722 switch (plcp & 0xF) {
2723 case 0xB:
2724 return ACX_OFDM_RATE_6MB;
2725 case 0xF:
2726 return ACX_OFDM_RATE_9MB;
2727 case 0xA:
2728 return ACX_OFDM_RATE_12MB;
2729 case 0xE:
2730 return ACX_OFDM_RATE_18MB;
2731 case 0x9:
2732 return ACX_OFDM_RATE_24MB;
2733 case 0xD:
2734 return ACX_OFDM_RATE_36MB;
2735 case 0x8:
2736 return ACX_OFDM_RATE_48MB;
2737 case 0xC:
2738 return ACX_OFDM_RATE_54MB;
2740 return 0;
2744 /***********************************************************************
2745 ** acx_l_rx
2747 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2748 ** buffer and feeds it to the network stack via netif_rx().
2750 ** Look to bcm43xx or p54
2752 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2755 struct ieee80211_rx_status* status = &adev->rx_status;
2756 struct ieee80211_hdr *w_hdr;
2757 struct sk_buff *skb;
2758 int buflen;
2759 FN_ENTER;
2761 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2762 printk("asked to receive a packet but interface is down??\n");
2763 goto out;
2766 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2767 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2769 * Allocate our skb
2771 skb = dev_alloc_skb(buflen + 2);
2773 if (!skb) {
2774 printk("skb allocation FAILED\n");
2775 goto out;
2778 skb_reserve(skb, 2);
2779 skb_put(skb, buflen);
2780 memcpy(skb->data, w_hdr, buflen);
2782 // memset(&status, 0, sizeof(status));
2784 status->mactime = rxbuf->time;
2785 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2786 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr);
2787 status->flag = 0;
2788 status->rate = rxbuf->phy_plcp_signal;
2789 status->antenna = 1;
2790 if (rxbuf->phy_stat_baseband & (1 << 3)) { /* Uses OFDM */
2791 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2792 } else {
2793 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2797 * FIXME: should it really be done here??
2799 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2800 adev->stats.rx_packets++;
2801 adev->stats.rx_bytes += skb->len;
2802 out:
2803 FN_EXIT0;
2808 /***********************************************************************
2809 ** acx_s_read_fw
2811 ** Loads a firmware image
2813 ** Returns:
2814 ** 0 unable to load file
2815 ** pointer to firmware success
2817 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2818 u32 * size)
2820 firmware_image_t *res;
2821 const struct firmware *fw_entry;
2823 res = NULL;
2824 log(L_INIT, "requesting firmware image '%s'\n", file);
2825 if (!request_firmware(&fw_entry, file, dev)) {
2826 *size = 8;
2827 if (fw_entry->size >= 8)
2828 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2829 if (fw_entry->size != *size) {
2830 printk("acx: firmware size does not match "
2831 "firmware header: %d != %d, "
2832 "aborting fw upload\n",
2833 (int)fw_entry->size, (int)*size);
2834 goto release_ret;
2836 res = vmalloc(*size);
2837 if (!res) {
2838 printk("acx: no memory for firmware "
2839 "(%u bytes)\n", *size);
2840 goto release_ret;
2842 memcpy(res, fw_entry->data, fw_entry->size);
2843 release_ret:
2844 release_firmware(fw_entry);
2845 return res;
2847 printk("acx: firmware image '%s' was not provided. "
2848 "Check your hotplug scripts\n", file);
2850 /* checksum will be verified in write_fw, so don't bother here */
2851 return res;
2855 /***********************************************************************
2856 ** acx_s_set_wepkey
2858 static void acx100_s_set_wepkey(acx_device_t * adev)
2860 ie_dot11WEPDefaultKey_t dk;
2861 int i;
2863 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2864 if (adev->wep_keys[i].size != 0) {
2865 log(L_INIT, "setting WEP key: %d with "
2866 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2867 dk.action = 1;
2868 dk.keySize = adev->wep_keys[i].size;
2869 dk.defaultKeyNum = i;
2870 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2871 acx_s_configure(adev, &dk,
2872 ACX100_REG_DOT11_WEP_DEFAULT_KEY_WRITE);
2877 static void acx111_s_set_wepkey(acx_device_t * adev)
2879 acx111WEPDefaultKey_t dk;
2880 int i;
2882 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2883 if (adev->wep_keys[i].size != 0) {
2884 log(L_INIT, "setting WEP key: %d with "
2885 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2886 memset(&dk, 0, sizeof(dk));
2887 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2888 dk.keySize = adev->wep_keys[i].size;
2890 /* are these two lines necessary? */
2891 dk.type = 0; /* default WEP key */
2892 dk.index = 0; /* ignored when setting default key */
2894 dk.defaultKeyNum = i;
2895 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2896 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2897 sizeof(dk));
2901 /* Obvious */
2902 static void acx_s_set_wepkey(acx_device_t * adev)
2904 if (IS_ACX111(adev))
2905 acx111_s_set_wepkey(adev);
2906 else
2907 acx100_s_set_wepkey(adev);
2911 /***********************************************************************
2912 ** acx100_s_init_wep
2914 ** FIXME: this should probably be moved into the new card settings
2915 ** management, but since we're also modifying the memory map layout here
2916 ** due to the WEP key space we want, we should take care...
2918 static int acx100_s_init_wep(acx_device_t * adev)
2920 acx100_ie_wep_options_t options;
2921 ie_dot11WEPDefaultKeyID_t dk;
2922 acx_ie_memmap_t pt;
2923 int res = NOT_OK;
2925 FN_ENTER;
2927 if (OK != acx_s_query(adev, &pt, ACX1xx_REG_MEMORY_MAP)) {
2928 goto fail;
2931 log(L_DEBUG, "CodeEnd:%X\n", pt.CodeEnd);
2933 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2934 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2936 if (OK != acx_s_configure(adev, &pt, ACX1xx_REG_MEMORY_MAP)) {
2937 goto fail;
2940 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2941 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2942 options.WEPOption = 0x00;
2944 log(L_ASSOC, "writing WEP options\n");
2945 acx_s_configure(adev, &options, ACX100_REG_WEP_OPTIONS);
2947 acx100_s_set_wepkey(adev);
2949 if (adev->wep_keys[adev->wep_current_index].size != 0) {
2950 log(L_ASSOC, "setting active default WEP key number: %d\n",
2951 adev->wep_current_index);
2952 dk.KeyID = adev->wep_current_index;
2953 acx_s_configure(adev, &dk, ACX1xx_REG_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
2955 /* FIXME!!! wep_key_struct is filled nowhere! But adev
2956 * is initialized to 0, and we don't REALLY need those keys either */
2957 /* for (i = 0; i < 10; i++) {
2958 if (adev->wep_key_struct[i].len != 0) {
2959 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
2960 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
2961 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
2962 wep_mgmt.Action = cpu_to_le16(1);
2963 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
2964 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
2965 adev->wep_key_struct[i].index = i;
2971 /* now retrieve the updated WEPCacheEnd pointer... */
2972 if (OK != acx_s_query(adev, &pt, ACX1xx_REG_MEMORY_MAP)) {
2973 printk("%s: ACX1xx_REG_MEMORY_MAP read #2 FAILED\n",
2974 wiphy_name(adev->ieee->wiphy));
2975 goto fail;
2977 /* ...and tell it to start allocating templates at that location */
2978 /* (no endianness conversion needed) */
2979 pt.PacketTemplateStart = pt.WEPCacheEnd;
2981 if (OK != acx_s_configure(adev, &pt, ACX1xx_REG_MEMORY_MAP)) {
2982 printk("%s: ACX1xx_REG_MEMORY_MAP write #2 FAILED\n",
2983 wiphy_name(adev->ieee->wiphy));
2984 goto fail;
2986 res = OK;
2988 fail:
2989 FN_EXIT1(res);
2990 return res;
2994 static int
2995 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
2996 unsigned int cmd)
2998 int res;
2999 union {
3000 acx_template_nullframe_t null;
3001 acx_template_beacon_t b;
3002 acx_template_tim_t tim;
3003 acx_template_probereq_t preq;
3004 acx_template_proberesp_t presp;
3005 } templ;
3007 memset(&templ, 0, len);
3008 templ.null.size = cpu_to_le16(len - 2);
3009 res = acx_s_issue_cmd(adev, cmd, &templ, len);
3010 return res;
3013 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
3015 return acx_s_init_max_template_generic(adev,
3016 sizeof(acx_template_nullframe_t),
3017 ACX1xx_CMD_CONFIG_NULL_DATA);
3020 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
3022 return acx_s_init_max_template_generic(adev,
3023 sizeof(acx_template_beacon_t),
3024 ACX1xx_CMD_CONFIG_BEACON);
3027 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
3029 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
3030 ACX1xx_CMD_CONFIG_TIM);
3033 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
3035 return acx_s_init_max_template_generic(adev,
3036 sizeof(acx_template_proberesp_t),
3037 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
3040 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
3042 return acx_s_init_max_template_generic(adev,
3043 sizeof(acx_template_probereq_t),
3044 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
3047 /***********************************************************************
3048 ** acx_s_set_tim_template
3050 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
3051 ** by calling this function
3052 ** (it can be done by irq handler on each DTIM irq or by timer...)
3054 [802.11 7.3.2.6] TIM information element:
3055 - 1 EID
3056 - 1 Length
3057 1 1 DTIM Count
3058 indicates how many beacons (including this) appear before next DTIM
3059 (0=this one is a DTIM)
3060 2 1 DTIM Period
3061 number of beacons between successive DTIMs
3062 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
3063 3 1 Bitmap Control
3064 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
3065 set to 1 in TIM elements with a value of 0 in the DTIM Count field
3066 when one or more broadcast or multicast frames are buffered at the AP.
3067 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
3068 4 n Partial Virtual Bitmap
3069 Visible part of traffic-indication bitmap.
3070 Full bitmap consists of 2008 bits (251 octets) such that bit number N
3071 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
3072 in octet number N/8 where the low-order bit of each octet is bit0,
3073 and the high order bit is bit7.
3074 Each set bit in virtual bitmap corresponds to traffic buffered by AP
3075 for a specific station (with corresponding AID?).
3076 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
3077 Bitmap Offset is a number of skipped zero octets (see above).
3078 'Missing' octets at the tail are also assumed to be zero.
3079 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
3080 This means that traffic-indication bitmap is:
3081 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
3082 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
3084 static int acx_s_set_tim_template(acx_device_t * adev)
3086 /* For now, configure smallish test bitmap, all zero ("no pending data") */
3087 enum { bitmap_size = 5 };
3089 acx_template_tim_t t;
3090 int result;
3092 FN_ENTER;
3094 memset(&t, 0, sizeof(t));
3095 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3096 t.tim_eid = WLAN_EID_TIM;
3097 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3098 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3099 FN_EXIT1(result);
3100 return result;
3106 #if POWER_SAVE_80211
3107 /***********************************************************************
3108 ** acx_s_set_null_data_template
3110 static int acx_s_set_null_data_template(acx_device_t * adev)
3112 struct acx_template_nullframe b;
3113 int result;
3115 FN_ENTER;
3117 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3119 b.size = cpu_to_le16(sizeof(b) - 2);
3120 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3121 b.hdr.dur = 0;
3122 MAC_BCAST(b.hdr.a1);
3123 MAC_COPY(b.hdr.a2, adev->dev_addr);
3124 MAC_COPY(b.hdr.a3, adev->bssid);
3125 b.hdr.seq = 0;
3127 result =
3128 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3130 FN_EXIT1(result);
3131 return result;
3133 #endif
3140 /***********************************************************************
3141 ** acx_s_init_packet_templates()
3143 ** NOTE: order is very important here, to have a correct memory layout!
3144 ** init templates: max Probe Request (station mode), max NULL data,
3145 ** max Beacon, max TIM, max Probe Response.
3147 static int acx_s_init_packet_templates(acx_device_t * adev)
3149 acx_ie_memmap_t mm; /* ACX100 only */
3150 int result = NOT_OK;
3152 FN_ENTER;
3154 log(L_DEBUG | L_INIT, "initializing max packet templates\n");
3156 if (OK != acx_s_init_max_probe_request_template(adev))
3157 goto failed;
3159 if (OK != acx_s_init_max_null_data_template(adev))
3160 goto failed;
3162 if (OK != acx_s_init_max_beacon_template(adev))
3163 goto failed;
3165 if (OK != acx_s_init_max_tim_template(adev))
3166 goto failed;
3168 if (OK != acx_s_init_max_probe_response_template(adev))
3169 goto failed;
3171 if (IS_ACX111(adev)) {
3172 /* ACX111 doesn't need the memory map magic below,
3173 * and the other templates will be set later (acx_start) */
3174 result = OK;
3175 goto success;
3178 /* ACX100 will have its TIM template set,
3179 * and we also need to update the memory map */
3181 if (OK != acx_s_set_tim_template(adev))
3182 goto failed_acx100;
3184 log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3186 if (OK != acx_s_query(adev, &mm, ACX1xx_REG_MEMORY_MAP))
3187 goto failed_acx100;
3189 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3190 if (OK != acx_s_configure(adev, &mm, ACX1xx_REG_MEMORY_MAP))
3191 goto failed_acx100;
3193 result = OK;
3194 goto success;
3196 failed_acx100:
3197 log(L_DEBUG | L_INIT,
3198 /* "cb=0x%X\n" */
3199 "ACXMemoryMap:\n"
3200 ".CodeStart=0x%X\n"
3201 ".CodeEnd=0x%X\n"
3202 ".WEPCacheStart=0x%X\n"
3203 ".WEPCacheEnd=0x%X\n"
3204 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3205 /* len, */
3206 le32_to_cpu(mm.CodeStart),
3207 le32_to_cpu(mm.CodeEnd),
3208 le32_to_cpu(mm.WEPCacheStart),
3209 le32_to_cpu(mm.WEPCacheEnd),
3210 le32_to_cpu(mm.PacketTemplateStart),
3211 le32_to_cpu(mm.PacketTemplateEnd));
3213 failed:
3214 printk("%s: %s() FAILED\n", wiphy_name(adev->ieee->wiphy), __func__);
3216 success:
3217 FN_EXIT1(result);
3218 return result;
3223 /***********************************************************************
3224 ** acx_s_init_mac
3226 int acx_s_init_mac(acx_device_t * adev)
3228 int result = NOT_OK;
3230 FN_ENTER;
3232 if (IS_ACX111(adev)) {
3233 adev->ie_len = acx111_ie_len;
3234 adev->ie_len_dot11 = acx111_ie_len_dot11;
3235 } else {
3236 adev->ie_len = acx100_ie_len;
3237 adev->ie_len_dot11 = acx100_ie_len_dot11;
3240 if (IS_PCI(adev)) {
3241 adev->memblocksize = 256; /* 256 is default */
3242 /* try to load radio for both ACX100 and ACX111, since both
3243 * chips have at least some firmware versions making use of an
3244 * external radio module */
3245 acxpci_s_upload_radio(adev);
3246 } else {
3247 adev->memblocksize = 128;
3250 if (IS_ACX111(adev)) {
3251 /* for ACX111, the order is different from ACX100
3252 1. init packet templates
3253 2. create station context and create dma regions
3254 3. init wep default keys
3256 if (OK != acx_s_init_packet_templates(adev))
3257 goto fail;
3258 if (OK != acx111_s_create_dma_regions(adev)) {
3259 printk("%s: acx111_create_dma_regions FAILED\n",
3260 wiphy_name(adev->ieee->wiphy));
3261 goto fail;
3263 } else {
3264 if (OK != acx100_s_init_wep(adev))
3265 goto fail;
3266 if (OK != acx_s_init_packet_templates(adev))
3267 goto fail;
3268 if (OK != acx100_s_create_dma_regions(adev)) {
3269 printk("%s: acx100_create_dma_regions FAILED\n",
3270 wiphy_name(adev->ieee->wiphy));
3271 goto fail;
3275 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3276 result = OK;
3278 fail:
3279 if (result)
3280 printk("acx: init_mac() FAILED\n");
3281 FN_EXIT1(result);
3282 return result;
3287 #if POWER_SAVE_80211
3288 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3290 /* merge both structs in a union to be able to have common code */
3291 union {
3292 acx111_ie_powersave_t acx111;
3293 acx100_ie_powersave_t acx100;
3294 } pm;
3296 /* change 802.11 power save mode settings */
3297 log(L_INIT, "updating 802.11 power save mode settings: "
3298 "wakeup_cfg 0x%02X, listen interval %u, "
3299 "options 0x%02X, hangover period %u, "
3300 "enhanced_ps_transition_time %u\n",
3301 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3302 adev->ps_options, adev->ps_hangover_period,
3303 adev->ps_enhanced_transition_time);
3304 acx_s_query(adev, &pm, ACX1xx_REG_POWER_MGMT);
3305 log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, "
3306 "listen interval %u, options 0x%02X, "
3307 "hangover period %u, "
3308 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3309 pm.acx111.wakeup_cfg,
3310 pm.acx111.listen_interval,
3311 pm.acx111.options,
3312 pm.acx111.hangover_period,
3313 IS_ACX111(adev) ?
3314 pm.acx111.enhanced_ps_transition_time
3315 : pm.acx100.enhanced_ps_transition_time,
3316 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3317 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3318 pm.acx111.listen_interval = adev->ps_listen_interval;
3319 pm.acx111.options = adev->ps_options;
3320 pm.acx111.hangover_period = adev->ps_hangover_period;
3321 if (IS_ACX111(adev)) {
3322 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3323 pm.acx111.enhanced_ps_transition_time =
3324 cpu_to_le32(adev->ps_enhanced_transition_time);
3325 } else {
3326 pm.acx100.enhanced_ps_transition_time =
3327 cpu_to_le16(adev->ps_enhanced_transition_time);
3329 acx_s_configure(adev, &pm, ACX1xx_REG_POWER_MGMT);
3330 acx_s_query(adev, &pm, ACX1xx_REG_POWER_MGMT);
3331 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3332 acx_s_mwait(40);
3333 acx_s_query(adev, &pm, ACX1xx_REG_POWER_MGMT);
3334 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3335 log(L_INIT, "power save mode change %s\n",
3336 (pm.acx111.
3337 wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful");
3338 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3339 * that power save mode change was successful. */
3340 /* FIXME: we shouldn't trigger a scan immediately after
3341 * fiddling with power save mode (since the firmware is sending
3342 * a NULL frame then). */
3344 #endif
3347 /***********************************************************************
3348 ** acx_s_update_card_settings
3350 ** Applies accumulated changes in various adev->xxxx members
3351 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3352 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3354 void acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
3356 unsigned mask;
3358 unsigned int i;
3360 for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
3361 if (acx_reg_domain_ids[i] == adev->reg_dom_id)
3362 break;
3364 if (sizeof(acx_reg_domain_ids) == i) {
3365 log(L_INIT, "Invalid or unsupported regulatory domain"
3366 " 0x%02X specified, falling back to FCC (USA)!"
3367 " Please report if this sounds fishy!\n",
3368 adev->reg_dom_id);
3369 i = 0;
3370 adev->reg_dom_id = acx_reg_domain_ids[i];
3372 /* since there was a mismatch, we need to force updating */
3373 do_set = 1;
3376 if (do_set) {
3377 acx_ie_generic_t dom;
3378 dom.m.bytes[0] = adev->reg_dom_id;
3379 acx_s_configure(adev, &dom, ACX1xx_REG_DOT11_CURRENT_REG_DOMAIN);
3382 adev->reg_dom_chanmask = reg_domain_channel_masks[i];
3384 mask = (1 << (adev->channel - 1));
3385 if (!(adev->reg_dom_chanmask & mask)) {
3386 /* hmm, need to adjust our channel to reside within domain */
3387 mask = 1;
3388 for (i = 1; i <= 14; i++) {
3389 if (adev->reg_dom_chanmask & mask) {
3390 printk("%s: adjusting selected channel from %d "
3391 "to %d due to new regulatory domain\n",
3392 wiphy_name(adev->ieee->wiphy), adev->channel, i);
3393 adev->channel = i;
3394 break;
3396 mask <<= 1;
3401 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3403 u32 feature1, feature2;
3405 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3406 printk("%s: invalid sensitivity setting (1..3), "
3407 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3408 adev->sensitivity = 1;
3410 acx111_s_get_feature_config(adev, &feature1, &feature2);
3411 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3412 if (adev->sensitivity > 1)
3413 SET_BIT(feature1, FEATURE1_LOW_RX);
3414 if (adev->sensitivity > 2)
3415 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3416 acx111_s_feature_set(adev, feature1, feature2);
3420 void acx_s_update_card_settings(acx_device_t *adev)
3422 unsigned long flags;
3423 unsigned int start_scan = 0;
3424 int i;
3426 FN_ENTER;
3428 log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3429 adev->get_mask, adev->set_mask);
3431 /* Track dependencies betweed various settings */
3433 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3434 log(L_INIT, "important setting has been changed. "
3435 "Need to update packet templates, too\n");
3436 SET_BIT(adev->set_mask, SET_TEMPLATES);
3438 if (adev->set_mask & GETSET_CHANNEL) {
3439 /* This will actually tune RX/TX to the channel */
3440 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3441 switch (adev->mode) {
3442 case ACX_MODE_0_ADHOC:
3443 case ACX_MODE_3_AP:
3444 /* Beacons contain channel# - update them */
3445 SET_BIT(adev->set_mask, SET_TEMPLATES);
3448 switch (adev->mode) {
3449 case ACX_MODE_0_ADHOC:
3450 case ACX_MODE_2_STA:
3451 start_scan = 1;
3455 /* Apply settings */
3458 if (adev->get_mask & GETSET_STATION_ID) {
3459 u8 stationID[4 + ACX1xx_REG_DOT11_STATION_ID_LEN];
3460 const u8 *paddr;
3462 acx_s_query(adev, &stationID, ACX1xx_REG_DOT11_STATION_ID);
3463 paddr = &stationID[4];
3464 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3465 for (i = 0; i < ETH_ALEN; i++) {
3466 /* we copy the MAC address (reversed in
3467 * the card) to the netdevice's MAC
3468 * address, and on ifup it will be
3469 * copied into iwadev->dev_addr */
3470 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3472 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3473 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3476 if (adev->get_mask & GETSET_SENSITIVITY) {
3477 if ((RADIO_RFMD_11 == adev->radio_type)
3478 || (RADIO_MAXIM_0D == adev->radio_type)
3479 || (RADIO_RALINK_15 == adev->radio_type)) {
3480 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3481 } else {
3482 log(L_INIT, "don't know how to get sensitivity "
3483 "for radio type 0x%02X\n", adev->radio_type);
3484 adev->sensitivity = 0;
3486 log(L_INIT, "got sensitivity value %u\n", adev->sensitivity);
3488 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3491 if (adev->get_mask & GETSET_ANTENNA) {
3492 u8 antenna[4 + ACX1xx_REG_DOT11_CURRENT_ANTENNA_LEN];
3494 memset(antenna, 0, sizeof(antenna));
3495 acx_s_query(adev, antenna,
3496 ACX1xx_REG_DOT11_CURRENT_ANTENNA);
3497 adev->antenna = antenna[4];
3498 log(L_INIT, "got antenna value 0x%02X\n", adev->antenna);
3499 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3502 if (adev->get_mask & GETSET_ED_THRESH) {
3503 if (IS_ACX100(adev)) {
3504 u8 ed_threshold[4 + ACX100_REG_DOT11_ED_THRESHOLD_LEN];
3506 memset(ed_threshold, 0, sizeof(ed_threshold));
3507 acx_s_query(adev, ed_threshold,
3508 ACX100_REG_DOT11_ED_THRESHOLD);
3509 adev->ed_threshold = ed_threshold[4];
3510 } else {
3511 log(L_INIT, "acx111 doesn't support ED\n");
3512 adev->ed_threshold = 0;
3514 log(L_INIT, "got Energy Detect (ED) threshold %u\n",
3515 adev->ed_threshold);
3516 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3519 if (adev->get_mask & GETSET_CCA) {
3520 if (IS_ACX100(adev)) {
3521 u8 cca[4 + ACX1xx_REG_DOT11_CURRENT_CCA_MODE_LEN];
3523 memset(cca, 0, sizeof(adev->cca));
3524 acx_s_query(adev, cca,
3525 ACX1xx_REG_DOT11_CURRENT_CCA_MODE);
3526 adev->cca = cca[4];
3527 } else {
3528 log(L_INIT, "acx111 doesn't support CCA\n");
3529 adev->cca = 0;
3531 log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n",
3532 adev->cca);
3533 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3536 if (adev->get_mask & GETSET_REG_DOMAIN) {
3537 acx_ie_generic_t dom;
3539 acx_s_query(adev, &dom,
3540 ACX1xx_REG_DOT11_CURRENT_REG_DOMAIN);
3541 adev->reg_dom_id = dom.m.bytes[0];
3542 acx_s_set_sane_reg_domain(adev, 0);
3543 log(L_INIT, "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3544 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3547 if (adev->set_mask & GETSET_STATION_ID) {
3548 u8 stationID[4 + ACX1xx_REG_DOT11_STATION_ID_LEN];
3549 u8 *paddr;
3551 paddr = &stationID[4];
3552 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3553 for (i = 0; i < ETH_ALEN; i++) {
3554 /* copy the MAC address we obtained when we noticed
3555 * that the ethernet iface's MAC changed
3556 * to the card (reversed in
3557 * the card!) */
3558 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3560 acx_s_configure(adev, &stationID, ACX1xx_REG_DOT11_STATION_ID);
3561 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3564 if (adev->set_mask & SET_STA_LIST) {
3565 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3567 if (adev->set_mask & SET_RATE_FALLBACK) {
3568 u8 rate[4 + ACX1xx_REG_RATE_FALLBACK_LEN];
3570 /* configure to not do fallbacks when not in auto rate mode */
3571 rate[4] =
3572 (adev->
3573 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3574 log(L_INIT, "updating Tx fallback to %u retries\n", rate[4]);
3575 acx_s_configure(adev, &rate, ACX1xx_REG_RATE_FALLBACK);
3576 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3578 if (adev->set_mask & GETSET_TXPOWER) {
3579 log(L_INIT, "updating transmit power: %u dBm\n",
3580 adev->tx_level_dbm);
3581 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3582 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3585 if (adev->set_mask & GETSET_SENSITIVITY) {
3586 log(L_INIT, "updating sensitivity value: %u\n",
3587 adev->sensitivity);
3588 switch (adev->radio_type) {
3589 case RADIO_RFMD_11:
3590 case RADIO_MAXIM_0D:
3591 case RADIO_RALINK_15:
3592 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3593 break;
3594 case RADIO_RADIA_16:
3595 case RADIO_UNKNOWN_17:
3596 acx111_s_sens_radio_16_17(adev);
3597 break;
3598 default:
3599 log(L_INIT, "don't know how to modify sensitivity "
3600 "for radio type 0x%02X\n", adev->radio_type);
3602 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3605 if (adev->set_mask & GETSET_ANTENNA) {
3606 /* antenna */
3607 u8 antenna[4 + ACX1xx_REG_DOT11_CURRENT_ANTENNA_LEN];
3609 memset(antenna, 0, sizeof(antenna));
3610 antenna[4] = adev->antenna;
3611 log(L_INIT, "updating antenna value: 0x%02X\n", adev->antenna);
3612 acx_s_configure(adev, &antenna,
3613 ACX1xx_REG_DOT11_CURRENT_ANTENNA);
3614 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3617 if (adev->set_mask & GETSET_ED_THRESH) {
3618 /* ed_threshold */
3619 log(L_INIT, "updating Energy Detect (ED) threshold: %u\n",
3620 adev->ed_threshold);
3621 if (IS_ACX100(adev)) {
3622 u8 ed_threshold[4 + ACX100_REG_DOT11_ED_THRESHOLD_LEN];
3624 memset(ed_threshold, 0, sizeof(ed_threshold));
3625 ed_threshold[4] = adev->ed_threshold;
3626 acx_s_configure(adev, &ed_threshold,
3627 ACX100_REG_DOT11_ED_THRESHOLD);
3628 } else
3629 log(L_INIT, "acx111 doesn't support ED!\n");
3630 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3633 if (adev->set_mask & GETSET_CCA) {
3634 /* CCA value */
3635 log(L_INIT, "updating Channel Clear Assessment "
3636 "(CCA) value: 0x%02X\n", adev->cca);
3637 if (IS_ACX100(adev)) {
3638 u8 cca[4 + ACX1xx_REG_DOT11_CURRENT_CCA_MODE_LEN];
3640 memset(cca, 0, sizeof(cca));
3641 cca[4] = adev->cca;
3642 acx_s_configure(adev, &cca,
3643 ACX1xx_REG_DOT11_CURRENT_CCA_MODE);
3644 } else
3645 log(L_INIT, "acx111 doesn't support CCA!\n");
3646 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3649 if (adev->set_mask & GETSET_LED_POWER) {
3650 /* Enable Tx */
3651 log(L_INIT, "updating power LED status: %u\n", adev->led_power);
3653 acx_lock(adev, flags); /* acxpci_l_power_led expects that the lock is already taken! */
3654 if (IS_PCI(adev))
3655 acxpci_l_power_led(adev, adev->led_power);
3656 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3657 acx_unlock(adev, flags);
3660 if (adev->set_mask & GETSET_POWER_80211) {
3661 #if POWER_SAVE_80211
3662 acx_s_update_80211_powersave_mode(adev);
3663 #endif
3664 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3667 if (adev->set_mask & GETSET_CHANNEL) {
3668 /* channel */
3669 log(L_INIT, "updating channel to: %u\n", adev->channel);
3670 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3673 if (adev->set_mask & GETSET_TX) {
3674 /* set Tx */
3675 log(L_INIT, "updating: %s Tx\n",
3676 adev->tx_disabled ? "disable" : "enable");
3677 if (adev->tx_disabled)
3678 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3679 else {
3680 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3681 &adev->channel, 1);
3682 FIXME();
3683 /* This needs to be keyed on WEP? */
3684 /* acx111_s_feature_on(adev, 0,
3685 FEATURE2_NO_TXCRYPT |
3686 FEATURE2_SNIFFER); */
3687 acx_wake_queue(adev->ieee, NULL);
3689 CLEAR_BIT(adev->set_mask, GETSET_TX);
3692 if (adev->set_mask & GETSET_RX) {
3693 /* Enable Rx */
3694 log(L_INIT, "updating: enable Rx on channel: %u\n",
3695 adev->channel);
3696 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3697 CLEAR_BIT(adev->set_mask, GETSET_RX);
3700 if (adev->set_mask & GETSET_RETRY) {
3701 u8 short_retry[4 + ACX1xx_REG_DOT11_SHORT_RETRY_LIMIT_LEN];
3702 u8 long_retry[4 + ACX1xx_REG_DOT11_LONG_RETRY_LIMIT_LEN];
3704 log(L_INIT,
3705 "updating short retry limit: %u, long retry limit: %u\n",
3706 adev->short_retry, adev->long_retry);
3707 short_retry[0x4] = adev->short_retry;
3708 long_retry[0x4] = adev->long_retry;
3709 acx_s_configure(adev, &short_retry,
3710 ACX1xx_REG_DOT11_SHORT_RETRY_LIMIT);
3711 acx_s_configure(adev, &long_retry,
3712 ACX1xx_REG_DOT11_LONG_RETRY_LIMIT);
3713 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3716 if (adev->set_mask & SET_MSDU_LIFETIME) {
3717 u8 xmt_msdu_lifetime[4 +
3718 ACX1xx_REG_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3720 log(L_INIT, "updating tx MSDU lifetime: %u\n",
3721 adev->msdu_lifetime);
3722 *(u32 *) & xmt_msdu_lifetime[4] =
3723 cpu_to_le32((u32) adev->msdu_lifetime);
3724 acx_s_configure(adev, &xmt_msdu_lifetime,
3725 ACX1xx_REG_DOT11_MAX_XMIT_MSDU_LIFETIME);
3726 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3729 if (adev->set_mask & GETSET_REG_DOMAIN) {
3730 log(L_INIT, "updating regulatory domain: 0x%02X\n",
3731 adev->reg_dom_id);
3732 acx_s_set_sane_reg_domain(adev, 1);
3733 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3735 if (adev->set_mask & GETSET_MODE ) {
3736 acx111_s_feature_on(adev, 0,
3737 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3738 switch (adev->mode) {
3739 case ACX_MODE_3_AP:
3740 adev->aid = 0;
3741 //acx111_s_feature_off(adev, 0,
3742 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3743 MAC_COPY(adev->bssid, adev->dev_addr);
3744 acx_s_cmd_join_bssid(adev, adev->dev_addr);
3745 break;
3746 case ACX_MODE_MONITOR:
3747 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3748 break;
3749 case ACX_MODE_0_ADHOC:
3750 case ACX_MODE_2_STA:
3751 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3752 break;
3753 default:
3754 break;
3756 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3758 if (adev->set_mask & SET_TEMPLATES) {
3759 switch (adev->mode)
3761 case ACX_MODE_3_AP:
3762 acx_s_set_tim_template(adev);
3763 break;
3764 default:
3765 break;
3767 if (adev->beacon_cache)
3769 acx_s_set_beacon_template(adev, adev->beacon_cache);
3770 dev_kfree_skb(adev->beacon_cache);
3771 adev->beacon_cache = NULL;
3773 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3776 if (adev->set_mask & SET_RXCONFIG) {
3777 acx_s_initialize_rx_config(adev);
3778 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3781 if (adev->set_mask & GETSET_RESCAN) {
3782 /* switch (adev->mode) {
3783 case ACX_MODE_0_ADHOC:
3784 case ACX_MODE_2_STA:
3785 start_scan = 1;
3786 break;
3788 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3791 if (adev->set_mask & GETSET_WEP) {
3792 /* encode */
3794 ie_dot11WEPDefaultKeyID_t dkey;
3795 #ifdef DEBUG_WEP
3796 struct {
3797 u16 type;
3798 u16 len;
3799 u8 val;
3800 } ACX_PACKED keyindic;
3801 #endif
3802 log(L_INIT, "updating WEP key settings\n");
3804 acx_s_set_wepkey(adev);
3805 if (adev->wep_enabled) {
3806 dkey.KeyID = adev->wep_current_index;
3807 log(L_INIT, "setting WEP key %u as default\n",
3808 dkey.KeyID);
3809 acx_s_configure(adev, &dkey,
3810 ACX1xx_REG_DOT11_WEP_DEFAULT_KEY_SET);
3811 #ifdef DEBUG_WEP
3812 keyindic.val = 3;
3813 acx_s_configure(adev, &keyindic, ACX111_REG_KEY_CHOOSE);
3814 #endif
3817 // start_scan = 1;
3818 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3821 if (adev->set_mask & SET_WEP_OPTIONS) {
3822 acx100_ie_wep_options_t options;
3824 if (IS_ACX111(adev)) {
3825 log(L_DEBUG,
3826 "setting WEP Options for acx111 is not supported\n");
3827 } else {
3828 log(L_INIT, "setting WEP Options\n");
3830 /* let's choose maximum setting: 4 default keys,
3831 * plus 10 other keys: */
3832 options.NumKeys =
3833 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3834 /* don't decrypt default key only,
3835 * don't override decryption: */
3836 options.WEPOption = 0;
3837 if (adev->mode == ACX_MODE_3_AP) {
3838 /* don't decrypt default key only,
3839 * override decryption mechanism: */
3840 options.WEPOption = 2;
3843 acx_s_configure(adev, &options, ACX100_REG_WEP_OPTIONS);
3845 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3849 /* debug, rate, and nick don't need any handling */
3850 /* what about sniffing mode?? */
3852 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3853 adev->get_mask, adev->set_mask);
3855 /* end: */
3856 FN_EXIT0;
3859 #if 0
3860 /***********************************************************************
3861 ** acx_e_after_interrupt_task
3863 static int acx_s_recalib_radio(acx_device_t * adev)
3865 if (IS_ACX111(adev)) {
3866 acx111_cmd_radiocalib_t cal;
3868 /* automatic recalibration, choose all methods: */
3869 cal.methods = cpu_to_le32(0x8000000f);
3870 /* automatic recalibration every 60 seconds (value in TUs)
3871 * I wonder what the firmware default here is? */
3872 cal.interval = cpu_to_le32(58594);
3873 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3874 &cal, sizeof(cal),
3875 CMD_TIMEOUT_MS(100));
3876 } else {
3877 /* On ACX100, we need to recalibrate the radio
3878 * by issuing a GETSET_TX|GETSET_RX */
3879 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3880 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3881 (OK ==
3882 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3883 &adev->channel, 1))
3884 && (OK ==
3885 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3886 &adev->channel, 1)))
3887 return OK;
3888 return NOT_OK;
3891 #endif // if 0
3892 #if 0
3893 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3895 int res;
3897 /* this helps with ACX100 at least;
3898 * hopefully ACX111 also does a
3899 * recalibration here */
3901 /* clear flag beforehand, since we want to make sure
3902 * it's cleared; then only set it again on specific circumstances */
3903 CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3905 /* better wait a bit between recalibrations to
3906 * prevent overheating due to torturing the card
3907 * into working too long despite high temperature
3908 * (just a safety measure) */
3909 if (adev->recalib_time_last_success
3910 && time_before(jiffies, adev->recalib_time_last_success
3911 + RECALIB_PAUSE * 60 * HZ)) {
3912 if (adev->recalib_msg_ratelimit <= 4) {
3913 printk("%s: less than " STRING(RECALIB_PAUSE)
3914 " minutes since last radio recalibration, "
3915 "not recalibrating (maybe card is too hot?)\n",
3916 wiphy_name(adev->ieee->wiphy));
3917 adev->recalib_msg_ratelimit++;
3918 if (adev->recalib_msg_ratelimit == 5)
3919 printk("disabling above message until next recalib\n");
3921 return;
3924 adev->recalib_msg_ratelimit = 0;
3926 /* note that commands sometimes fail (card busy),
3927 * so only clear flag if we were fully successful */
3928 res = acx_s_recalib_radio(adev);
3929 if (res == OK) {
3930 printk("%s: successfully recalibrated radio\n",
3931 wiphy_name(adev->ieee->wiphy));
3932 adev->recalib_time_last_success = jiffies;
3933 adev->recalib_failure_count = 0;
3934 } else {
3935 /* failed: resubmit, but only limited
3936 * amount of times within some time range
3937 * to prevent endless loop */
3939 adev->recalib_time_last_success = 0; /* we failed */
3941 /* if some time passed between last
3942 * attempts, then reset failure retry counter
3943 * to be able to do next recalib attempt */
3944 if (time_after
3945 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3946 adev->recalib_failure_count = 0;
3948 if (adev->recalib_failure_count < 5) {
3949 /* increment inside only, for speedup of outside path */
3950 adev->recalib_failure_count++;
3951 adev->recalib_time_last_attempt = jiffies;
3952 acx_schedule_task(adev,
3953 ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3957 #endif // if 0
3959 void acx_e_after_interrupt_task(struct work_struct *work)
3961 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
3962 unsigned long flags;
3964 FN_ENTER;
3966 acx_lock(adev, flags);
3968 if (!adev->after_interrupt_jobs || !adev->initialized)
3969 goto end; /* no jobs to do */
3971 /* we see lotsa tx errors */
3972 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) {
3973 printk("too many TX errors??\n");
3974 // acx_s_after_interrupt_recalib(adev);
3977 /* a poor interrupt code wanted to do update_card_settings() */
3978 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) {
3979 if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
3980 acx_unlock(adev, flags);
3981 acx_s_update_card_settings(adev);
3982 acx_lock(adev, flags);
3984 CLEAR_BIT(adev->after_interrupt_jobs,
3985 ACX_AFTER_IRQ_UPDATE_CARD_CFG);
3988 /* 1) we detected that no Scan_Complete IRQ came from fw, or
3989 ** 2) we found too many STAs */
3990 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) {
3991 log(L_IRQ, "sending a stop scan cmd...\n");
3992 acx_unlock(adev, flags);
3993 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
3994 acx_lock(adev, flags);
3995 /* HACK: set the IRQ bit, since we won't get a
3996 * scan complete IRQ any more on ACX111 (works on ACX100!),
3997 * since _we_, not a fw, have stopped the scan */
3998 SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
3999 CLEAR_BIT(adev->after_interrupt_jobs,
4000 ACX_AFTER_IRQ_CMD_STOP_SCAN);
4003 /* either fw sent Scan_Complete or we detected that
4004 ** no Scan_Complete IRQ came from fw. Finish scanning,
4005 ** pick join partner if any */
4006 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) {
4007 /* + scan kills current join status - restore it
4008 ** (do we need it for STA?) */
4009 /* + does it happen only with active scans?
4010 ** active and passive scans? ALL scans including
4011 ** background one? */
4012 /* + was not verified that everything is restored
4013 ** (but at least we start to emit beacons again) */
4014 CLEAR_BIT(adev->after_interrupt_jobs,
4015 ACX_AFTER_IRQ_COMPLETE_SCAN);
4018 /* STA auth or assoc timed out, start over again */
4020 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) {
4021 log(L_IRQ, "sending a start_scan cmd...\n");
4022 CLEAR_BIT(adev->after_interrupt_jobs,
4023 ACX_AFTER_IRQ_RESTART_SCAN);
4026 /* whee, we got positive assoc response! 8) */
4027 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) {
4028 CLEAR_BIT(adev->after_interrupt_jobs,
4029 ACX_AFTER_IRQ_CMD_ASSOCIATE);
4031 end:
4032 if(adev->after_interrupt_jobs)
4034 printk("Jobs still to be run: %x\n",adev->after_interrupt_jobs);
4035 adev->after_interrupt_jobs = 0;
4037 acx_unlock(adev, flags);
4038 // acx_sem_unlock(adev);
4039 FN_EXIT0;
4043 /***********************************************************************
4044 ** acx_schedule_task
4046 ** Schedule the call of the after_interrupt method after leaving
4047 ** the interrupt context.
4049 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
4051 if (!adev->after_interrupt_jobs)
4053 SET_BIT(adev->after_interrupt_jobs, set_flag);
4054 schedule_work(&adev->after_interrupt_task);
4059 /***********************************************************************
4061 void acx_init_task_scheduler(acx_device_t * adev)
4063 /* configure task scheduler */
4064 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4068 /***********************************************************************
4069 ** acx_s_start
4071 void acx_s_start(acx_device_t * adev)
4073 FN_ENTER;
4076 * Ok, now we do everything that can possibly be done with ioctl
4077 * calls to make sure that when it was called before the card
4078 * was up we get the changes asked for
4081 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4082 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4083 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4084 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4086 log(L_INIT, "updating initial settings on iface activation\n");
4087 acx_s_update_card_settings(adev);
4089 FN_EXIT0;
4093 /***********************************************************************
4094 ** acx_update_capabilities
4095 *//*
4096 void acx_update_capabilities(acx_device_t * adev)
4098 u16 cap = 0;
4100 switch (adev->mode) {
4101 case ACX_MODE_3_AP:
4102 SET_BIT(cap, WF_MGMT_CAP_ESS);
4103 break;
4104 case ACX_MODE_0_ADHOC:
4105 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4106 break;
4107 */ /* other types of stations do not emit beacons */
4108 /* }
4110 if (adev->wep_restricted) {
4111 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4113 if (adev->cfgopt_dot11ShortPreambleOption) {
4114 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4116 if (adev->cfgopt_dot11PBCCOption) {
4117 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4119 if (adev->cfgopt_dot11ChannelAgility) {
4120 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4122 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4123 adev->capabilities, cap);
4124 adev->capabilities = cap;
4128 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4131 static void acx_s_select_opmode(acx_device_t * adev)
4133 int changed = 0;
4134 FN_ENTER;
4136 if (adev->interface.operating) {
4137 switch (adev->interface.type) {
4138 case IEEE80211_IF_TYPE_AP:
4139 if (adev->mode != ACX_MODE_3_AP)
4141 adev->mode = ACX_MODE_3_AP;
4142 changed = 1;
4144 break;
4145 case IEEE80211_IF_TYPE_IBSS:
4146 if (adev->mode != ACX_MODE_0_ADHOC)
4148 adev->mode = ACX_MODE_0_ADHOC;
4149 changed = 1;
4151 break;
4152 case IEEE80211_IF_TYPE_STA:
4153 if (adev->mode != ACX_MODE_2_STA)
4155 adev->mode = ACX_MODE_2_STA;
4156 changed = 1;
4158 break;
4159 case IEEE80211_IF_TYPE_WDS:
4160 default:
4161 if (adev->mode != ACX_MODE_OFF)
4163 adev->mode = ACX_MODE_OFF;
4164 changed = 1;
4166 break;
4168 } else {
4169 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4171 if (adev->mode != ACX_MODE_MONITOR)
4173 adev->mode = ACX_MODE_MONITOR;
4174 changed = 1;
4177 else
4179 if (adev->mode != ACX_MODE_OFF)
4181 adev->mode = ACX_MODE_OFF;
4182 changed = 1;
4186 if (changed)
4188 SET_BIT(adev->set_mask, GETSET_MODE);
4189 acx_s_update_card_settings(adev);
4190 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4193 FN_EXIT0;
4197 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4201 int acx_add_interface(struct ieee80211_hw *ieee,
4202 struct ieee80211_if_init_conf *conf)
4204 acx_device_t *adev = ieee2adev(ieee);
4205 unsigned long flags;
4206 int err = -EOPNOTSUPP;
4208 DECLARE_MAC_BUF(mac);
4210 FN_ENTER;
4211 acx_lock(adev, flags);
4213 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4214 adev->interface.monitor++;
4215 } else {
4216 if (adev->interface.operating)
4217 goto out_unlock;
4218 adev->interface.operating = 1;
4219 adev->interface.type = conf->type;
4221 // adev->mode = conf->type;
4223 acx_unlock(adev, flags);
4225 if (adev->initialized)
4226 acx_s_select_opmode(adev);
4228 acx_lock(adev, flags);
4230 err = 0;
4232 printk(KERN_INFO "Virtual interface added "
4233 "(type: 0x%08X, MAC: %s)\n",
4234 conf->type,
4235 print_mac(mac, conf->mac_addr));
4237 out_unlock:
4238 acx_unlock(adev, flags);
4240 FN_EXIT0;
4241 return err;
4244 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4248 void acx_remove_interface(struct ieee80211_hw *hw,
4249 struct ieee80211_if_init_conf *conf)
4251 acx_device_t *adev = ieee2adev(hw);
4253 DECLARE_MAC_BUF(mac);
4255 FN_ENTER;
4257 acx_sem_lock(adev);
4258 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4259 adev->interface.monitor--;
4260 // assert(bcm->interface.monitor >= 0);
4261 } else {
4262 adev->interface.operating = 0;
4265 printk("Removing interface: %d %d\n", adev->interface.operating, conf->type);
4266 acx_sem_unlock(adev);
4268 if (adev->initialized)
4269 acx_s_select_opmode(adev);
4270 flush_scheduled_work();
4272 printk(KERN_INFO "Virtual interface removed "
4273 "(type: 0x%08X, MAC: %s)\n",
4274 conf->type, print_mac(mac, conf->mac_addr));
4276 FN_EXIT0;
4279 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4283 int acx_net_reset(struct ieee80211_hw *ieee)
4285 acx_device_t *adev = ieee2adev(ieee);
4286 FN_ENTER;
4287 if (IS_PCI(adev))
4288 acxpci_s_reset_dev(adev);
4289 else
4290 TODO();
4292 FN_EXIT0;
4293 return 0;
4297 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4300 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4302 int result;
4304 FN_ENTER;
4306 acx_sem_lock(adev);
4307 adev->rx_status.channel = channel;
4308 adev->rx_status.freq = freq;
4310 adev->channel = channel;
4311 /* hmm, the following code part is strange, but this is how
4312 * it was being done before... */
4313 log(L_IOCTL, "Changing to channel %d\n", channel);
4314 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4315 result = -EINPROGRESS; /* need to call commit handler */
4317 acx_sem_unlock(adev);
4318 FN_EXIT1(result);
4319 return result;
4323 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4326 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4328 acx_device_t *adev = ieee2adev(hw);
4329 unsigned long flags;
4331 FN_ENTER;
4333 acx_lock(adev, flags);
4334 //FIXME();
4335 if (!adev->initialized) {
4336 acx_unlock(adev, flags);
4337 return 0;
4339 if (conf->beacon_int != adev->beacon_interval)
4340 adev->beacon_interval = conf->beacon_int;
4341 if (conf->channel != adev->channel) {
4342 acx_unlock(adev, flags);
4343 acx_selectchannel(adev, conf->channel,conf->freq);
4344 acx_lock(adev, flags);
4345 /* acx_schedule_task(adev,
4346 ACX_AFTER_IRQ_UPDATE_CARD_CFG
4347 */ /*+ ACX_AFTER_IRQ_RESTART_SCAN */ /*);*/
4350 if (conf->short_slot_time != adev->short_slot) {
4351 // assert(phy->type == BCM43xx_PHYTYPE_G);
4352 if (conf->short_slot_time)
4353 acx_short_slot_timing_enable(adev);
4354 else
4355 acx_short_slot_timing_disable(adev);
4356 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4359 adev->tx_disabled = !conf->radio_enabled;
4360 /* if (conf->power_level != 0){
4361 adev->tx_level_dbm = conf->power_level;
4362 acx_s_set_tx_level(adev, adev->tx_level_dbm);
4363 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4364 //acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4367 //FIXME: This does not seem to wake up:
4368 #if 0
4369 if (conf->power_level == 0) {
4370 if (radio->enabled)
4371 bcm43xx_radio_turn_off(bcm);
4372 } else {
4373 if (!radio->enabled)
4374 bcm43xx_radio_turn_on(bcm);
4376 #endif
4378 //TODO: phymode
4379 //TODO: antennas
4380 if (adev->set_mask > 0) {
4381 acx_unlock(adev, flags);
4382 acx_s_update_card_settings(adev);
4383 acx_lock(adev, flags);
4385 acx_unlock(adev, flags);
4387 FN_EXIT0;
4388 return 0;
4392 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4396 extern int acx_config_interface(struct ieee80211_hw* ieee,
4397 struct ieee80211_vif *vif,
4398 struct ieee80211_if_conf *conf)
4400 acx_device_t *adev = ieee2adev(ieee);
4401 unsigned long flags;
4402 int err = -ENODEV;
4403 FN_ENTER;
4404 if (!adev->interface.operating)
4405 goto err_out;
4407 if (adev->initialized)
4408 acx_s_select_opmode(adev);
4410 acx_lock(adev, flags);
4412 if ((conf->type == IEEE80211_IF_TYPE_AP)
4413 && (adev->vif == vif)) {
4414 if ((conf->ssid_len > 0) && conf->ssid)
4416 adev->essid_len = conf->ssid_len;
4417 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4418 SET_BIT(adev->set_mask, SET_TEMPLATES);
4421 if (conf->beacon != 0)
4423 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4424 adev->beacon_cache = conf->beacon;
4425 SET_BIT(adev->set_mask, SET_TEMPLATES);
4428 acx_unlock(adev, flags);
4430 if (adev->set_mask != 0)
4431 acx_s_update_card_settings(adev);
4432 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4433 err = 0;
4434 err_out:
4435 FN_EXIT1(err);
4436 return err;
4440 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4444 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4445 struct ieee80211_tx_queue_stats *stats)
4447 // acx_device_t *adev = ndev2adev(net_dev);
4448 struct ieee80211_tx_queue_stats_data *data;
4449 int err = -ENODEV;
4451 FN_ENTER;
4453 // acx_lock(adev, flags);
4454 data = &(stats->data[0]);
4455 data->len = 0;
4456 data->limit = TX_CNT;
4457 data->count = 0;
4458 // acx_unlock(adev, flags);
4460 FN_EXIT0;
4461 return err;
4464 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4468 int acx_net_conf_tx(struct ieee80211_hw *hw,
4469 int queue, const struct ieee80211_tx_queue_params *params)
4471 FN_ENTER;
4472 // TODO();
4473 FN_EXIT0;
4474 return 0;
4477 static void keymac_write(acx_device_t * adev, u16 index, const u32 * addr)
4479 /* for keys 0-3 there is no associated mac address */
4480 if (index < 4)
4481 return;
4483 index -= 4;
4484 if (1) {
4485 TODO();
4487 bcm43xx_shm_write32(bcm,
4488 BCM43xx_SHM_HWMAC,
4489 index * 2,
4490 cpu_to_be32(*addr));
4491 bcm43xx_shm_write16(bcm,
4492 BCM43xx_SHM_HWMAC,
4493 (index * 2) + 1,
4494 cpu_to_be16(*((u16 *)(addr + 1))));
4496 } else {
4497 if (index < 8) {
4498 TODO(); /* Put them in the macaddress filter */
4499 } else {
4500 TODO();
4501 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4502 Keep in mind to update the count of keymacs in 0x003 */
4508 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4512 int acx_clear_keys(acx_device_t * adev)
4514 static const u32 zero_mac[2] = { 0 };
4515 unsigned int i, j, nr_keys = 54;
4516 u16 offset;
4518 /* FixMe:Check for Number of Keys available */
4520 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4522 for (i = 0; i < nr_keys; i++) {
4523 adev->key[i].enabled = 0;
4524 /* returns for i < 4 immediately */
4525 keymac_write(adev, i, zero_mac);
4527 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4528 0x100 + (i * 2), 0x0000);
4530 for (j = 0; j < 8; j++) {
4531 offset =
4532 adev->security_offset + (j * 4) +
4533 (i * ACX_SEC_KEYSIZE);
4535 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4536 offset, 0x0000);
4540 return 1;
4544 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4548 int acx_key_write(acx_device_t * adev,
4549 u16 index, u8 algorithm,
4550 const struct ieee80211_key_conf *key, const u8 * mac_addr)
4552 // struct iw_point *dwrq = &wrqu->encoding;
4553 int result;
4555 FN_ENTER;
4557 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4558 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4560 // acx_sem_lock(adev);
4562 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4563 if (key->keylen > 0) {
4564 /* if index is 0 or invalid, use default key */
4565 if (index > 3)
4566 index = (int)adev->wep_current_index;
4567 if ((algorithm == ACX_SEC_ALGO_WEP) ||
4568 (algorithm == ACX_SEC_ALGO_WEP104)) {
4569 switch(key->keylen) {
4570 case 40 / 8:
4571 /* WEP 40-bit =
4572 40-bit entered key + 24 bit IV = 64-bit */
4573 adev->wep_keys[index].size = 13;
4574 break;
4575 case 104 / 8:
4576 /* WEP 104-bit =
4577 104-bit entered key + 24-bit IV = 128-bit */
4578 adev->wep_keys[index].size = 29;
4579 break;
4580 case 128 / 8:
4581 /* WEP 128-bit =
4582 128-bit entered key + 24 bit IV = 152-bit */
4583 adev->wep_keys[index].size = 16;
4584 break;
4585 default:
4586 adev->wep_keys[index].size = 0;
4587 return -EINVAL; /* shouldn't happen */
4590 memset(adev->wep_keys[index].key, 0,
4591 sizeof(adev->wep_keys[index].key));
4592 memcpy(adev->wep_keys[index].key, key, key->keylen);
4593 } else {
4594 /* set transmit key */
4595 if (index <= 3)
4596 adev->wep_current_index = index;
4597 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4598 /* complain if we were not just setting
4599 * the key mode */
4600 // result = -EINVAL;
4601 // goto end_unlock;
4602 // }
4606 adev->wep_enabled = (algorithm == ALG_WEP);
4608 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4610 if (algorithm & IW_ENCODE_OPEN) {
4611 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4612 adev->wep_restricted = 0;
4614 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4615 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4616 adev->wep_restricted = 1;
4619 // adev->auth_alg = algorithm;
4620 /* set flag to make sure the card WEP settings get updated */
4621 if (adev->wep_enabled) {
4622 SET_BIT(adev->set_mask, GETSET_WEP);
4623 acx_s_update_card_settings(adev);
4624 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4627 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4628 dwrq->length, extra, dwrq->flags);
4629 for (index = 0; index <= 3; index++) {
4630 if (adev->wep_keys[index].size) {
4631 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4632 adev->wep_keys[index].index,
4633 (int) adev->wep_keys[index].size,
4634 adev->wep_keys[index].key);
4638 result = -EINPROGRESS;
4639 // acx_sem_unlock(adev);
4641 FN_EXIT1(result);
4642 return result;
4648 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4652 int acx_net_set_key(struct ieee80211_hw *ieee,
4653 enum set_key_cmd cmd, const u8 *local_addr,
4654 const u8 * addr, struct ieee80211_key_conf *key)
4656 // return 0;
4657 struct acx_device *adev = ieee2adev(ieee);
4658 unsigned long flags;
4659 u8 algorithm;
4660 u16 index;
4661 int err = -EINVAL;
4662 FN_ENTER;
4663 // TODO();
4664 switch (key->alg) {
4665 default:
4666 /* case ALG_NONE:
4667 case ALG_NULL:
4668 algorithm = ACX_SEC_ALGO_NONE;
4669 break;
4670 */ case ALG_WEP:
4671 if (key->keylen == 5)
4672 algorithm = ACX_SEC_ALGO_WEP;
4673 else
4674 algorithm = ACX_SEC_ALGO_WEP104;
4675 break;
4676 case ALG_TKIP:
4677 algorithm = ACX_SEC_ALGO_TKIP;
4678 break;
4679 case ALG_CCMP:
4680 algorithm = ACX_SEC_ALGO_AES;
4681 break;
4684 index = (u8) (key->keyidx);
4685 if (index >= ARRAY_SIZE(adev->key))
4686 goto out;
4687 acx_lock(adev, flags);
4688 switch (cmd) {
4689 case SET_KEY:
4690 err = acx_key_write(adev, index, algorithm, key, addr);
4691 if (err)
4692 goto out_unlock;
4693 key->hw_key_idx = index;
4694 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4695 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4696 adev->default_key_idx = index;*/
4697 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4698 adev->key[index].enabled = 1;
4699 break;
4700 case DISABLE_KEY:
4701 adev->key[index].enabled = 0;
4702 err = 0;
4703 break;
4704 /* case ENABLE_COMPRESSION:
4705 case DISABLE_COMPRESSION:
4706 err = 0;
4707 break; */
4709 out_unlock:
4710 acx_unlock(adev, flags);
4711 out:
4712 FN_EXIT0;
4713 return err;
4718 /***********************************************************************
4719 ** Common function to parse ALL configoption struct formats
4720 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4721 ** FIXME: logging should be removed here and added to a /proc file instead
4723 ** Look into bcm43xx
4725 void
4726 acx_s_parse_configoption(acx_device_t * adev,
4727 const acx111_ie_configoption_t * pcfg)
4729 const u8 *pEle;
4730 int i;
4731 int is_acx111 = IS_ACX111(adev);
4733 if (acx_debug & L_DEBUG) {
4734 printk("configoption struct content:\n");
4735 acx_dump_bytes(pcfg, sizeof(*pcfg));
4738 if ((is_acx111 && (adev->eeprom_version == 5))
4739 || (!is_acx111 && (adev->eeprom_version == 4))
4740 || (!is_acx111 && (adev->eeprom_version == 5))) {
4741 /* these versions are known to be supported */
4742 } else {
4743 printk("unknown chip and EEPROM version combination (%s, v%d), "
4744 "don't know how to parse config options yet. "
4745 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4746 adev->eeprom_version);
4747 return;
4750 /* first custom-parse the first part which has chip-specific layout */
4752 pEle = (const u8 *)pcfg;
4754 pEle += 4; /* skip (type,len) header */
4756 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4757 pEle += sizeof(adev->cfgopt_NVSv);
4759 if (is_acx111) {
4760 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4761 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4763 adev->cfgopt_probe_delay = 200; /* good default value? */
4764 pEle += 2; /* FIXME: unknown, value 0x0001 */
4765 } else {
4766 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4767 pEle += sizeof(adev->cfgopt_MAC);
4769 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4770 pEle += sizeof(adev->cfgopt_probe_delay);
4771 if ((adev->cfgopt_probe_delay < 100)
4772 || (adev->cfgopt_probe_delay > 500)) {
4773 printk("strange probe_delay value %d, "
4774 "tweaking to 200\n", adev->cfgopt_probe_delay);
4775 adev->cfgopt_probe_delay = 200;
4779 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4780 pEle += sizeof(adev->cfgopt_eof_memory);
4782 printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n",
4783 adev->cfgopt_NVS_vendor_offs,
4784 adev->cfgopt_probe_delay, adev->cfgopt_eof_memory);
4786 adev->cfgopt_dot11CCAModes = *pEle++;
4787 adev->cfgopt_dot11Diversity = *pEle++;
4788 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4789 adev->cfgopt_dot11PBCCOption = *pEle++;
4790 adev->cfgopt_dot11ChannelAgility = *pEle++;
4791 adev->cfgopt_dot11PhyType = *pEle++;
4792 adev->cfgopt_dot11TempType = *pEle++;
4793 printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4794 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4795 adev->cfgopt_dot11CCAModes,
4796 adev->cfgopt_dot11Diversity,
4797 adev->cfgopt_dot11ShortPreambleOption,
4798 adev->cfgopt_dot11PBCCOption,
4799 adev->cfgopt_dot11ChannelAgility,
4800 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4802 /* then use common parsing for next part which has common layout */
4804 pEle++; /* skip table_count (6) */
4806 adev->cfgopt_antennas.type = pEle[0];
4807 adev->cfgopt_antennas.len = pEle[1];
4808 printk("AntennaID:%02X Len:%02X Data:",
4809 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4810 for (i = 0; i < pEle[1]; i++) {
4811 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4812 printk("%02X ", pEle[i + 2]);
4814 printk("\n");
4816 pEle += pEle[1] + 2;
4817 adev->cfgopt_power_levels.type = pEle[0];
4818 adev->cfgopt_power_levels.len = pEle[1];
4819 printk("PowerLevelID:%02X Len:%02X Data:",
4820 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4821 for (i = 0; i < pEle[1]; i++) {
4822 adev->cfgopt_power_levels.list[i] =
4823 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4824 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4826 printk("\n");
4828 pEle += pEle[1] * 2 + 2;
4829 adev->cfgopt_data_rates.type = pEle[0];
4830 adev->cfgopt_data_rates.len = pEle[1];
4831 printk("DataRatesID:%02X Len:%02X Data:",
4832 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4833 for (i = 0; i < pEle[1]; i++) {
4834 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4835 printk("%02X ", pEle[i + 2]);
4837 printk("\n");
4839 pEle += pEle[1] + 2;
4840 adev->cfgopt_domains.type = pEle[0];
4841 adev->cfgopt_domains.len = pEle[1];
4842 printk("DomainID:%02X Len:%02X Data:",
4843 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4844 for (i = 0; i < pEle[1]; i++) {
4845 adev->cfgopt_domains.list[i] = pEle[i + 2];
4846 printk("%02X ", pEle[i + 2]);
4848 printk("\n");
4850 pEle += pEle[1] + 2;
4851 adev->cfgopt_product_id.type = pEle[0];
4852 adev->cfgopt_product_id.len = pEle[1];
4853 for (i = 0; i < pEle[1]; i++) {
4854 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4856 printk("ProductID:%02X Len:%02X Data:%.*s\n",
4857 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4858 adev->cfgopt_product_id.len,
4859 (char *)adev->cfgopt_product_id.list);
4861 pEle += pEle[1] + 2;
4862 adev->cfgopt_manufacturer.type = pEle[0];
4863 adev->cfgopt_manufacturer.len = pEle[1];
4864 for (i = 0; i < pEle[1]; i++) {
4865 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4867 printk("ManufacturerID:%02X Len:%02X Data:%.*s\n",
4868 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4869 adev->cfgopt_manufacturer.len,
4870 (char *)adev->cfgopt_manufacturer.list);
4872 printk("EEPROM part:\n");
4873 for (i=0; i<58; i++) {
4874 printk("%02X =======> 0x%02X\n",
4875 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4881 /***********************************************************************
4882 ** Linux Kernel Specific
4884 static int __init acx_e_init_module(void)
4886 int r1, r2;
4888 acx_struct_size_check();
4890 printk("acx: this driver is still EXPERIMENTAL\n"
4891 "acx: reading README file and/or Craig's HOWTO is "
4892 "recommended, visit http://acx100.sourceforge.net/wiki in case "
4893 "of further questions/discussion\n");
4895 #if defined(CONFIG_ACX_MAC80211_PCI)
4896 r1 = acxpci_e_init_module();
4897 #else
4898 r1 = -EINVAL;
4899 #endif
4900 #if defined(CONFIG_ACX_MAC80211_USB)
4901 r2 = acxusb_e_init_module();
4902 #else
4903 r2 = -EINVAL;
4904 #endif
4905 if (r2 && r1) /* both failed! */
4906 return r2 ? r2 : r1;
4907 /* return success if at least one succeeded */
4908 return 0;
4911 static void __exit acx_e_cleanup_module(void)
4913 #if defined(CONFIG_ACX_MAC80211_PCI)
4914 acxpci_e_cleanup_module();
4915 #endif
4916 #if defined(CONFIG_ACX_MAC80211_USB)
4917 acxusb_e_cleanup_module();
4918 #endif
4921 module_init(acx_e_init_module)
4922 module_exit(acx_e_cleanup_module)