Merge branch 'master' of http://xazz.no-ip.info/projects/acx-mac80211
[acx-mac80211.git] / common.c
blobe4cefa38c2442514662005962d660876f66ddba5
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_interrogate(adev, &fw, ACX1xx_IE_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 * Note: the FreeBSD and DragonFlyBSD drivers seems to use different
508 * so-called correction constants depending on the chip. They will be
509 * defined for now, but as it is still unknown whether they are correct
510 * or not, only the original value will be used. Something else to take
511 * into account is that the OpenBSD driver uses another approach and
512 * defines the maximum RSSI value depending on the chip, rather than
513 * using a value of 100 for all of them, as it is currently done here.
515 #define ACX100_RSSI_CORR 8
516 #define ACX111_RSSI_CORR 5
517 static u8 acx_signal_to_winlevel(u8 rawlevel)
519 /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
520 u8 winlevel = (((ACX100_RSSI_CORR / 2) + (rawlevel * 5)) /
521 ACX100_RSSI_CORR);
523 if (winlevel > 100)
524 winlevel = 100;
525 return winlevel;
528 u8 acx_signal_determine_quality(u8 signal, u8 noise)
530 int qual;
532 qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2;
534 if (qual > 100)
535 return 100;
536 if (qual < 0)
537 return 0;
538 return qual;
542 /***********************************************************************
543 ** Interrogate/configure commands
546 /* FIXME: the lengths given here probably aren't always correct.
547 * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4",
548 * unless the firmware actually expects a different length than the struct length */
549 static const u16 acx100_ie_len[] = {
551 ACX100_IE_ACX_TIMER_LEN,
552 sizeof(acx100_ie_powersave_t) - 4, /* is that 6 or 8??? */
553 ACX1xx_IE_QUEUE_CONFIG_LEN,
554 ACX100_IE_BLOCK_SIZE_LEN,
555 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
556 ACX1xx_IE_RATE_FALLBACK_LEN,
557 ACX100_IE_WEP_OPTIONS_LEN,
558 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
560 ACX1xx_IE_ASSOC_ID_LEN,
562 ACX111_IE_CONFIG_OPTIONS_LEN,
563 ACX1xx_IE_FWREV_LEN,
564 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
565 ACX1xx_IE_MEDIUM_USAGE_LEN,
566 ACX1xx_IE_RXCONFIG_LEN,
569 sizeof(fw_stats_t) - 4,
571 ACX1xx_IE_FEATURE_CONFIG_LEN,
572 ACX111_IE_KEY_CHOOSE_LEN,
573 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
574 ACX1FF_IE_WONE_CONFIG_LEN,
576 ACX1FF_IE_TID_CONFIG_LEN,
580 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
581 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
582 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
583 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
585 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
586 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
587 ACX1FF_IE_CCA_THRESHOLD_LEN,
588 ACX1FF_IE_EVENT_MASK_LEN,
589 ACX1FF_IE_DTIM_PERIOD_LEN,
591 ACX1FF_IE_ACI_CONFIG_SET_LEN,
598 ACX1FF_IE_EEPROM_VER_LEN,
601 static const u16 acx100_ie_len_dot11[] = {
603 ACX1xx_IE_DOT11_STATION_ID_LEN,
605 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
606 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
607 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
608 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
609 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
610 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
612 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
613 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
615 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
616 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
617 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
618 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
624 static const u16 acx111_ie_len[] = {
626 ACX100_IE_ACX_TIMER_LEN,
627 sizeof(acx111_ie_powersave_t) - 4,
628 ACX1xx_IE_QUEUE_CONFIG_LEN,
629 ACX100_IE_BLOCK_SIZE_LEN,
630 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
631 ACX1xx_IE_RATE_FALLBACK_LEN,
632 ACX100_IE_WEP_OPTIONS_LEN,
633 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
635 ACX1xx_IE_ASSOC_ID_LEN,
637 ACX111_IE_CONFIG_OPTIONS_LEN,
638 ACX1xx_IE_FWREV_LEN,
639 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
640 ACX1xx_IE_MEDIUM_USAGE_LEN,
641 ACX1xx_IE_RXCONFIG_LEN,
644 sizeof(fw_stats_t) - 4,
646 ACX1xx_IE_FEATURE_CONFIG_LEN,
647 ACX111_IE_KEY_CHOOSE_LEN,
648 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
649 ACX1FF_IE_WONE_CONFIG_LEN,
651 ACX1FF_IE_TID_CONFIG_LEN,
655 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
656 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
657 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
658 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
660 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
661 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
662 ACX1FF_IE_CCA_THRESHOLD_LEN,
663 ACX1FF_IE_EVENT_MASK_LEN,
664 ACX1FF_IE_DTIM_PERIOD_LEN,
666 ACX1FF_IE_ACI_CONFIG_SET_LEN,
673 ACX1FF_IE_EEPROM_VER_LEN,
676 static const u16 acx111_ie_len_dot11[] = {
678 ACX1xx_IE_DOT11_STATION_ID_LEN,
680 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
681 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
682 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
683 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
684 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
685 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
687 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
688 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
690 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
691 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
692 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
693 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
700 #undef FUNC
701 #define FUNC "configure"
702 #if !ACX_DEBUG
703 int acx_s_configure(acx_device_t * adev, void *pdr, int type)
705 #else
707 acx_s_configure_debug(acx_device_t * adev, void *pdr, int type,
708 const char *typestr)
710 #endif
711 u16 len;
712 int res;
714 if (type < 0x1000)
715 len = adev->ie_len[type];
716 else
717 len = adev->ie_len_dot11[type - 0x1000];
719 log(L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
720 if (unlikely(!len)) {
721 log(L_DEBUG, "zero-length type %s?!\n", typestr);
724 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
725 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
726 res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4);
727 if (unlikely(OK != res)) {
728 #if ACX_DEBUG
729 printk("%s: " FUNC "(type:%s) FAILED\n", wiphy_name(adev->ieee->wiphy),
730 typestr);
731 #else
732 printk("%s: " FUNC "(type:0x%X) FAILED\n", wiphy_name(adev->ieee->wiphy),
733 type);
734 #endif
735 /* dump_stack() is already done in issue_cmd() */
737 return res;
740 #undef FUNC
741 #define FUNC "interrogate"
742 #if !ACX_DEBUG
743 int acx_s_interrogate(acx_device_t * adev, void *pdr, int type)
745 #else
747 acx_s_interrogate_debug(acx_device_t * adev, void *pdr, int type,
748 const char *typestr)
750 #endif
751 u16 len;
752 int res;
754 FN_ENTER;
756 /* FIXME: no check whether this exceeds the array yet.
757 * We should probably remember the number of entries... */
758 if (type < 0x1000)
759 len = adev->ie_len[type];
760 else
761 len = adev->ie_len_dot11[type - 0x1000];
763 log(L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
765 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
766 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
767 res = acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, pdr, len + 4);
768 if (unlikely(OK != res)) {
769 #if ACX_DEBUG
770 printk("%s: " FUNC "(type:%s) FAILED\n", wiphy_name(adev->ieee->wiphy),
771 typestr);
772 #else
773 printk("%s: " FUNC "(type:0x%X) FAILED\n", wiphy_name(adev->ieee->wiphy),
774 type);
775 #endif
776 /* dump_stack() is already done in issue_cmd() */
779 FN_EXIT1(res);
780 return res;
783 #if CMD_DISCOVERY
784 void great_inquisitor(acx_device_t * adev)
786 static struct {
787 u16 type;
788 u16 len;
789 /* 0x200 was too large here: */
790 u8 data[0x100 - 4];
791 } ACX_PACKED ie;
792 u16 type;
794 FN_ENTER;
796 /* 0..0x20, 0x1000..0x1020 */
797 for (type = 0; type <= 0x1020; type++) {
798 if (type == 0x21)
799 type = 0x1000;
800 ie.type = cpu_to_le16(type);
801 ie.len = cpu_to_le16(sizeof(ie) - 4);
802 acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie));
804 FN_EXIT0;
806 #endif
809 #ifdef CONFIG_PROC_FS
810 /***********************************************************************
811 ** /proc files
813 /***********************************************************************
814 ** acx_l_proc_output
815 ** Generate content for our /proc entry
817 ** Arguments:
818 ** buf is a pointer to write output to
819 ** adev is the usual pointer to our private struct acx_device
820 ** Returns:
821 ** number of bytes actually written to buf
822 ** Side effects:
823 ** none
825 static int acx_l_proc_output(char *buf, acx_device_t * adev)
827 char *p = buf;
829 FN_ENTER;
831 p += sprintf(p,
832 "acx driver version:\t\t" ACX_RELEASE "\n"
833 "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n"
834 "chip name:\t\t\t%s (0x%08X)\n"
835 "radio type:\t\t\t0x%02X\n"
836 "form factor:\t\t\t0x%02X\n"
837 "EEPROM version:\t\t\t0x%02X\n"
838 "firmware version:\t\t%s (0x%08X)\n",
839 adev->chip_name, adev->firmware_id,
840 adev->radio_type,
841 adev->form_factor,
842 adev->eeprom_version,
843 adev->firmware_version, adev->firmware_numver);
845 FN_EXIT1(p - buf);
846 return p - buf;
850 /***********************************************************************
852 static int acx_s_proc_diag_output(char *buf, acx_device_t * adev)
854 char *p = buf;
855 unsigned long flags;
856 ssize_t len = 0, partlen;
857 u32 temp1, temp2;
858 u8 *st, *st_end;
859 #ifdef __BIG_ENDIAN
860 u8 *st2;
861 #endif
862 fw_stats_t *fw_stats;
863 char *part_str = NULL;
864 fw_stats_tx_t *tx = NULL;
865 fw_stats_rx_t *rx = NULL;
866 fw_stats_dma_t *dma = NULL;
867 fw_stats_irq_t *irq = NULL;
868 fw_stats_wep_t *wep = NULL;
869 fw_stats_pwr_t *pwr = NULL;
870 fw_stats_mic_t *mic = NULL;
871 fw_stats_aes_t *aes = NULL;
872 fw_stats_event_t *evt = NULL;
874 FN_ENTER;
876 acx_lock(adev, flags);
878 if (IS_PCI(adev))
879 p = acxpci_s_proc_diag_output(p, adev);
881 p += sprintf(p,
882 "\n"
883 "** network status **\n"
884 "dev_state_mask 0x%04X\n"
885 "mode %u, channel %u, "
886 "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
887 adev->dev_state_mask,
888 adev->mode, adev->channel,
889 adev->reg_dom_id, adev->reg_dom_chanmask);
890 p += sprintf(p,
891 "ESSID \"%s\", essid_active %d, essid_len %d, "
892 "essid_for_assoc \"%s\", nick \"%s\"\n"
893 "WEP ena %d, restricted %d, idx %d\n",
894 adev->essid, adev->essid_active, (int)adev->essid_len,
895 adev->essid_for_assoc, adev->nick,
896 adev->wep_enabled, adev->wep_restricted,
897 adev->wep_current_index);
898 p += sprintf(p, "dev_addr " MACSTR "\n", MAC(adev->dev_addr));
899 p += sprintf(p, "bssid " MACSTR "\n", MAC(adev->bssid));
900 p += sprintf(p, "ap_filter " MACSTR "\n", MAC(adev->ap));
902 p += sprintf(p, "\n" "** PHY status **\n"
903 "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
904 "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
905 "rate_basic 0x%04X, rate_oper 0x%04X\n"
906 "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
907 "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
908 adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */
909 adev->sensitivity, adev->antenna, adev->ed_threshold,
910 adev->cca, adev->preamble_mode, adev->rate_basic, adev->rate_oper, adev->rts_threshold,
911 adev->frag_threshold, adev->short_retry, adev->long_retry,
912 adev->msdu_lifetime, adev->listen_interval,
913 adev->beacon_interval);
915 acx_unlock(adev, flags);
917 p += sprintf(p,
918 "\n"
919 "** Firmware **\n"
920 "NOTE: version dependent statistics layout, "
921 "please report if you suspect wrong parsing!\n"
922 "\n" "version \"%s\"\n", adev->firmware_version);
924 /* TODO: may replace kmalloc/memset with kzalloc once
925 * Linux 2.6.14 is widespread */
926 fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL);
927 if (!fw_stats) {
928 FN_EXIT1(0);
929 return 0;
931 memset(fw_stats, 0, sizeof(*fw_stats));
933 st = (u8 *) fw_stats;
935 part_str = "statistics query command";
937 if (OK != acx_s_interrogate(adev, st, ACX1xx_IE_FIRMWARE_STATISTICS))
938 goto fw_stats_end;
940 st += sizeof(u16);
941 len = *(u16 *) st;
943 if (len > sizeof(*fw_stats)) {
944 p += sprintf(p,
945 "firmware version with bigger fw_stats struct detected\n"
946 "(%zu vs. %zu), please report\n", len, sizeof(fw_stats_t));
947 if (len > sizeof(*fw_stats)) {
948 p += sprintf(p, "struct size exceeded allocation!\n");
949 len = sizeof(*fw_stats);
952 st += sizeof(u16);
953 st_end = st - 2 * sizeof(u16) + len;
955 #ifdef __BIG_ENDIAN
956 /* let's make one bold assumption here:
957 * (hopefully!) *all* statistics fields are u32 only,
958 * thus if we need to make endianness corrections
959 * we can simply do them in one go, in advance */
960 st2 = (u8 *) fw_stats;
961 for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4)
962 *(u32 *) st2 = le32_to_cpu(*(u32 *) st2);
963 #endif
965 part_str = "Rx/Tx";
967 /* directly at end of a struct part? --> no error! */
968 if (st == st_end)
969 goto fw_stats_end;
971 tx = (fw_stats_tx_t *) st;
972 st += sizeof(fw_stats_tx_t);
973 rx = (fw_stats_rx_t *) st;
974 st += sizeof(fw_stats_rx_t);
975 partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t);
977 if (IS_ACX100(adev)) {
978 /* at least ACX100 PCI F/W 1.9.8.b
979 * and ACX100 USB F/W 1.0.7-USB
980 * don't have those two fields... */
981 st -= 2 * sizeof(u32);
983 /* our parsing doesn't quite match this firmware yet,
984 * log failure */
985 if (st > st_end)
986 goto fw_stats_fail;
987 temp1 = temp2 = 999999999;
988 } else {
989 if (st > st_end)
990 goto fw_stats_fail;
991 temp1 = rx->rx_aci_events;
992 temp2 = rx->rx_aci_resets;
995 p += sprintf(p,
996 "%s:\n"
997 " tx_desc_overfl %u\n"
998 " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
999 " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n"
1000 " rx_aci_events %u, rx_aci_resets %u\n",
1001 part_str,
1002 tx->tx_desc_of,
1003 rx->rx_oom,
1004 rx->rx_hdr_of,
1005 rx->rx_hw_stuck,
1006 rx->rx_dropped_frame,
1007 rx->rx_frame_ptr_err, rx->rx_xfr_hint_trig, temp1, temp2);
1009 part_str = "DMA";
1011 if (st == st_end)
1012 goto fw_stats_end;
1014 dma = (fw_stats_dma_t *) st;
1015 partlen = sizeof(fw_stats_dma_t);
1016 st += partlen;
1018 if (st > st_end)
1019 goto fw_stats_fail;
1021 p += sprintf(p,
1022 "%s:\n"
1023 " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n",
1024 part_str,
1025 dma->rx_dma_req,
1026 dma->rx_dma_err, dma->tx_dma_req, dma->tx_dma_err);
1028 part_str = "IRQ";
1030 if (st == st_end)
1031 goto fw_stats_end;
1033 irq = (fw_stats_irq_t *) st;
1034 partlen = sizeof(fw_stats_irq_t);
1035 st += partlen;
1037 if (st > st_end)
1038 goto fw_stats_fail;
1040 p += sprintf(p,
1041 "%s:\n"
1042 " cmd_cplt %u, fiq %u\n"
1043 " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
1044 " irqs %u, tx_procs %u, decrypt_done %u\n"
1045 " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
1046 " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
1047 " host_acks %u, pci_pm %u, acm_wakeups %u\n",
1048 part_str,
1049 irq->cmd_cplt,
1050 irq->fiq,
1051 irq->rx_hdrs,
1052 irq->rx_cmplt,
1053 irq->rx_mem_of,
1054 irq->rx_rdys,
1055 irq->irqs,
1056 irq->tx_procs,
1057 irq->decrypt_done,
1058 irq->dma_0_done,
1059 irq->dma_1_done,
1060 irq->tx_exch_complet,
1061 irq->commands,
1062 irq->rx_procs,
1063 irq->hw_pm_mode_changes,
1064 irq->host_acks, irq->pci_pm, irq->acm_wakeups);
1066 part_str = "WEP";
1068 if (st == st_end)
1069 goto fw_stats_end;
1071 wep = (fw_stats_wep_t *) st;
1072 partlen = sizeof(fw_stats_wep_t);
1073 st += partlen;
1075 if (IS_ACX100(adev)) {
1076 /* at least ACX100 PCI F/W 1.9.8.b
1077 * and ACX100 USB F/W 1.0.7-USB
1078 * don't have those two fields... */
1079 st -= 2 * sizeof(u32);
1080 if (st > st_end)
1081 goto fw_stats_fail;
1082 temp1 = temp2 = 999999999;
1083 } else {
1084 if (st > st_end)
1085 goto fw_stats_fail;
1086 temp1 = wep->wep_pkt_decrypt;
1087 temp2 = wep->wep_decrypt_irqs;
1090 p += sprintf(p,
1091 "%s:\n"
1092 " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
1093 " wep_key_not_found %u, wep_decrypt_fail %u\n"
1094 " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
1095 part_str,
1096 wep->wep_key_count,
1097 wep->wep_default_key_count,
1098 wep->dot11_def_key_mib,
1099 wep->wep_key_not_found,
1100 wep->wep_decrypt_fail, temp1, temp2);
1102 part_str = "power";
1104 if (st == st_end)
1105 goto fw_stats_end;
1107 pwr = (fw_stats_pwr_t *) st;
1108 partlen = sizeof(fw_stats_pwr_t);
1109 st += partlen;
1111 if (st > st_end)
1112 goto fw_stats_fail;
1114 p += sprintf(p,
1115 "%s:\n"
1116 " tx_start_ctr %u, no_ps_tx_too_short %u\n"
1117 " rx_start_ctr %u, no_ps_rx_too_short %u\n"
1118 " lppd_started %u\n"
1119 " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n",
1120 part_str,
1121 pwr->tx_start_ctr,
1122 pwr->no_ps_tx_too_short,
1123 pwr->rx_start_ctr,
1124 pwr->no_ps_rx_too_short,
1125 pwr->lppd_started,
1126 pwr->no_lppd_too_noisy,
1127 pwr->no_lppd_too_short, pwr->no_lppd_matching_frame);
1129 part_str = "MIC";
1131 if (st == st_end)
1132 goto fw_stats_end;
1134 mic = (fw_stats_mic_t *) st;
1135 partlen = sizeof(fw_stats_mic_t);
1136 st += partlen;
1138 if (st > st_end)
1139 goto fw_stats_fail;
1141 p += sprintf(p,
1142 "%s:\n"
1143 " mic_rx_pkts %u, mic_calc_fail %u\n",
1144 part_str, mic->mic_rx_pkts, mic->mic_calc_fail);
1146 part_str = "AES";
1148 if (st == st_end)
1149 goto fw_stats_end;
1151 aes = (fw_stats_aes_t *) st;
1152 partlen = sizeof(fw_stats_aes_t);
1153 st += partlen;
1155 if (st > st_end)
1156 goto fw_stats_fail;
1158 p += sprintf(p,
1159 "%s:\n"
1160 " aes_enc_fail %u, aes_dec_fail %u\n"
1161 " aes_enc_pkts %u, aes_dec_pkts %u\n"
1162 " aes_enc_irq %u, aes_dec_irq %u\n",
1163 part_str,
1164 aes->aes_enc_fail,
1165 aes->aes_dec_fail,
1166 aes->aes_enc_pkts,
1167 aes->aes_dec_pkts, aes->aes_enc_irq, aes->aes_dec_irq);
1169 part_str = "event";
1171 if (st == st_end)
1172 goto fw_stats_end;
1174 evt = (fw_stats_event_t *) st;
1175 partlen = sizeof(fw_stats_event_t);
1176 st += partlen;
1178 if (st > st_end)
1179 goto fw_stats_fail;
1181 p += sprintf(p,
1182 "%s:\n"
1183 " heartbeat %u, calibration %u\n"
1184 " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
1185 " oom_late %u\n"
1186 " phy_tx_err %u, tx_stuck %u\n",
1187 part_str,
1188 evt->heartbeat,
1189 evt->calibration,
1190 evt->rx_mismatch,
1191 evt->rx_mem_empty,
1192 evt->rx_pool,
1193 evt->oom_late, evt->phy_tx_err, evt->tx_stuck);
1195 if (st < st_end)
1196 goto fw_stats_bigger;
1198 goto fw_stats_end;
1200 fw_stats_fail:
1201 st -= partlen;
1202 p += sprintf(p,
1203 "failed at %s part (size %zu), offset %zu (struct size %zu), "
1204 "please report\n", part_str, partlen,
1205 ((void *)st - (void *)fw_stats), len);
1207 fw_stats_bigger:
1208 for (; st < st_end; st += 4)
1209 p += sprintf(p,
1210 "UNKN%3d: %u\n",
1211 (int)((void *)st - (void *)fw_stats), *(u32 *) st);
1213 fw_stats_end:
1214 kfree(fw_stats);
1216 FN_EXIT1(p - buf);
1217 return p - buf;
1221 /***********************************************************************
1223 static int acx_s_proc_phy_output(char *buf, acx_device_t * adev)
1225 char *p = buf;
1226 int i;
1228 FN_ENTER;
1231 if (RADIO_RFMD_11 != adev->radio_type) {
1232 printk("sorry, not yet adapted for radio types "
1233 "other than RFMD, please verify "
1234 "PHY size etc. first!\n");
1235 goto end;
1239 /* The PHY area is only 0x80 bytes long; further pages after that
1240 * only have some page number registers with altered value,
1241 * all other registers remain the same. */
1242 for (i = 0; i < 0x80; i++) {
1243 acx_s_read_phy_reg(adev, i, p++);
1246 FN_EXIT1(p - buf);
1247 return p - buf;
1251 /***********************************************************************
1252 ** acx_e_read_proc_XXXX
1253 ** Handle our /proc entry
1255 ** Arguments:
1256 ** standard kernel read_proc interface
1257 ** Returns:
1258 ** number of bytes written to buf
1259 ** Side effects:
1260 ** none
1262 static int
1263 acx_e_read_proc(char *buf, char **start, off_t offset, int count,
1264 int *eof, void *data)
1266 acx_device_t *adev = (acx_device_t *) data;
1267 unsigned long flags;
1268 int length;
1270 FN_ENTER;
1272 acx_sem_lock(adev);
1273 acx_lock(adev, flags);
1274 /* fill buf */
1275 length = acx_l_proc_output(buf, adev);
1276 acx_unlock(adev, flags);
1277 acx_sem_unlock(adev);
1279 /* housekeeping */
1280 if (length <= offset + count)
1281 *eof = 1;
1282 *start = buf + offset;
1283 length -= offset;
1284 if (length > count)
1285 length = count;
1286 if (length < 0)
1287 length = 0;
1288 FN_EXIT1(length);
1289 return length;
1292 static int
1293 acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count,
1294 int *eof, void *data)
1296 acx_device_t *adev = (acx_device_t *) data;
1297 int length;
1299 FN_ENTER;
1301 acx_sem_lock(adev);
1302 /* fill buf */
1303 length = acx_s_proc_diag_output(buf, adev);
1304 acx_sem_unlock(adev);
1306 /* housekeeping */
1307 if (length <= offset + count)
1308 *eof = 1;
1309 *start = buf + offset;
1310 length -= offset;
1311 if (length > count)
1312 length = count;
1313 if (length < 0)
1314 length = 0;
1315 FN_EXIT1(length);
1316 return length;
1319 static int
1320 acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count,
1321 int *eof, void *data)
1323 acx_device_t *adev = (acx_device_t *) data;
1324 int length;
1326 FN_ENTER;
1328 /* fill buf */
1329 length = 0;
1330 if (IS_PCI(adev)) {
1331 acx_sem_lock(adev);
1332 length = acxpci_proc_eeprom_output(buf, adev);
1333 acx_sem_unlock(adev);
1336 /* housekeeping */
1337 if (length <= offset + count)
1338 *eof = 1;
1339 *start = buf + offset;
1340 length -= offset;
1341 if (length > count)
1342 length = count;
1343 if (length < 0)
1344 length = 0;
1345 FN_EXIT1(length);
1346 return length;
1349 static int
1350 acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count,
1351 int *eof, void *data)
1353 acx_device_t *adev = (acx_device_t *) data;
1354 int length;
1356 FN_ENTER;
1358 acx_sem_lock(adev);
1359 /* fill buf */
1360 length = acx_s_proc_phy_output(buf, adev);
1361 acx_sem_unlock(adev);
1363 /* housekeeping */
1364 if (length <= offset + count)
1365 *eof = 1;
1366 *start = buf + offset;
1367 length -= offset;
1368 if (length > count)
1369 length = count;
1370 if (length < 0)
1371 length = 0;
1372 FN_EXIT1(length);
1373 return length;
1377 /***********************************************************************
1378 ** /proc files registration
1380 static const char *const
1381 proc_files[] = { "", "_diag", "_eeprom", "_phy" };
1383 static read_proc_t *const
1384 proc_funcs[] = {
1385 acx_e_read_proc,
1386 acx_e_read_proc_diag,
1387 acx_e_read_proc_eeprom,
1388 acx_e_read_proc_phy
1391 static int manage_proc_entries(struct ieee80211_hw *hw, int remove)
1393 acx_device_t *adev = ieee2adev(hw);
1394 char procbuf[80];
1395 int i;
1397 FN_ENTER;
1399 for (i = 0; i < ARRAY_SIZE(proc_files); i++) {
1400 snprintf(procbuf, sizeof(procbuf),
1401 "driver/acx%s", proc_files[i]);
1402 log(L_INIT, "%sing /proc entry %s\n",
1403 remove ? "remov" : "creat", procbuf);
1404 if (!remove) {
1405 if (!create_proc_read_entry
1406 (procbuf, 0, NULL, proc_funcs[i], adev)) {
1407 printk("acx: cannot register /proc entry %s\n",
1408 procbuf);
1409 FN_EXIT1(NOT_OK);
1410 return NOT_OK;
1412 } else {
1413 remove_proc_entry(procbuf, NULL);
1416 FN_EXIT0;
1417 return OK;
1420 int acx_proc_register_entries(struct ieee80211_hw *ieee)
1422 return manage_proc_entries(ieee, 0);
1425 int acx_proc_unregister_entries(struct ieee80211_hw *ieee)
1427 return manage_proc_entries(ieee, 1);
1429 #endif /* CONFIG_PROC_FS */
1431 /****
1432 ** Gathered From rt2x00 and bcm43xx_mac80211 projects
1434 void acx_free_modes(acx_device_t * adev)
1437 // kfree(adev->modes);
1438 // adev->modes = NULL;
1442 #define RATETAB_ENT(_rate, _rateid, _flags) \
1444 .rate = (_rate), \
1445 .val = (_rateid), \
1446 .val2 = (_rateid), \
1447 .flags = (_flags), \
1451 static struct ieee80211_rate __acx_rates[] = {
1452 { .rate = 10,
1453 .val = RATE111_1,
1454 .flags = IEEE80211_RATE_CCK },
1455 { .rate = 20,
1456 .val = RATE111_2,
1457 .flags = IEEE80211_RATE_CCK },
1458 { .rate = 55,
1459 .val = RATE111_5,
1460 .flags = IEEE80211_RATE_CCK },
1461 { .rate = 110,
1462 .val = RATE111_11,
1463 .flags = IEEE80211_RATE_CCK },
1464 { .rate = 60,
1465 .val = RATE111_6,
1466 .flags = IEEE80211_RATE_OFDM },
1467 { .rate = 90,
1468 .val = RATE111_9,
1469 .flags = IEEE80211_RATE_OFDM },
1470 { .rate = 120,
1471 .val = RATE111_12,
1472 .flags = IEEE80211_RATE_OFDM },
1473 { .rate = 180,
1474 .val = RATE111_18,
1475 .flags = IEEE80211_RATE_OFDM },
1476 { .rate = 240,
1477 .val = RATE111_24,
1478 .flags = IEEE80211_RATE_OFDM },
1479 { .rate = 360,
1480 .val = RATE111_36,
1481 .flags = IEEE80211_RATE_OFDM },
1482 { .rate = 480,
1483 .val = RATE111_48,
1484 .flags = IEEE80211_RATE_OFDM },
1485 { .rate = 540,
1486 .val = RATE111_54,
1487 .flags = IEEE80211_RATE_OFDM },
1490 static struct ieee80211_channel channels[] = {
1491 { .chan = 1,
1492 .freq = 2412},
1493 { .chan = 2,
1494 .freq = 2417},
1495 { .chan = 3,
1496 .freq = 2422},
1497 { .chan = 4,
1498 .freq = 2427},
1499 { .chan = 5,
1500 .freq = 2432},
1501 { .chan = 6,
1502 .freq = 2437},
1503 { .chan = 7,
1504 .freq = 2442},
1505 { .chan = 8,
1506 .freq = 2447},
1507 { .chan = 9,
1508 .freq = 2452},
1509 { .chan = 10,
1510 .freq = 2457},
1511 { .chan = 11,
1512 .freq = 2462},
1513 { .chan = 12,
1514 .freq = 2467},
1515 { .chan = 13,
1516 .freq = 2472},
1519 int acx_setup_modes(acx_device_t * adev)
1521 struct ieee80211_hw *hw = adev->ieee;
1522 struct ieee80211_hw_mode *mode;
1523 int err = -ENOMEM;
1525 FN_ENTER;
1527 if (IS_ACX111(adev)) {
1529 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);
1530 err = acx_setup_modes_gphy(adev);
1532 mode = &adev->modes[0];
1534 /* from the zd1211rw driver: - do we need to do the same? */
1536 memcpy(mode->channels, channels, sizeof(channels));
1537 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1540 mode->mode = MODE_IEEE80211G;
1541 mode->num_channels = ARRAY_SIZE(channels);
1542 mode->num_rates = 12;
1543 mode->rates = __acx_rates;
1544 } else {
1546 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1547 err = acx_setup_modes_bphy(adev);
1549 mode = &adev->modes[1];
1551 /* from the zd1211rw driver: - do we need to do the same? */
1553 memcpy(mode->channels, channels, sizeof(channels));
1554 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1557 mode->mode = MODE_IEEE80211B;
1558 mode->num_channels = ARRAY_SIZE(channels);
1559 mode->num_rates = 4;
1560 mode->rates = __acx_rates;
1563 /* if (err && adev->modes)
1564 kfree(adev->modes);*/
1566 mode->channels = channels;
1567 err = ieee80211_register_hwmode(hw, mode);
1569 FN_EXIT1(err);
1570 return err;
1574 /***********************************************************************
1575 ** acx_fill_beacon_or_proberesp_template
1577 ** Origin: derived from rt2x00 project
1579 static int
1580 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1581 struct acx_template_beacon *templ,
1582 struct sk_buff* skb /* in host order! */)
1584 FN_ENTER;
1586 memcpy(templ,skb->data, skb->len);
1587 FN_EXIT1(skb->len);
1588 return skb->len;
1591 /***********************************************************************
1592 ** acx_s_set_beacon_template
1596 static int
1597 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1599 struct acx_template_beacon bcn;
1600 int len, result;
1602 FN_ENTER;
1603 printk("Size of template: %08zX, Size of beacon: %08X\n", sizeof(struct acx_template_beacon),skb->len);
1604 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1605 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1607 FN_EXIT1(result);
1608 return result;
1611 /***********************************************************************
1612 ** acx_cmd_join_bssid
1614 ** Common code for both acx100 and acx111.
1616 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1617 static const u8 bitpos2genframe_txrate[] = {
1618 10, /* 0. 1 Mbit/s */
1619 20, /* 1. 2 Mbit/s */
1620 55, /* 2. 5.5 Mbit/s */
1621 0x0B, /* 3. 6 Mbit/s */
1622 0x0F, /* 4. 9 Mbit/s */
1623 110, /* 5. 11 Mbit/s */
1624 0x0A, /* 6. 12 Mbit/s */
1625 0x0E, /* 7. 18 Mbit/s */
1626 220, /* 8. 22 Mbit/s */
1627 0x09, /* 9. 24 Mbit/s */
1628 0x0D, /* 10. 36 Mbit/s */
1629 0x08, /* 11. 48 Mbit/s */
1630 0x0C, /* 12. 54 Mbit/s */
1631 10, /* 13. 1 Mbit/s, should never happen */
1632 10, /* 14. 1 Mbit/s, should never happen */
1633 10, /* 15. 1 Mbit/s, should never happen */
1636 /* Looks scary, eh?
1637 ** Actually, each one compiled into one AND and one SHIFT,
1638 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1639 static inline unsigned int rate111to5bits(unsigned int rate)
1641 return (rate & 0x7)
1642 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1643 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1647 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1649 acx_joinbss_t tmp;
1650 int dtim_interval;
1651 int i;
1653 if (mac_is_zero(bssid))
1654 return;
1656 FN_ENTER;
1658 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1659 1 : adev->dtim_interval;
1661 memset(&tmp, 0, sizeof(tmp));
1663 for (i = 0; i < ETH_ALEN; i++) {
1664 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1667 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1669 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1670 ** are sent with one of these rates */
1671 if (IS_ACX111(adev)) {
1672 /* It was experimentally determined that rates_basic
1673 ** can take 11g rates as well, not only rates
1674 ** defined with JOINBSS_RATES_BASIC111_nnn.
1675 ** Just use RATE111_nnn constants... */
1676 tmp.u.acx111.dtim_interval = dtim_interval;
1677 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1678 log(L_ASSOC, "rates_basic:%04X, rates_supported:%04X\n",
1679 adev->rate_basic, adev->rate_oper);
1680 } else {
1681 tmp.u.acx100.dtim_interval = dtim_interval;
1682 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1683 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1684 log(L_ASSOC, "rates_basic:%04X->%02X, "
1685 "rates_supported:%04X->%02X\n",
1686 adev->rate_basic, tmp.u.acx100.rates_basic,
1687 adev->rate_oper, tmp.u.acx100.rates_supported);
1690 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1691 ** will be sent (rate/modulation/preamble) */
1692 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1693 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1694 /* we can use short pre *if* all peers can understand it */
1695 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1697 /* we switch fw to STA mode in MONITOR mode, it seems to be
1698 ** the only mode where fw does not emit beacons by itself
1699 ** but allows us to send anything (we really want to retain
1700 ** ability to tx arbitrary frames in MONITOR mode)
1702 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1703 tmp.channel = adev->channel;
1704 tmp.essid_len = adev->essid_len;
1706 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1707 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1709 log(L_ASSOC|L_DEBUG, "BSS_Type = %u\n", tmp.macmode);
1710 acxlog_mac(L_ASSOC|L_DEBUG, "JoinBSSID MAC:", adev->bssid, "\n");
1712 /* acx_update_capabilities(adev); */
1713 FN_EXIT0;
1716 /***********************************************************************
1717 ** acxpci_i_set_multicast_list
1718 ** FIXME: most likely needs refinement
1721 void acx_i_set_multicast_list(struct ieee80211_hw *hw,
1722 unsigned int changed_flags,
1723 unsigned int *total_flags,
1724 int mc_count, struct dev_addr_list *mc_list)
1726 acx_device_t *adev = ieee2adev(hw);
1727 unsigned long flags;
1729 FN_ENTER;
1731 acx_lock(adev, flags);
1733 changed_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1734 FIF_CONTROL | FIF_OTHER_BSS);
1735 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1736 FIF_CONTROL | FIF_OTHER_BSS);
1737 /* if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1738 return; */
1740 if (*total_flags) {
1741 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1742 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1743 SET_BIT(adev->set_mask, SET_RXCONFIG);
1744 /* let kernel know in case *we* needed to set promiscuous */
1745 } else {
1746 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1747 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1748 SET_BIT(adev->set_mask, SET_RXCONFIG);
1751 /* cannot update card settings directly here, atomic context */
1752 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
1754 acx_unlock(adev, flags);
1756 FN_EXIT0;
1759 /***********************************************************************
1760 ** acx111 feature config
1762 ** Obvious
1764 static int
1765 acx111_s_get_feature_config(acx_device_t * adev,
1766 u32 * feature_options, u32 * data_flow_options)
1768 struct acx111_ie_feature_config feat;
1770 FN_ENTER;
1772 if (!IS_ACX111(adev)) {
1773 return NOT_OK;
1776 memset(&feat, 0, sizeof(feat));
1778 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1779 FN_EXIT1(NOT_OK);
1780 return NOT_OK;
1782 log(L_DEBUG,
1783 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1784 feat.feature_options, feat.data_flow_options);
1786 if (feature_options)
1787 *feature_options = le32_to_cpu(feat.feature_options);
1788 if (data_flow_options)
1789 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1791 FN_EXIT0;
1792 return OK;
1796 static int
1797 acx111_s_set_feature_config(acx_device_t * adev,
1798 u32 feature_options, u32 data_flow_options,
1799 unsigned int mode
1800 /* 0 == remove, 1 == add, 2 == set */ )
1802 struct acx111_ie_feature_config feat;
1804 FN_ENTER;
1806 if (!IS_ACX111(adev)) {
1807 FN_EXIT1(NOT_OK);
1808 return NOT_OK;
1811 if ((mode < 0) || (mode > 2)) {
1812 FN_EXIT1(NOT_OK);
1813 return NOT_OK;
1816 if (mode != 2)
1817 /* need to modify old data */
1818 acx111_s_get_feature_config(adev, &feat.feature_options,
1819 &feat.data_flow_options);
1820 else {
1821 /* need to set a completely new value */
1822 feat.feature_options = 0;
1823 feat.data_flow_options = 0;
1826 if (mode == 0) { /* remove */
1827 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1828 CLEAR_BIT(feat.data_flow_options,
1829 cpu_to_le32(data_flow_options));
1830 } else { /* add or set */
1831 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1832 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1835 log(L_DEBUG,
1836 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1837 "new: feature 0x%08X dataflow 0x%08X\n",
1838 feature_options, data_flow_options, mode,
1839 le32_to_cpu(feat.feature_options),
1840 le32_to_cpu(feat.data_flow_options));
1842 if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1843 FN_EXIT1(NOT_OK);
1844 return NOT_OK;
1847 FN_EXIT0;
1848 return OK;
1851 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1853 return acx111_s_set_feature_config(adev, f, d, 0);
1855 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1857 return acx111_s_set_feature_config(adev, f, d, 1);
1859 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1861 return acx111_s_set_feature_config(adev, f, d, 2);
1865 /***********************************************************************
1866 ** acx100_s_init_memory_pools
1868 static int
1869 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1871 acx100_ie_memblocksize_t MemoryBlockSize;
1872 acx100_ie_memconfigoption_t MemoryConfigOption;
1873 int TotalMemoryBlocks;
1874 int RxBlockNum;
1875 int TotalRxBlockSize;
1876 int TxBlockNum;
1877 int TotalTxBlockSize;
1879 FN_ENTER;
1881 /* Let's see if we can follow this:
1882 first we select our memory block size (which I think is
1883 completely arbitrary) */
1884 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1886 /* Then we alert the card to our decision of block size */
1887 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
1888 goto bad;
1891 /* We figure out how many total blocks we can create, using
1892 the block size we chose, and the beginning and ending
1893 memory pointers, i.e.: end-start/size */
1894 TotalMemoryBlocks =
1895 (le32_to_cpu(mmt->PoolEnd) -
1896 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1898 log(L_DEBUG, "TotalMemoryBlocks=%u (%u bytes)\n",
1899 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1901 /* MemoryConfigOption.DMA_config bitmask:
1902 access to ACX memory is to be done:
1903 0x00080000 using PCI conf space?!
1904 0x00040000 using IO instructions?
1905 0x00000000 using memory access instructions
1906 0x00020000 using local memory block linked list (else what?)
1907 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1909 if (IS_PCI(adev)) {
1910 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1911 /* Declare start of the Rx host pool */
1912 MemoryConfigOption.pRxHostDesc =
1913 cpu2acx(adev->rxhostdesc_startphy);
1914 log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
1915 acx2cpu(MemoryConfigOption.pRxHostDesc),
1916 (long)adev->rxhostdesc_startphy);
1917 } else {
1918 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1921 /* 50% of the allotment of memory blocks go to tx descriptors */
1922 TxBlockNum = TotalMemoryBlocks / 2;
1923 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1925 /* and 50% go to the rx descriptors */
1926 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1927 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1929 /* size of the tx and rx descriptor queues */
1930 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1931 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1932 log(L_DEBUG, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u "
1933 "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum,
1934 TotalTxBlockSize, TotalRxBlockSize);
1937 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1938 MemoryConfigOption.rx_mem =
1939 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1941 /* align the rx descriptor queue to units of 0x20
1942 * and offset it by the tx descriptor queue */
1943 MemoryConfigOption.tx_mem =
1944 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
1945 0x1f) & ~0x1f);
1946 log(L_DEBUG, "rx_mem %08X rx_mem %08X\n", MemoryConfigOption.tx_mem,
1947 MemoryConfigOption.rx_mem);
1949 /* alert the device to our decision */
1950 if (OK !=
1951 acx_s_configure(adev, &MemoryConfigOption,
1952 ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
1953 goto bad;
1956 /* and tell the device to kick it into gear */
1957 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
1958 goto bad;
1960 FN_EXIT1(OK);
1961 return OK;
1962 bad:
1963 FN_EXIT1(NOT_OK);
1964 return NOT_OK;
1968 /***********************************************************************
1969 ** acx100_s_create_dma_regions
1971 ** Note that this fn messes up heavily with hardware, but we cannot
1972 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1974 /* OLD CODE? - let's rewrite it! */
1975 static int acx100_s_create_dma_regions(acx_device_t * adev)
1977 acx100_ie_queueconfig_t queueconf;
1978 acx_ie_memmap_t memmap;
1979 int res = NOT_OK;
1980 u32 tx_queue_start, rx_queue_start;
1982 FN_ENTER;
1984 /* read out the acx100 physical start address for the queues */
1985 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1986 goto fail;
1989 tx_queue_start = le32_to_cpu(memmap.QueueStart);
1990 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
1992 log(L_DEBUG, "initializing Queue Indicator\n");
1994 memset(&queueconf, 0, sizeof(queueconf));
1996 /* Not needed for PCI, so we can avoid setting them altogether */
1997 if (IS_USB(adev)) {
1998 queueconf.NumTxDesc = USB_TX_CNT;
1999 queueconf.NumRxDesc = USB_RX_CNT;
2002 /* calculate size of queues */
2003 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
2004 RX_CNT * sizeof(rxdesc_t) + 8);
2005 queueconf.NumTxQueues = 1; /* number of tx queues */
2006 /* sets the beginning of the tx descriptor queue */
2007 queueconf.TxQueueStart = memmap.QueueStart;
2008 /* done by memset: queueconf.TxQueuePri = 0; */
2009 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
2010 queueconf.QueueOptions = 1; /* auto reset descriptor */
2011 /* sets the end of the rx descriptor queue */
2012 queueconf.QueueEnd =
2013 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
2015 /* sets the beginning of the next queue */
2016 queueconf.HostQueueEnd =
2017 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
2018 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
2019 goto fail;
2022 if (IS_PCI(adev)) {
2023 /* sets the beginning of the rx descriptor queue, after the tx descrs */
2024 if (OK != acxpci_s_create_hostdesc_queues(adev))
2025 goto fail;
2026 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2029 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2030 goto fail;
2033 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
2034 0x1f) & ~0x1f);
2036 if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2037 goto fail;
2040 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
2041 goto fail;
2044 res = OK;
2045 goto end;
2047 fail:
2048 acx_s_mwait(1000); /* ? */
2049 if (IS_PCI(adev))
2050 acxpci_free_desc_queues(adev);
2051 end:
2052 FN_EXIT1(res);
2053 return res;
2057 /***********************************************************************
2058 ** acx111_s_create_dma_regions
2060 ** Note that this fn messes heavily with hardware, but we cannot
2061 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2063 #define ACX111_PERCENT(percent) ((percent)/5)
2065 static int acx111_s_create_dma_regions(acx_device_t * adev)
2067 struct acx111_ie_memoryconfig memconf;
2068 struct acx111_ie_queueconfig queueconf;
2069 u32 tx_queue_start, rx_queue_start;
2071 FN_ENTER;
2073 /* Calculate memory positions and queue sizes */
2075 /* Set up our host descriptor pool + data pool */
2076 if (IS_PCI(adev)) {
2077 if (OK != acxpci_s_create_hostdesc_queues(adev))
2078 goto fail;
2081 memset(&memconf, 0, sizeof(memconf));
2082 /* the number of STAs (STA contexts) to support
2083 ** NB: was set to 1 and everything seemed to work nevertheless... */
2084 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
2085 /* specify the memory block size. Default is 256 */
2086 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
2087 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
2088 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
2089 /* set the count of our queues
2090 ** NB: struct acx111_ie_memoryconfig shall be modified
2091 ** if we ever will switch to more than one rx and/or tx queue */
2092 memconf.count_rx_queues = 1;
2093 memconf.count_tx_queues = 1;
2094 /* 0 == Busmaster Indirect Memory Organization, which is what we want
2095 * (using linked host descs with their allocated mem).
2096 * 2 == Generic Bus Slave */
2097 /* done by memset: memconf.options = 0; */
2098 /* let's use 25% for fragmentations and 75% for frame transfers
2099 * (specified in units of 5%) */
2100 memconf.fragmentation = ACX111_PERCENT(75);
2101 /* Rx descriptor queue config */
2102 memconf.rx_queue1_count_descs = RX_CNT;
2103 memconf.rx_queue1_type = 7; /* must be set to 7 */
2104 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2105 if (IS_PCI(adev)) {
2106 memconf.rx_queue1_host_rx_start =
2107 cpu2acx(adev->rxhostdesc_startphy);
2109 /* Tx descriptor queue config */
2110 memconf.tx_queue1_count_descs = TX_CNT;
2111 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2113 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
2114 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2115 ** But it is actually correct wrt IE numbers.
2116 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
2117 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2118 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2119 if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
2120 goto fail;
2123 acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
2125 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2126 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2128 log(L_INIT, "dump queue head (from card):\n"
2129 "len: %u\n"
2130 "tx_memory_block_address: %X\n"
2131 "rx_memory_block_address: %X\n"
2132 "tx1_queue address: %X\n"
2133 "rx1_queue address: %X\n",
2134 le16_to_cpu(queueconf.len),
2135 le32_to_cpu(queueconf.tx_memory_block_address),
2136 le32_to_cpu(queueconf.rx_memory_block_address),
2137 tx_queue_start, rx_queue_start);
2139 if (IS_PCI(adev))
2140 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2142 FN_EXIT1(OK);
2143 return OK;
2144 fail:
2145 if (IS_PCI(adev))
2146 acxpci_free_desc_queues(adev);
2148 FN_EXIT1(NOT_OK);
2149 return NOT_OK;
2153 /***********************************************************************
2155 static void acx_s_initialize_rx_config(acx_device_t * adev)
2157 struct {
2158 u16 id;
2159 u16 len;
2160 u16 rx_cfg1;
2161 u16 rx_cfg2;
2162 } ACX_PACKED cfg;
2163 switch (adev->mode) {
2164 case ACX_MODE_MONITOR:
2165 adev->rx_config_1 = (u16) (0
2166 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2167 /* | RX_CFG1_FILTER_SSID */
2168 /* | RX_CFG1_FILTER_BCAST */
2169 /* | RX_CFG1_RCV_MC_ADDR1 */
2170 /* | RX_CFG1_RCV_MC_ADDR0 */
2171 /* | RX_CFG1_FILTER_ALL_MULTI */
2172 /* | RX_CFG1_FILTER_BSSID */
2173 /* | RX_CFG1_FILTER_MAC */
2174 | RX_CFG1_RCV_PROMISCUOUS
2175 | RX_CFG1_INCLUDE_FCS
2176 /* | RX_CFG1_INCLUDE_PHY_HDR */
2178 adev->rx_config_2 = (u16) (0
2179 | RX_CFG2_RCV_ASSOC_REQ
2180 | RX_CFG2_RCV_AUTH_FRAMES
2181 | RX_CFG2_RCV_BEACON_FRAMES
2182 | RX_CFG2_RCV_CONTENTION_FREE
2183 | RX_CFG2_RCV_CTRL_FRAMES
2184 | RX_CFG2_RCV_DATA_FRAMES
2185 | RX_CFG2_RCV_BROKEN_FRAMES
2186 | RX_CFG2_RCV_MGMT_FRAMES
2187 | RX_CFG2_RCV_PROBE_REQ
2188 | RX_CFG2_RCV_PROBE_RESP
2189 | RX_CFG2_RCV_ACK_FRAMES
2190 | RX_CFG2_RCV_OTHER);
2191 break;
2192 default:
2193 adev->rx_config_1 = (u16) (0
2194 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2195 /* | RX_CFG1_FILTER_SSID */
2196 /* | RX_CFG1_FILTER_BCAST */
2197 /* | RX_CFG1_RCV_MC_ADDR1 */
2198 /* | RX_CFG1_RCV_MC_ADDR0 */
2199 /* | RX_CFG1_FILTER_ALL_MULTI */
2200 /* | RX_CFG1_FILTER_BSSID */
2201 /* | RX_CFG1_FILTER_MAC */
2202 | RX_CFG1_RCV_PROMISCUOUS
2203 /* | RX_CFG1_INCLUDE_FCS */
2204 /* | RX_CFG1_INCLUDE_PHY_HDR */
2206 adev->rx_config_2 = (u16) (0
2207 | RX_CFG2_RCV_ASSOC_REQ
2208 | RX_CFG2_RCV_AUTH_FRAMES
2209 | RX_CFG2_RCV_BEACON_FRAMES
2210 | RX_CFG2_RCV_CONTENTION_FREE
2211 | RX_CFG2_RCV_CTRL_FRAMES
2212 | RX_CFG2_RCV_DATA_FRAMES
2213 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2214 | RX_CFG2_RCV_MGMT_FRAMES
2215 | RX_CFG2_RCV_PROBE_REQ
2216 | RX_CFG2_RCV_PROBE_RESP
2217 | RX_CFG2_RCV_ACK_FRAMES
2218 | RX_CFG2_RCV_OTHER);
2219 break;
2221 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2223 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2224 || (adev->firmware_numver >= 0x02000000))
2225 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2226 else
2227 adev->phy_header_len = 0;
2229 log(L_INIT, "setting RXconfig to %04X:%04X\n",
2230 adev->rx_config_1, adev->rx_config_2);
2231 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2232 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2233 acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
2237 /***********************************************************************
2238 ** FIXME: this should be solved in a general way for all radio types
2239 ** by decoding the radio firmware module,
2240 ** since it probably has some standard structure describing how to
2241 ** set the power level of the radio module which it controls.
2242 ** Or maybe not, since the radio module probably has a function interface
2243 ** instead which then manages Tx level programming :-\
2245 ** Obvious
2247 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2249 struct acx111_ie_tx_level tx_level;
2251 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2252 * 1 (30mW) [15dBm]
2253 * 2 (10mW) [10dBm]
2254 * For now, just assume all other acx111 cards have the same.
2255 * FIXME: Ideally we would query it here, but we first need a
2256 * standard way to query individual configoptions easily.
2257 * Well, now we have proper cfgopt txpower variables, but this still
2258 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2259 if (level_dbm <= 12) {
2260 tx_level.level = 2; /* 10 dBm */
2261 adev->tx_level_dbm = 10;
2262 } else {
2263 tx_level.level = 1; /* 15 dBm */
2264 adev->tx_level_dbm = 15;
2266 if (level_dbm != adev->tx_level_dbm)
2267 log(L_INIT, "only predefined transmission "
2268 "power levels are supported at this time: "
2269 "adjusted %d dBm to %d dBm\n", level_dbm,
2270 adev->tx_level_dbm);
2272 return acx_s_configure(adev, &tx_level, ACX1xx_REG_DOT11_TX_POWER_LEVEL);
2275 static int acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
2277 if (IS_ACX111(adev)) {
2278 return acx111_s_set_tx_level(adev, level_dbm);
2280 if (IS_PCI(adev)) {
2281 return acx100pci_s_set_tx_level(adev, level_dbm);
2284 return OK;
2288 /***********************************************************************
2289 ** acx_s_set_defaults
2291 void acx_s_set_defaults(acx_device_t * adev)
2293 struct ieee80211_conf *conf = &adev->ieee->conf;
2294 unsigned long flags;
2296 FN_ENTER;
2298 acx_lock(adev, flags);
2299 /* do it before getting settings, prevent bogus channel 0 warning */
2300 adev->channel = 1;
2302 /* query some settings from the card.
2303 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2304 * query is REQUIRED, otherwise the card won't work correctly! */
2305 adev->get_mask =
2306 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2307 GETSET_REG_DOMAIN;
2308 /* Only ACX100 supports ED and CCA */
2309 if (IS_ACX100(adev))
2310 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2312 acx_unlock(adev, flags);
2314 acx_s_update_card_settings(adev);
2316 acx_lock(adev, flags);
2318 /* set our global interrupt mask */
2319 if (IS_PCI(adev))
2320 acxpci_set_interrupt_mask(adev);
2322 adev->led_power = 1; /* LED is active on startup */
2323 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2324 adev->brange_time_last_state_change = jiffies;
2326 /* copy the MAC address we just got from the card
2327 * into our MAC address used during current 802.11 session */
2328 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
2329 MAC_BCAST(adev->ap);
2331 adev->essid_len =
2332 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2333 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2334 adev->essid_active = 1;
2336 /* we have a nick field to waste, so why not abuse it
2337 * to announce the driver version? ;-) */
2338 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2340 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2341 /* first regulatory domain entry in EEPROM == default reg. domain */
2342 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2345 /* 0xffff would be better, but then we won't get a "scan complete"
2346 * interrupt, so our current infrastructure will fail: */
2347 adev->scan_count = 1;
2348 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2349 adev->scan_duration = 100;
2350 adev->scan_probe_delay = 200;
2351 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2352 adev->scan_rate = ACX_SCAN_RATE_1;
2355 adev->mode = ACX_MODE_2_STA;
2356 adev->listen_interval = 100;
2357 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2358 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2360 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2362 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2363 adev->frag_threshold = 2346;
2365 /* use standard default values for retry limits */
2366 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2367 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2369 adev->preamble_mode = 2; /* auto */
2370 adev->fallback_threshold = 3;
2371 adev->stepup_threshold = 10;
2372 adev->rate_bcast = RATE111_1;
2373 adev->rate_bcast100 = RATE100_1;
2374 adev->rate_basic = RATE111_1 | RATE111_2;
2375 adev->rate_auto = 1;
2376 if (IS_ACX111(adev)) {
2377 adev->rate_oper = RATE111_ALL;
2378 } else {
2379 adev->rate_oper = RATE111_ACX100_COMPAT;
2382 /* Supported Rates element - the rates here are given in units of
2383 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2384 acx_l_update_ratevector(adev);
2386 /* set some more defaults */
2387 if (IS_ACX111(adev)) {
2388 /* 30mW (15dBm) is default, at least in my acx111 card: */
2389 adev->tx_level_dbm = 15;
2390 conf->power_level = adev->tx_level_dbm;
2391 acx_unlock(adev, flags);
2392 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2393 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2394 acx_lock(adev, flags);
2395 } else {
2396 /* don't use max. level, since it might be dangerous
2397 * (e.g. WRT54G people experience
2398 * excessive Tx power damage!) */
2399 adev->tx_level_dbm = 18;
2400 conf->power_level = adev->tx_level_dbm;
2401 acx_unlock(adev, flags);
2402 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2403 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2404 acx_lock(adev, flags);
2407 /* adev->tx_level_auto = 1; */
2408 if (IS_ACX111(adev)) {
2409 /* start with sensitivity level 1 out of 3: */
2410 adev->sensitivity = 1;
2413 /* #define ENABLE_POWER_SAVE */
2414 #ifdef ENABLE_POWER_SAVE
2415 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2416 adev->ps_listen_interval = 1;
2417 adev->ps_options =
2418 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2419 adev->ps_hangover_period = 30;
2420 adev->ps_enhanced_transition_time = 0;
2421 #else
2422 adev->ps_wakeup_cfg = 0;
2423 adev->ps_listen_interval = 0;
2424 adev->ps_options = 0;
2425 adev->ps_hangover_period = 0;
2426 adev->ps_enhanced_transition_time = 0;
2427 #endif
2429 /* These settings will be set in fw on ifup */
2430 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2431 /* configure card to do rate fallback when in auto rate mode */
2432 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2433 /* better re-init the antenna value we got above */
2434 | GETSET_ANTENNA
2435 #if POWER_SAVE_80211
2436 | GETSET_POWER_80211
2437 #endif
2440 acx_unlock(adev, flags);
2441 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2443 acx_s_initialize_rx_config(adev);
2445 FN_EXIT0;
2449 /***********************************************************************
2450 ** acx_l_process_rxbuf
2452 ** NB: used by USB code also
2454 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2456 struct ieee80211_hdr *hdr;
2457 u16 fc, buf_len;
2459 FN_ENTER;
2461 hdr = acx_get_wlan_hdr(adev, rxbuf);
2462 fc = le16_to_cpu(hdr->frame_control);
2463 /* length of frame from control field to first byte of FCS */
2464 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2466 if (unlikely(acx_debug & L_DATA)) {
2467 printk("rx: 802.11 buf[%u]: \n", buf_len);
2468 acx_dump_bytes(hdr, buf_len);
2472 acx_l_rx(adev, rxbuf);
2473 /* Now check Rx quality level, AFTER processing packet.
2474 * I tried to figure out how to map these levels to dBm
2475 * values, but for the life of me I really didn't
2476 * manage to get it. Either these values are not meant to
2477 * be expressed in dBm, or it's some pretty complicated
2478 * calculation. */
2480 /* TODO: only the RSSI seems to be reported */
2481 adev->rx_status.ssi = acx_signal_to_winlevel(rxbuf->phy_level);
2483 FN_EXIT0;
2487 /***********************************************************************
2488 ** acx_l_handle_txrate_auto
2490 ** Theory of operation:
2491 ** client->rate_cap is a bitmask of rates client is capable of.
2492 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2493 ** It is set as a result of iwconfig rate N [auto]
2494 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2495 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2496 ** auto (0x00ff == 18Mbit or any lower value),
2497 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2499 ** client->rate_cur is a value for rate111 field in tx descriptor.
2500 ** It is always set to txrate_cfg sans zero or more most significant
2501 ** bits. This routine handles selection of new rate_cur value depending on
2502 ** outcome of last tx event.
2504 ** client->rate_100 is a precalculated rate value for acx100
2505 ** (we can do without it, but will need to calculate it on each tx).
2507 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2508 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2509 ** In theory you can implement it, but so far it is considered not worth doing.
2511 ** 22Mbit, of course, is PBCC always. */
2513 /* maps acx100 tx descr rate field to acx111 one */
2515 static u16 rate100to111(u8 r)
2517 switch (r) {
2518 case RATE100_1:
2519 return RATE111_1;
2520 case RATE100_2:
2521 return RATE111_2;
2522 case RATE100_5:
2523 case (RATE100_5 | RATE100_PBCC511):
2524 return RATE111_5;
2525 case RATE100_11:
2526 case (RATE100_11 | RATE100_PBCC511):
2527 return RATE111_11;
2528 case RATE100_22:
2529 return RATE111_22;
2530 default:
2531 printk("acx: unexpected acx100 txrate: %u! "
2532 "Please report\n", r);
2533 return RATE111_1;
2540 acx_i_start_xmit(struct ieee80211_hw *hw,
2541 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2543 acx_device_t *adev = ieee2adev(hw);
2544 tx_t *tx;
2545 void *txbuf;
2546 unsigned long flags;
2548 int txresult = NOT_OK;
2550 FN_ENTER;
2552 if (unlikely(!skb)) {
2553 /* indicate success */
2554 txresult = OK;
2555 goto out;
2558 if (unlikely(!adev)) {
2559 goto out;
2562 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2563 goto out;
2565 if (unlikely(!adev->initialized)) {
2566 goto out;
2569 acx_lock(adev, flags);
2571 tx = acx_l_alloc_tx(adev);
2573 if (unlikely(!tx)) {
2574 printk_ratelimited("%s: start_xmit: txdesc ring is full, "
2575 "dropping tx\n", wiphy_name(adev->ieee->wiphy));
2576 txresult = NOT_OK;
2577 goto out_unlock;
2580 txbuf = acx_l_get_txbuf(adev, tx);
2582 if (unlikely(!txbuf)) {
2583 /* Card was removed */
2584 txresult = NOT_OK;
2585 acx_l_dealloc_tx(adev, tx);
2586 goto out_unlock;
2588 memcpy(txbuf, skb->data, skb->len);
2590 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2592 txresult = OK;
2593 adev->stats.tx_packets++;
2594 adev->stats.tx_bytes += skb->len;
2596 out_unlock:
2597 acx_unlock(adev, flags);
2599 out:
2600 FN_EXIT1(txresult);
2601 return txresult;
2603 /***********************************************************************
2604 ** acx_l_update_ratevector
2606 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2608 const u8 acx_bitpos2ratebyte[] = {
2609 DOT11RATEBYTE_1,
2610 DOT11RATEBYTE_2,
2611 DOT11RATEBYTE_5_5,
2612 DOT11RATEBYTE_6_G,
2613 DOT11RATEBYTE_9_G,
2614 DOT11RATEBYTE_11,
2615 DOT11RATEBYTE_12_G,
2616 DOT11RATEBYTE_18_G,
2617 DOT11RATEBYTE_22,
2618 DOT11RATEBYTE_24_G,
2619 DOT11RATEBYTE_36_G,
2620 DOT11RATEBYTE_48_G,
2621 DOT11RATEBYTE_54_G,
2624 void acx_l_update_ratevector(acx_device_t * adev)
2626 u16 bcfg = adev->rate_basic;
2627 u16 ocfg = adev->rate_oper;
2628 u8 *supp = adev->rate_supported;
2629 const u8 *dot11 = acx_bitpos2ratebyte;
2631 FN_ENTER;
2633 while (ocfg) {
2634 if (ocfg & 1) {
2635 *supp = *dot11;
2636 if (bcfg & 1) {
2637 *supp |= 0x80;
2639 supp++;
2641 dot11++;
2642 ocfg >>= 1;
2643 bcfg >>= 1;
2645 adev->rate_supported_len = supp - adev->rate_supported;
2646 if (acx_debug & L_ASSOC) {
2647 printk("new ratevector: ");
2648 acx_dump_bytes(adev->rate_supported, adev->rate_supported_len);
2650 FN_EXIT0;
2653 /***********************************************************************
2654 ** acx_i_timer
2656 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2658 ** Obvious
2660 void acx_i_timer(unsigned long address)
2662 unsigned long flags;
2663 acx_device_t *adev = (acx_device_t *) address;
2665 FN_ENTER;
2667 acx_lock(adev, flags);
2669 FIXME();
2670 /* We need calibration and stats gather tasks to perform here */
2672 acx_unlock(adev, flags);
2674 FN_EXIT0;
2678 /***********************************************************************
2679 ** acx_set_timer
2681 ** Sets the 802.11 state management timer's timeout.
2683 ** Linux derived
2685 void acx_set_timer(acx_device_t * adev, int timeout_us)
2687 FN_ENTER;
2689 log(L_DEBUG | L_IRQ, "%s(%u ms)\n", __func__, timeout_us / 1000);
2690 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2691 printk("attempt to set the timer "
2692 "when the card interface is not up!\n");
2693 goto end;
2696 /* first check if the timer was already initialized, THEN modify it */
2697 if (adev->mgmt_timer.function) {
2698 mod_timer(&adev->mgmt_timer,
2699 jiffies + (timeout_us * HZ / 1000000));
2701 end:
2702 FN_EXIT0;
2705 /** acx_plcp_get_bitrate_cck
2707 ** Obvious
2709 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2711 switch (plcp) {
2712 case 0x0A:
2713 return ACX_CCK_RATE_1MB;
2714 case 0x14:
2715 return ACX_CCK_RATE_2MB;
2716 case 0x37:
2717 return ACX_CCK_RATE_5MB;
2718 case 0x6E:
2719 return ACX_CCK_RATE_11MB;
2721 return 0;
2724 /* Extract the bitrate out of an OFDM PLCP header. */
2725 /** Obvious **/
2726 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2728 switch (plcp & 0xF) {
2729 case 0xB:
2730 return ACX_OFDM_RATE_6MB;
2731 case 0xF:
2732 return ACX_OFDM_RATE_9MB;
2733 case 0xA:
2734 return ACX_OFDM_RATE_12MB;
2735 case 0xE:
2736 return ACX_OFDM_RATE_18MB;
2737 case 0x9:
2738 return ACX_OFDM_RATE_24MB;
2739 case 0xD:
2740 return ACX_OFDM_RATE_36MB;
2741 case 0x8:
2742 return ACX_OFDM_RATE_48MB;
2743 case 0xC:
2744 return ACX_OFDM_RATE_54MB;
2746 return 0;
2750 /***********************************************************************
2751 ** acx_l_rx
2753 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2754 ** buffer and feeds it to the network stack via netif_rx().
2756 ** Look to bcm43xx or p54
2758 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2761 struct ieee80211_rx_status* status = &adev->rx_status;
2762 struct ieee80211_hdr *w_hdr;
2763 struct sk_buff *skb;
2764 int buflen;
2765 FN_ENTER;
2767 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2768 printk("asked to receive a packet but interface is down??\n");
2769 goto out;
2772 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2773 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2775 * Allocate our skb
2777 skb = dev_alloc_skb(buflen + 2);
2779 if (!skb) {
2780 printk("skb allocation FAILED\n");
2781 goto out;
2784 skb_reserve(skb, 2);
2785 skb_put(skb, buflen);
2786 memcpy(skb->data, w_hdr, buflen);
2788 // memset(&status, 0, sizeof(status));
2790 status->mactime = rxbuf->time;
2791 status->ssi = acx_signal_to_winlevel(rxbuf->phy_level);
2792 /* TODO: they do not seem to be reported, at least on the acx111
2793 * (and TNETW1450?), therefore commenting them out
2794 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2795 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr); */
2796 status->flag = 0;
2797 status->rate = rxbuf->phy_plcp_signal;
2798 status->antenna = 1;
2799 if (rxbuf->phy_stat_baseband & (1 << 3)) { /* Uses OFDM */
2800 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2801 } else {
2802 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2806 * FIXME: should it really be done here??
2808 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2809 adev->stats.rx_packets++;
2810 adev->stats.rx_bytes += skb->len;
2811 out:
2812 FN_EXIT0;
2817 /***********************************************************************
2818 ** acx_s_read_fw
2820 ** Loads a firmware image
2822 ** Returns:
2823 ** 0 unable to load file
2824 ** pointer to firmware success
2826 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2827 u32 * size)
2829 firmware_image_t *res;
2830 const struct firmware *fw_entry;
2832 res = NULL;
2833 log(L_INIT, "requesting firmware image '%s'\n", file);
2834 if (!request_firmware(&fw_entry, file, dev)) {
2835 *size = 8;
2836 if (fw_entry->size >= 8)
2837 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2838 if (fw_entry->size != *size) {
2839 printk("acx: firmware size does not match "
2840 "firmware header: %d != %d, "
2841 "aborting fw upload\n",
2842 (int)fw_entry->size, (int)*size);
2843 goto release_ret;
2845 res = vmalloc(*size);
2846 if (!res) {
2847 printk("acx: no memory for firmware "
2848 "(%u bytes)\n", *size);
2849 goto release_ret;
2851 memcpy(res, fw_entry->data, fw_entry->size);
2852 release_ret:
2853 release_firmware(fw_entry);
2854 return res;
2856 printk("acx: firmware image '%s' was not provided. "
2857 "Check your hotplug scripts\n", file);
2859 /* checksum will be verified in write_fw, so don't bother here */
2860 return res;
2864 /***********************************************************************
2865 ** acx_s_set_wepkey
2867 static void acx100_s_set_wepkey(acx_device_t * adev)
2869 ie_dot11WEPDefaultKey_t dk;
2870 int i;
2872 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2873 if (adev->wep_keys[i].size != 0) {
2874 log(L_INIT, "setting WEP key: %d with "
2875 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2876 dk.action = 1;
2877 dk.keySize = adev->wep_keys[i].size;
2878 dk.defaultKeyNum = i;
2879 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2880 acx_s_configure(adev, &dk,
2881 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
2886 static void acx111_s_set_wepkey(acx_device_t * adev)
2888 acx111WEPDefaultKey_t dk;
2889 int i;
2891 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2892 if (adev->wep_keys[i].size != 0) {
2893 log(L_INIT, "setting WEP key: %d with "
2894 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2895 memset(&dk, 0, sizeof(dk));
2896 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2897 dk.keySize = adev->wep_keys[i].size;
2899 /* are these two lines necessary? */
2900 dk.type = 0; /* default WEP key */
2901 dk.index = 0; /* ignored when setting default key */
2903 dk.defaultKeyNum = i;
2904 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2905 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2906 sizeof(dk));
2910 /* Obvious */
2911 static void acx_s_set_wepkey(acx_device_t * adev)
2913 if (IS_ACX111(adev))
2914 acx111_s_set_wepkey(adev);
2915 else
2916 acx100_s_set_wepkey(adev);
2920 /***********************************************************************
2921 ** acx100_s_init_wep
2923 ** FIXME: this should probably be moved into the new card settings
2924 ** management, but since we're also modifying the memory map layout here
2925 ** due to the WEP key space we want, we should take care...
2927 static int acx100_s_init_wep(acx_device_t * adev)
2929 acx100_ie_wep_options_t options;
2930 ie_dot11WEPDefaultKeyID_t dk;
2931 acx_ie_memmap_t pt;
2932 int res = NOT_OK;
2934 FN_ENTER;
2936 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2937 goto fail;
2940 log(L_DEBUG, "CodeEnd:%X\n", pt.CodeEnd);
2942 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2943 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2945 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2946 goto fail;
2949 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2950 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2951 options.WEPOption = 0x00;
2953 log(L_ASSOC, "writing WEP options\n");
2954 acx_s_configure(adev, &options, ACX100_REG_WEP_OPTIONS);
2956 acx100_s_set_wepkey(adev);
2958 if (adev->wep_keys[adev->wep_current_index].size != 0) {
2959 log(L_ASSOC, "setting active default WEP key number: %d\n",
2960 adev->wep_current_index);
2961 dk.KeyID = adev->wep_current_index;
2962 acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
2964 /* FIXME!!! wep_key_struct is filled nowhere! But adev
2965 * is initialized to 0, and we don't REALLY need those keys either */
2966 /* for (i = 0; i < 10; i++) {
2967 if (adev->wep_key_struct[i].len != 0) {
2968 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
2969 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
2970 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
2971 wep_mgmt.Action = cpu_to_le16(1);
2972 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
2973 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
2974 adev->wep_key_struct[i].index = i;
2980 /* now retrieve the updated WEPCacheEnd pointer... */
2981 if (OK != acx_s_query(adev, &pt, ACX1xx_REG_MEMORY_MAP)) {
2982 printk("%s: ACX1xx_REG_MEMORY_MAP read #2 FAILED\n",
2983 wiphy_name(adev->ieee->wiphy));
2984 goto fail;
2986 /* ...and tell it to start allocating templates at that location */
2987 /* (no endianness conversion needed) */
2988 pt.PacketTemplateStart = pt.WEPCacheEnd;
2990 if (OK != acx_s_configure(adev, &pt, ACX1xx_REG_MEMORY_MAP)) {
2991 printk("%s: ACX1xx_REG_MEMORY_MAP write #2 FAILED\n",
2992 wiphy_name(adev->ieee->wiphy));
2993 goto fail;
2995 res = OK;
2997 fail:
2998 FN_EXIT1(res);
2999 return res;
3003 static int
3004 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
3005 unsigned int cmd)
3007 int res;
3008 union {
3009 acx_template_nullframe_t null;
3010 acx_template_beacon_t b;
3011 acx_template_tim_t tim;
3012 acx_template_probereq_t preq;
3013 acx_template_proberesp_t presp;
3014 } templ;
3016 memset(&templ, 0, len);
3017 templ.null.size = cpu_to_le16(len - 2);
3018 res = acx_s_issue_cmd(adev, cmd, &templ, len);
3019 return res;
3022 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
3024 return acx_s_init_max_template_generic(adev,
3025 sizeof(acx_template_nullframe_t),
3026 ACX1xx_CMD_CONFIG_NULL_DATA);
3029 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
3031 return acx_s_init_max_template_generic(adev,
3032 sizeof(acx_template_beacon_t),
3033 ACX1xx_CMD_CONFIG_BEACON);
3036 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
3038 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
3039 ACX1xx_CMD_CONFIG_TIM);
3042 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
3044 return acx_s_init_max_template_generic(adev,
3045 sizeof(acx_template_proberesp_t),
3046 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
3049 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
3051 return acx_s_init_max_template_generic(adev,
3052 sizeof(acx_template_probereq_t),
3053 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
3056 /***********************************************************************
3057 ** acx_s_set_tim_template
3059 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
3060 ** by calling this function
3061 ** (it can be done by irq handler on each DTIM irq or by timer...)
3063 [802.11 7.3.2.6] TIM information element:
3064 - 1 EID
3065 - 1 Length
3066 1 1 DTIM Count
3067 indicates how many beacons (including this) appear before next DTIM
3068 (0=this one is a DTIM)
3069 2 1 DTIM Period
3070 number of beacons between successive DTIMs
3071 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
3072 3 1 Bitmap Control
3073 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
3074 set to 1 in TIM elements with a value of 0 in the DTIM Count field
3075 when one or more broadcast or multicast frames are buffered at the AP.
3076 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
3077 4 n Partial Virtual Bitmap
3078 Visible part of traffic-indication bitmap.
3079 Full bitmap consists of 2008 bits (251 octets) such that bit number N
3080 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
3081 in octet number N/8 where the low-order bit of each octet is bit0,
3082 and the high order bit is bit7.
3083 Each set bit in virtual bitmap corresponds to traffic buffered by AP
3084 for a specific station (with corresponding AID?).
3085 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
3086 Bitmap Offset is a number of skipped zero octets (see above).
3087 'Missing' octets at the tail are also assumed to be zero.
3088 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
3089 This means that traffic-indication bitmap is:
3090 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
3091 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
3093 static int acx_s_set_tim_template(acx_device_t * adev)
3095 /* For now, configure smallish test bitmap, all zero ("no pending data") */
3096 enum { bitmap_size = 5 };
3098 acx_template_tim_t t;
3099 int result;
3101 FN_ENTER;
3103 memset(&t, 0, sizeof(t));
3104 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3105 t.tim_eid = WLAN_EID_TIM;
3106 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3107 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3108 FN_EXIT1(result);
3109 return result;
3115 #if POWER_SAVE_80211
3116 /***********************************************************************
3117 ** acx_s_set_null_data_template
3119 static int acx_s_set_null_data_template(acx_device_t * adev)
3121 struct acx_template_nullframe b;
3122 int result;
3124 FN_ENTER;
3126 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3128 b.size = cpu_to_le16(sizeof(b) - 2);
3129 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3130 b.hdr.dur = 0;
3131 MAC_BCAST(b.hdr.a1);
3132 MAC_COPY(b.hdr.a2, adev->dev_addr);
3133 MAC_COPY(b.hdr.a3, adev->bssid);
3134 b.hdr.seq = 0;
3136 result =
3137 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3139 FN_EXIT1(result);
3140 return result;
3142 #endif
3149 /***********************************************************************
3150 ** acx_s_init_packet_templates()
3152 ** NOTE: order is very important here, to have a correct memory layout!
3153 ** init templates: max Probe Request (station mode), max NULL data,
3154 ** max Beacon, max TIM, max Probe Response.
3156 static int acx_s_init_packet_templates(acx_device_t * adev)
3158 acx_ie_memmap_t mm; /* ACX100 only */
3159 int result = NOT_OK;
3161 FN_ENTER;
3163 log(L_DEBUG | L_INIT, "initializing max packet templates\n");
3165 if (OK != acx_s_init_max_probe_request_template(adev))
3166 goto failed;
3168 if (OK != acx_s_init_max_null_data_template(adev))
3169 goto failed;
3171 if (OK != acx_s_init_max_beacon_template(adev))
3172 goto failed;
3174 if (OK != acx_s_init_max_tim_template(adev))
3175 goto failed;
3177 if (OK != acx_s_init_max_probe_response_template(adev))
3178 goto failed;
3180 if (IS_ACX111(adev)) {
3181 /* ACX111 doesn't need the memory map magic below,
3182 * and the other templates will be set later (acx_start) */
3183 result = OK;
3184 goto success;
3187 /* ACX100 will have its TIM template set,
3188 * and we also need to update the memory map */
3190 if (OK != acx_s_set_tim_template(adev))
3191 goto failed_acx100;
3193 log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3195 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3196 goto failed_acx100;
3198 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3199 if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3200 goto failed_acx100;
3202 result = OK;
3203 goto success;
3205 failed_acx100:
3206 log(L_DEBUG | L_INIT,
3207 /* "cb=0x%X\n" */
3208 "ACXMemoryMap:\n"
3209 ".CodeStart=0x%X\n"
3210 ".CodeEnd=0x%X\n"
3211 ".WEPCacheStart=0x%X\n"
3212 ".WEPCacheEnd=0x%X\n"
3213 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3214 /* len, */
3215 le32_to_cpu(mm.CodeStart),
3216 le32_to_cpu(mm.CodeEnd),
3217 le32_to_cpu(mm.WEPCacheStart),
3218 le32_to_cpu(mm.WEPCacheEnd),
3219 le32_to_cpu(mm.PacketTemplateStart),
3220 le32_to_cpu(mm.PacketTemplateEnd));
3222 failed:
3223 printk("%s: %s() FAILED\n", wiphy_name(adev->ieee->wiphy), __func__);
3225 success:
3226 FN_EXIT1(result);
3227 return result;
3232 /***********************************************************************
3233 ** acx_s_init_mac
3235 int acx_s_init_mac(acx_device_t * adev)
3237 int result = NOT_OK;
3239 FN_ENTER;
3241 if (IS_ACX111(adev)) {
3242 adev->ie_len = acx111_ie_len;
3243 adev->ie_len_dot11 = acx111_ie_len_dot11;
3244 } else {
3245 adev->ie_len = acx100_ie_len;
3246 adev->ie_len_dot11 = acx100_ie_len_dot11;
3249 if (IS_PCI(adev)) {
3250 adev->memblocksize = 256; /* 256 is default */
3251 /* try to load radio for both ACX100 and ACX111, since both
3252 * chips have at least some firmware versions making use of an
3253 * external radio module */
3254 acxpci_s_upload_radio(adev);
3255 } else {
3256 adev->memblocksize = 128;
3259 if (IS_ACX111(adev)) {
3260 /* for ACX111, the order is different from ACX100
3261 1. init packet templates
3262 2. create station context and create dma regions
3263 3. init wep default keys
3265 if (OK != acx_s_init_packet_templates(adev))
3266 goto fail;
3267 if (OK != acx111_s_create_dma_regions(adev)) {
3268 printk("%s: acx111_create_dma_regions FAILED\n",
3269 wiphy_name(adev->ieee->wiphy));
3270 goto fail;
3272 } else {
3273 if (OK != acx100_s_init_wep(adev))
3274 goto fail;
3275 if (OK != acx_s_init_packet_templates(adev))
3276 goto fail;
3277 if (OK != acx100_s_create_dma_regions(adev)) {
3278 printk("%s: acx100_create_dma_regions FAILED\n",
3279 wiphy_name(adev->ieee->wiphy));
3280 goto fail;
3284 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3285 result = OK;
3287 fail:
3288 if (result)
3289 printk("acx: init_mac() FAILED\n");
3290 FN_EXIT1(result);
3291 return result;
3296 #if POWER_SAVE_80211
3297 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3299 /* merge both structs in a union to be able to have common code */
3300 union {
3301 acx111_ie_powersave_t acx111;
3302 acx100_ie_powersave_t acx100;
3303 } pm;
3305 /* change 802.11 power save mode settings */
3306 log(L_INIT, "updating 802.11 power save mode settings: "
3307 "wakeup_cfg 0x%02X, listen interval %u, "
3308 "options 0x%02X, hangover period %u, "
3309 "enhanced_ps_transition_time %u\n",
3310 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3311 adev->ps_options, adev->ps_hangover_period,
3312 adev->ps_enhanced_transition_time);
3313 acx_s_query(adev, &pm, ACX1xx_REG_POWER_MGMT);
3314 log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, "
3315 "listen interval %u, options 0x%02X, "
3316 "hangover period %u, "
3317 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3318 pm.acx111.wakeup_cfg,
3319 pm.acx111.listen_interval,
3320 pm.acx111.options,
3321 pm.acx111.hangover_period,
3322 IS_ACX111(adev) ?
3323 pm.acx111.enhanced_ps_transition_time
3324 : pm.acx100.enhanced_ps_transition_time,
3325 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3326 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3327 pm.acx111.listen_interval = adev->ps_listen_interval;
3328 pm.acx111.options = adev->ps_options;
3329 pm.acx111.hangover_period = adev->ps_hangover_period;
3330 if (IS_ACX111(adev)) {
3331 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3332 pm.acx111.enhanced_ps_transition_time =
3333 cpu_to_le32(adev->ps_enhanced_transition_time);
3334 } else {
3335 pm.acx100.enhanced_ps_transition_time =
3336 cpu_to_le16(adev->ps_enhanced_transition_time);
3338 acx_s_configure(adev, &pm, ACX1xx_REG_POWER_MGMT);
3339 acx_s_query(adev, &pm, ACX1xx_REG_POWER_MGMT);
3340 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3341 acx_s_mwait(40);
3342 acx_s_query(adev, &pm, ACX1xx_REG_POWER_MGMT);
3343 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3344 log(L_INIT, "power save mode change %s\n",
3345 (pm.acx111.
3346 wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful");
3347 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3348 * that power save mode change was successful. */
3349 /* FIXME: we shouldn't trigger a scan immediately after
3350 * fiddling with power save mode (since the firmware is sending
3351 * a NULL frame then). */
3353 #endif
3356 /***********************************************************************
3357 ** acx_s_update_card_settings
3359 ** Applies accumulated changes in various adev->xxxx members
3360 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3361 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3363 void acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
3365 unsigned mask;
3367 unsigned int i;
3369 for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
3370 if (acx_reg_domain_ids[i] == adev->reg_dom_id)
3371 break;
3373 if (sizeof(acx_reg_domain_ids) == i) {
3374 log(L_INIT, "Invalid or unsupported regulatory domain"
3375 " 0x%02X specified, falling back to FCC (USA)!"
3376 " Please report if this sounds fishy!\n",
3377 adev->reg_dom_id);
3378 i = 0;
3379 adev->reg_dom_id = acx_reg_domain_ids[i];
3381 /* since there was a mismatch, we need to force updating */
3382 do_set = 1;
3385 if (do_set) {
3386 acx_ie_generic_t dom;
3387 dom.m.bytes[0] = adev->reg_dom_id;
3388 acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3391 adev->reg_dom_chanmask = reg_domain_channel_masks[i];
3393 mask = (1 << (adev->channel - 1));
3394 if (!(adev->reg_dom_chanmask & mask)) {
3395 /* hmm, need to adjust our channel to reside within domain */
3396 mask = 1;
3397 for (i = 1; i <= 14; i++) {
3398 if (adev->reg_dom_chanmask & mask) {
3399 printk("%s: adjusting selected channel from %d "
3400 "to %d due to new regulatory domain\n",
3401 wiphy_name(adev->ieee->wiphy), adev->channel, i);
3402 adev->channel = i;
3403 break;
3405 mask <<= 1;
3410 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3412 u32 feature1, feature2;
3414 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3415 printk("%s: invalid sensitivity setting (1..3), "
3416 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3417 adev->sensitivity = 1;
3419 acx111_s_get_feature_config(adev, &feature1, &feature2);
3420 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3421 if (adev->sensitivity > 1)
3422 SET_BIT(feature1, FEATURE1_LOW_RX);
3423 if (adev->sensitivity > 2)
3424 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3425 acx111_s_feature_set(adev, feature1, feature2);
3429 void acx_s_update_card_settings(acx_device_t *adev)
3431 unsigned long flags;
3432 unsigned int start_scan = 0;
3433 int i;
3435 FN_ENTER;
3437 log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3438 adev->get_mask, adev->set_mask);
3440 /* Track dependencies betweed various settings */
3442 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3443 log(L_INIT, "important setting has been changed. "
3444 "Need to update packet templates, too\n");
3445 SET_BIT(adev->set_mask, SET_TEMPLATES);
3447 if (adev->set_mask & GETSET_CHANNEL) {
3448 /* This will actually tune RX/TX to the channel */
3449 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3450 switch (adev->mode) {
3451 case ACX_MODE_0_ADHOC:
3452 case ACX_MODE_3_AP:
3453 /* Beacons contain channel# - update them */
3454 SET_BIT(adev->set_mask, SET_TEMPLATES);
3457 switch (adev->mode) {
3458 case ACX_MODE_0_ADHOC:
3459 case ACX_MODE_2_STA:
3460 start_scan = 1;
3464 /* Apply settings */
3467 if (adev->get_mask & GETSET_STATION_ID) {
3468 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3469 const u8 *paddr;
3471 acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3472 paddr = &stationID[4];
3473 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3474 for (i = 0; i < ETH_ALEN; i++) {
3475 /* we copy the MAC address (reversed in
3476 * the card) to the netdevice's MAC
3477 * address, and on ifup it will be
3478 * copied into iwadev->dev_addr */
3479 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3481 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3482 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3485 if (adev->get_mask & GETSET_SENSITIVITY) {
3486 if ((RADIO_RFMD_11 == adev->radio_type)
3487 || (RADIO_MAXIM_0D == adev->radio_type)
3488 || (RADIO_RALINK_15 == adev->radio_type)) {
3489 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3490 } else {
3491 log(L_INIT, "don't know how to get sensitivity "
3492 "for radio type 0x%02X\n", adev->radio_type);
3493 adev->sensitivity = 0;
3495 log(L_INIT, "got sensitivity value %u\n", adev->sensitivity);
3497 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3500 if (adev->get_mask & GETSET_ANTENNA) {
3501 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3503 memset(antenna, 0, sizeof(antenna));
3504 acx_s_interrogate(adev, antenna,
3505 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3506 adev->antenna = antenna[4];
3507 log(L_INIT, "got antenna value 0x%02X\n", adev->antenna);
3508 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3511 if (adev->get_mask & GETSET_ED_THRESH) {
3512 if (IS_ACX100(adev)) {
3513 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3515 memset(ed_threshold, 0, sizeof(ed_threshold));
3516 acx_s_interrogate(adev, ed_threshold,
3517 ACX100_IE_DOT11_ED_THRESHOLD);
3518 adev->ed_threshold = ed_threshold[4];
3519 } else {
3520 log(L_INIT, "acx111 doesn't support ED\n");
3521 adev->ed_threshold = 0;
3523 log(L_INIT, "got Energy Detect (ED) threshold %u\n",
3524 adev->ed_threshold);
3525 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3528 if (adev->get_mask & GETSET_CCA) {
3529 if (IS_ACX100(adev)) {
3530 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3532 memset(cca, 0, sizeof(adev->cca));
3533 acx_s_interrogate(adev, cca,
3534 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3535 adev->cca = cca[4];
3536 } else {
3537 log(L_INIT, "acx111 doesn't support CCA\n");
3538 adev->cca = 0;
3540 log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n",
3541 adev->cca);
3542 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3545 if (adev->get_mask & GETSET_REG_DOMAIN) {
3546 acx_ie_generic_t dom;
3548 acx_s_interrogate(adev, &dom,
3549 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3550 adev->reg_dom_id = dom.m.bytes[0];
3551 acx_s_set_sane_reg_domain(adev, 0);
3552 log(L_INIT, "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3553 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3556 if (adev->set_mask & GETSET_STATION_ID) {
3557 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3558 u8 *paddr;
3560 paddr = &stationID[4];
3561 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3562 for (i = 0; i < ETH_ALEN; i++) {
3563 /* copy the MAC address we obtained when we noticed
3564 * that the ethernet iface's MAC changed
3565 * to the card (reversed in
3566 * the card!) */
3567 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3569 acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3570 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3573 if (adev->set_mask & SET_STA_LIST) {
3574 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3576 if (adev->set_mask & SET_RATE_FALLBACK) {
3577 u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
3579 /* configure to not do fallbacks when not in auto rate mode */
3580 rate[4] =
3581 (adev->
3582 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3583 log(L_INIT, "updating Tx fallback to %u retries\n", rate[4]);
3584 acx_s_configure(adev, &rate, ACX1xx_REG_RATE_FALLBACK);
3585 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3587 if (adev->set_mask & GETSET_TXPOWER) {
3588 log(L_INIT, "updating transmit power: %u dBm\n",
3589 adev->tx_level_dbm);
3590 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3591 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3594 if (adev->set_mask & GETSET_SENSITIVITY) {
3595 log(L_INIT, "updating sensitivity value: %u\n",
3596 adev->sensitivity);
3597 switch (adev->radio_type) {
3598 case RADIO_RFMD_11:
3599 case RADIO_MAXIM_0D:
3600 case RADIO_RALINK_15:
3601 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3602 break;
3603 case RADIO_RADIA_16:
3604 case RADIO_UNKNOWN_17:
3605 acx111_s_sens_radio_16_17(adev);
3606 break;
3607 default:
3608 log(L_INIT, "don't know how to modify sensitivity "
3609 "for radio type 0x%02X\n", adev->radio_type);
3611 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3614 if (adev->set_mask & GETSET_ANTENNA) {
3615 /* antenna */
3616 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3618 memset(antenna, 0, sizeof(antenna));
3619 antenna[4] = adev->antenna;
3620 log(L_INIT, "updating antenna value: 0x%02X\n", adev->antenna);
3621 acx_s_configure(adev, &antenna,
3622 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3623 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3626 if (adev->set_mask & GETSET_ED_THRESH) {
3627 /* ed_threshold */
3628 log(L_INIT, "updating Energy Detect (ED) threshold: %u\n",
3629 adev->ed_threshold);
3630 if (IS_ACX100(adev)) {
3631 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3633 memset(ed_threshold, 0, sizeof(ed_threshold));
3634 ed_threshold[4] = adev->ed_threshold;
3635 acx_s_configure(adev, &ed_threshold,
3636 ACX100_IE_DOT11_ED_THRESHOLD);
3637 } else
3638 log(L_INIT, "acx111 doesn't support ED!\n");
3639 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3642 if (adev->set_mask & GETSET_CCA) {
3643 /* CCA value */
3644 log(L_INIT, "updating Channel Clear Assessment "
3645 "(CCA) value: 0x%02X\n", adev->cca);
3646 if (IS_ACX100(adev)) {
3647 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3649 memset(cca, 0, sizeof(cca));
3650 cca[4] = adev->cca;
3651 acx_s_configure(adev, &cca,
3652 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3653 } else
3654 log(L_INIT, "acx111 doesn't support CCA!\n");
3655 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3658 if (adev->set_mask & GETSET_LED_POWER) {
3659 /* Enable Tx */
3660 log(L_INIT, "updating power LED status: %u\n", adev->led_power);
3662 acx_lock(adev, flags); /* acxpci_l_power_led expects that the lock is already taken! */
3663 if (IS_PCI(adev))
3664 acxpci_l_power_led(adev, adev->led_power);
3665 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3666 acx_unlock(adev, flags);
3669 if (adev->set_mask & GETSET_POWER_80211) {
3670 #if POWER_SAVE_80211
3671 acx_s_update_80211_powersave_mode(adev);
3672 #endif
3673 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3676 if (adev->set_mask & GETSET_CHANNEL) {
3677 /* channel */
3678 log(L_INIT, "updating channel to: %u\n", adev->channel);
3679 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3682 if (adev->set_mask & GETSET_TX) {
3683 /* set Tx */
3684 log(L_INIT, "updating: %s Tx\n",
3685 adev->tx_disabled ? "disable" : "enable");
3686 if (adev->tx_disabled)
3687 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3688 else {
3689 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3690 &adev->channel, 1);
3691 FIXME();
3692 /* This needs to be keyed on WEP? */
3693 /* acx111_s_feature_on(adev, 0,
3694 FEATURE2_NO_TXCRYPT |
3695 FEATURE2_SNIFFER); */
3696 acx_wake_queue(adev->ieee, NULL);
3698 CLEAR_BIT(adev->set_mask, GETSET_TX);
3701 if (adev->set_mask & GETSET_RX) {
3702 /* Enable Rx */
3703 log(L_INIT, "updating: enable Rx on channel: %u\n",
3704 adev->channel);
3705 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3706 CLEAR_BIT(adev->set_mask, GETSET_RX);
3709 if (adev->set_mask & GETSET_RETRY) {
3710 u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
3711 u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
3713 log(L_INIT,
3714 "updating short retry limit: %u, long retry limit: %u\n",
3715 adev->short_retry, adev->long_retry);
3716 short_retry[0x4] = adev->short_retry;
3717 long_retry[0x4] = adev->long_retry;
3718 acx_s_configure(adev, &short_retry,
3719 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
3720 acx_s_configure(adev, &long_retry,
3721 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
3722 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3725 if (adev->set_mask & SET_MSDU_LIFETIME) {
3726 u8 xmt_msdu_lifetime[4 +
3727 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3729 log(L_INIT, "updating tx MSDU lifetime: %u\n",
3730 adev->msdu_lifetime);
3731 *(u32 *) & xmt_msdu_lifetime[4] =
3732 cpu_to_le32((u32) adev->msdu_lifetime);
3733 acx_s_configure(adev, &xmt_msdu_lifetime,
3734 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
3735 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3738 if (adev->set_mask & GETSET_REG_DOMAIN) {
3739 log(L_INIT, "updating regulatory domain: 0x%02X\n",
3740 adev->reg_dom_id);
3741 acx_s_set_sane_reg_domain(adev, 1);
3742 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3744 if (adev->set_mask & GETSET_MODE ) {
3745 acx111_s_feature_on(adev, 0,
3746 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3747 switch (adev->mode) {
3748 case ACX_MODE_3_AP:
3749 adev->aid = 0;
3750 //acx111_s_feature_off(adev, 0,
3751 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3752 MAC_COPY(adev->bssid, adev->dev_addr);
3753 acx_s_cmd_join_bssid(adev, adev->dev_addr);
3754 break;
3755 case ACX_MODE_MONITOR:
3756 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3757 break;
3758 case ACX_MODE_0_ADHOC:
3759 case ACX_MODE_2_STA:
3760 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3761 break;
3762 default:
3763 break;
3765 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3767 if (adev->set_mask & SET_TEMPLATES) {
3768 switch (adev->mode)
3770 case ACX_MODE_3_AP:
3771 acx_s_set_tim_template(adev);
3772 break;
3773 default:
3774 break;
3776 if (adev->beacon_cache)
3778 acx_s_set_beacon_template(adev, adev->beacon_cache);
3779 dev_kfree_skb(adev->beacon_cache);
3780 adev->beacon_cache = NULL;
3782 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3785 if (adev->set_mask & SET_RXCONFIG) {
3786 acx_s_initialize_rx_config(adev);
3787 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3790 if (adev->set_mask & GETSET_RESCAN) {
3791 /* switch (adev->mode) {
3792 case ACX_MODE_0_ADHOC:
3793 case ACX_MODE_2_STA:
3794 start_scan = 1;
3795 break;
3797 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3800 if (adev->set_mask & GETSET_WEP) {
3801 /* encode */
3803 ie_dot11WEPDefaultKeyID_t dkey;
3804 #ifdef DEBUG_WEP
3805 struct {
3806 u16 type;
3807 u16 len;
3808 u8 val;
3809 } ACX_PACKED keyindic;
3810 #endif
3811 log(L_INIT, "updating WEP key settings\n");
3813 acx_s_set_wepkey(adev);
3814 if (adev->wep_enabled) {
3815 dkey.KeyID = adev->wep_current_index;
3816 log(L_INIT, "setting WEP key %u as default\n",
3817 dkey.KeyID);
3818 acx_s_configure(adev, &dkey,
3819 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
3820 #ifdef DEBUG_WEP
3821 keyindic.val = 3;
3822 acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
3823 #endif
3826 // start_scan = 1;
3827 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3830 if (adev->set_mask & SET_WEP_OPTIONS) {
3831 acx100_ie_wep_options_t options;
3833 if (IS_ACX111(adev)) {
3834 log(L_DEBUG,
3835 "setting WEP Options for acx111 is not supported\n");
3836 } else {
3837 log(L_INIT, "setting WEP Options\n");
3839 /* let's choose maximum setting: 4 default keys,
3840 * plus 10 other keys: */
3841 options.NumKeys =
3842 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3843 /* don't decrypt default key only,
3844 * don't override decryption: */
3845 options.WEPOption = 0;
3846 if (adev->mode == ACX_MODE_3_AP) {
3847 /* don't decrypt default key only,
3848 * override decryption mechanism: */
3849 options.WEPOption = 2;
3852 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3854 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3858 /* debug, rate, and nick don't need any handling */
3859 /* what about sniffing mode?? */
3861 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3862 adev->get_mask, adev->set_mask);
3864 /* end: */
3865 FN_EXIT0;
3868 #if 0
3869 /***********************************************************************
3870 ** acx_e_after_interrupt_task
3872 static int acx_s_recalib_radio(acx_device_t * adev)
3874 if (IS_ACX111(adev)) {
3875 acx111_cmd_radiocalib_t cal;
3877 /* automatic recalibration, choose all methods: */
3878 cal.methods = cpu_to_le32(0x8000000f);
3879 /* automatic recalibration every 60 seconds (value in TUs)
3880 * I wonder what the firmware default here is? */
3881 cal.interval = cpu_to_le32(58594);
3882 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3883 &cal, sizeof(cal),
3884 CMD_TIMEOUT_MS(100));
3885 } else {
3886 /* On ACX100, we need to recalibrate the radio
3887 * by issuing a GETSET_TX|GETSET_RX */
3888 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3889 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3890 (OK ==
3891 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3892 &adev->channel, 1))
3893 && (OK ==
3894 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3895 &adev->channel, 1)))
3896 return OK;
3897 return NOT_OK;
3900 #endif // if 0
3901 #if 0
3902 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3904 int res;
3906 /* this helps with ACX100 at least;
3907 * hopefully ACX111 also does a
3908 * recalibration here */
3910 /* clear flag beforehand, since we want to make sure
3911 * it's cleared; then only set it again on specific circumstances */
3912 CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3914 /* better wait a bit between recalibrations to
3915 * prevent overheating due to torturing the card
3916 * into working too long despite high temperature
3917 * (just a safety measure) */
3918 if (adev->recalib_time_last_success
3919 && time_before(jiffies, adev->recalib_time_last_success
3920 + RECALIB_PAUSE * 60 * HZ)) {
3921 if (adev->recalib_msg_ratelimit <= 4) {
3922 printk("%s: less than " STRING(RECALIB_PAUSE)
3923 " minutes since last radio recalibration, "
3924 "not recalibrating (maybe card is too hot?)\n",
3925 wiphy_name(adev->ieee->wiphy));
3926 adev->recalib_msg_ratelimit++;
3927 if (adev->recalib_msg_ratelimit == 5)
3928 printk("disabling above message until next recalib\n");
3930 return;
3933 adev->recalib_msg_ratelimit = 0;
3935 /* note that commands sometimes fail (card busy),
3936 * so only clear flag if we were fully successful */
3937 res = acx_s_recalib_radio(adev);
3938 if (res == OK) {
3939 printk("%s: successfully recalibrated radio\n",
3940 wiphy_name(adev->ieee->wiphy));
3941 adev->recalib_time_last_success = jiffies;
3942 adev->recalib_failure_count = 0;
3943 } else {
3944 /* failed: resubmit, but only limited
3945 * amount of times within some time range
3946 * to prevent endless loop */
3948 adev->recalib_time_last_success = 0; /* we failed */
3950 /* if some time passed between last
3951 * attempts, then reset failure retry counter
3952 * to be able to do next recalib attempt */
3953 if (time_after
3954 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3955 adev->recalib_failure_count = 0;
3957 if (adev->recalib_failure_count < 5) {
3958 /* increment inside only, for speedup of outside path */
3959 adev->recalib_failure_count++;
3960 adev->recalib_time_last_attempt = jiffies;
3961 acx_schedule_task(adev,
3962 ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3966 #endif // if 0
3968 void acx_e_after_interrupt_task(struct work_struct *work)
3970 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
3971 unsigned long flags;
3973 FN_ENTER;
3975 acx_lock(adev, flags);
3977 if (!adev->after_interrupt_jobs || !adev->initialized)
3978 goto end; /* no jobs to do */
3980 /* we see lotsa tx errors */
3981 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) {
3982 printk("too many TX errors??\n");
3983 // acx_s_after_interrupt_recalib(adev);
3986 /* a poor interrupt code wanted to do update_card_settings() */
3987 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) {
3988 if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
3989 acx_unlock(adev, flags);
3990 acx_s_update_card_settings(adev);
3991 acx_lock(adev, flags);
3993 CLEAR_BIT(adev->after_interrupt_jobs,
3994 ACX_AFTER_IRQ_UPDATE_CARD_CFG);
3997 /* 1) we detected that no Scan_Complete IRQ came from fw, or
3998 ** 2) we found too many STAs */
3999 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) {
4000 log(L_IRQ, "sending a stop scan cmd...\n");
4001 acx_unlock(adev, flags);
4002 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
4003 acx_lock(adev, flags);
4004 /* HACK: set the IRQ bit, since we won't get a
4005 * scan complete IRQ any more on ACX111 (works on ACX100!),
4006 * since _we_, not a fw, have stopped the scan */
4007 SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
4008 CLEAR_BIT(adev->after_interrupt_jobs,
4009 ACX_AFTER_IRQ_CMD_STOP_SCAN);
4012 /* either fw sent Scan_Complete or we detected that
4013 ** no Scan_Complete IRQ came from fw. Finish scanning,
4014 ** pick join partner if any */
4015 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) {
4016 /* + scan kills current join status - restore it
4017 ** (do we need it for STA?) */
4018 /* + does it happen only with active scans?
4019 ** active and passive scans? ALL scans including
4020 ** background one? */
4021 /* + was not verified that everything is restored
4022 ** (but at least we start to emit beacons again) */
4023 CLEAR_BIT(adev->after_interrupt_jobs,
4024 ACX_AFTER_IRQ_COMPLETE_SCAN);
4027 /* STA auth or assoc timed out, start over again */
4029 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) {
4030 log(L_IRQ, "sending a start_scan cmd...\n");
4031 CLEAR_BIT(adev->after_interrupt_jobs,
4032 ACX_AFTER_IRQ_RESTART_SCAN);
4035 /* whee, we got positive assoc response! 8) */
4036 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) {
4037 CLEAR_BIT(adev->after_interrupt_jobs,
4038 ACX_AFTER_IRQ_CMD_ASSOCIATE);
4040 end:
4041 if(adev->after_interrupt_jobs)
4043 printk("Jobs still to be run: %x\n",adev->after_interrupt_jobs);
4044 adev->after_interrupt_jobs = 0;
4046 acx_unlock(adev, flags);
4047 // acx_sem_unlock(adev);
4048 FN_EXIT0;
4052 /***********************************************************************
4053 ** acx_schedule_task
4055 ** Schedule the call of the after_interrupt method after leaving
4056 ** the interrupt context.
4058 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
4060 if (!adev->after_interrupt_jobs)
4062 SET_BIT(adev->after_interrupt_jobs, set_flag);
4063 schedule_work(&adev->after_interrupt_task);
4068 /***********************************************************************
4070 void acx_init_task_scheduler(acx_device_t * adev)
4072 /* configure task scheduler */
4073 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4077 /***********************************************************************
4078 ** acx_s_start
4080 void acx_s_start(acx_device_t * adev)
4082 FN_ENTER;
4085 * Ok, now we do everything that can possibly be done with ioctl
4086 * calls to make sure that when it was called before the card
4087 * was up we get the changes asked for
4090 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4091 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4092 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4093 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4095 log(L_INIT, "updating initial settings on iface activation\n");
4096 acx_s_update_card_settings(adev);
4098 FN_EXIT0;
4102 /***********************************************************************
4103 ** acx_update_capabilities
4104 *//*
4105 void acx_update_capabilities(acx_device_t * adev)
4107 u16 cap = 0;
4109 switch (adev->mode) {
4110 case ACX_MODE_3_AP:
4111 SET_BIT(cap, WF_MGMT_CAP_ESS);
4112 break;
4113 case ACX_MODE_0_ADHOC:
4114 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4115 break;
4116 */ /* other types of stations do not emit beacons */
4117 /* }
4119 if (adev->wep_restricted) {
4120 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4122 if (adev->cfgopt_dot11ShortPreambleOption) {
4123 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4125 if (adev->cfgopt_dot11PBCCOption) {
4126 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4128 if (adev->cfgopt_dot11ChannelAgility) {
4129 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4131 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4132 adev->capabilities, cap);
4133 adev->capabilities = cap;
4137 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4140 static void acx_s_select_opmode(acx_device_t * adev)
4142 int changed = 0;
4143 FN_ENTER;
4145 if (adev->interface.operating) {
4146 switch (adev->interface.type) {
4147 case IEEE80211_IF_TYPE_AP:
4148 if (adev->mode != ACX_MODE_3_AP)
4150 adev->mode = ACX_MODE_3_AP;
4151 changed = 1;
4153 break;
4154 case IEEE80211_IF_TYPE_IBSS:
4155 if (adev->mode != ACX_MODE_0_ADHOC)
4157 adev->mode = ACX_MODE_0_ADHOC;
4158 changed = 1;
4160 break;
4161 case IEEE80211_IF_TYPE_STA:
4162 if (adev->mode != ACX_MODE_2_STA)
4164 adev->mode = ACX_MODE_2_STA;
4165 changed = 1;
4167 break;
4168 case IEEE80211_IF_TYPE_WDS:
4169 default:
4170 if (adev->mode != ACX_MODE_OFF)
4172 adev->mode = ACX_MODE_OFF;
4173 changed = 1;
4175 break;
4177 } else {
4178 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4180 if (adev->mode != ACX_MODE_MONITOR)
4182 adev->mode = ACX_MODE_MONITOR;
4183 changed = 1;
4186 else
4188 if (adev->mode != ACX_MODE_OFF)
4190 adev->mode = ACX_MODE_OFF;
4191 changed = 1;
4195 if (changed)
4197 SET_BIT(adev->set_mask, GETSET_MODE);
4198 acx_s_update_card_settings(adev);
4199 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4202 FN_EXIT0;
4206 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4210 int acx_add_interface(struct ieee80211_hw *ieee,
4211 struct ieee80211_if_init_conf *conf)
4213 acx_device_t *adev = ieee2adev(ieee);
4214 unsigned long flags;
4215 int err = -EOPNOTSUPP;
4217 DECLARE_MAC_BUF(mac);
4219 FN_ENTER;
4220 acx_lock(adev, flags);
4222 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4223 adev->interface.monitor++;
4224 } else {
4225 if (adev->interface.operating)
4226 goto out_unlock;
4227 adev->interface.operating = 1;
4228 adev->interface.mac_addr = conf->mac_addr;
4229 adev->interface.type = conf->type;
4231 // adev->mode = conf->type;
4233 acx_unlock(adev, flags);
4235 if (adev->initialized)
4236 acx_s_select_opmode(adev);
4238 acx_lock(adev, flags);
4240 err = 0;
4242 printk(KERN_INFO "Virtual interface added "
4243 "(type: 0x%08X, MAC: %s)\n",
4244 conf->type,
4245 print_mac(mac, conf->mac_addr));
4247 out_unlock:
4248 acx_unlock(adev, flags);
4250 FN_EXIT0;
4251 return err;
4254 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4258 void acx_remove_interface(struct ieee80211_hw *hw,
4259 struct ieee80211_if_init_conf *conf)
4261 acx_device_t *adev = ieee2adev(hw);
4263 DECLARE_MAC_BUF(mac);
4265 FN_ENTER;
4267 acx_sem_lock(adev);
4268 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4269 adev->interface.monitor--;
4270 // assert(bcm->interface.monitor >= 0);
4271 } else {
4272 adev->interface.operating = 0;
4275 printk("Removing interface: %d %d\n", adev->interface.operating, conf->type);
4276 acx_sem_unlock(adev);
4278 if (adev->initialized)
4279 acx_s_select_opmode(adev);
4280 flush_scheduled_work();
4282 printk(KERN_INFO "Virtual interface removed "
4283 "(type: 0x%08X, MAC: %s)\n",
4284 conf->type, print_mac(mac, conf->mac_addr));
4286 FN_EXIT0;
4289 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4293 int acx_net_reset(struct ieee80211_hw *ieee)
4295 acx_device_t *adev = ieee2adev(ieee);
4296 FN_ENTER;
4297 if (IS_PCI(adev))
4298 acxpci_s_reset_dev(adev);
4299 else
4300 TODO();
4302 FN_EXIT0;
4303 return 0;
4307 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4310 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4312 int result;
4314 FN_ENTER;
4316 acx_sem_lock(adev);
4317 adev->rx_status.channel = channel;
4318 adev->rx_status.freq = freq;
4320 adev->channel = channel;
4321 /* hmm, the following code part is strange, but this is how
4322 * it was being done before... */
4323 log(L_IOCTL, "Changing to channel %d\n", channel);
4324 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4325 result = -EINPROGRESS; /* need to call commit handler */
4327 acx_sem_unlock(adev);
4328 FN_EXIT1(result);
4329 return result;
4333 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4336 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4338 acx_device_t *adev = ieee2adev(hw);
4339 unsigned long flags;
4341 FN_ENTER;
4343 acx_lock(adev, flags);
4344 //FIXME();
4345 if (!adev->initialized) {
4346 acx_unlock(adev, flags);
4347 return 0;
4349 if (conf->beacon_int != adev->beacon_interval)
4350 adev->beacon_interval = conf->beacon_int;
4351 if (conf->channel != adev->channel) {
4352 acx_unlock(adev, flags);
4353 acx_selectchannel(adev, conf->channel,conf->freq);
4354 acx_lock(adev, flags);
4355 /* acx_schedule_task(adev,
4356 ACX_AFTER_IRQ_UPDATE_CARD_CFG
4357 */ /*+ ACX_AFTER_IRQ_RESTART_SCAN */ /*);*/
4360 if (conf->short_slot_time != adev->short_slot) {
4361 // assert(phy->type == BCM43xx_PHYTYPE_G);
4362 if (conf->short_slot_time)
4363 acx_short_slot_timing_enable(adev);
4364 else
4365 acx_short_slot_timing_disable(adev);
4366 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4369 adev->tx_disabled = !conf->radio_enabled;
4370 /* if (conf->power_level != 0){
4371 adev->tx_level_dbm = conf->power_level;
4372 acx_s_set_tx_level(adev, adev->tx_level_dbm);
4373 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4374 //acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4377 //FIXME: This does not seem to wake up:
4378 #if 0
4379 if (conf->power_level == 0) {
4380 if (radio->enabled)
4381 bcm43xx_radio_turn_off(bcm);
4382 } else {
4383 if (!radio->enabled)
4384 bcm43xx_radio_turn_on(bcm);
4386 #endif
4388 //TODO: phymode
4389 //TODO: antennas
4390 if (adev->set_mask > 0) {
4391 acx_unlock(adev, flags);
4392 acx_s_update_card_settings(adev);
4393 acx_lock(adev, flags);
4395 acx_unlock(adev, flags);
4397 FN_EXIT0;
4398 return 0;
4402 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4406 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
4407 extern int acx_config_interface(struct ieee80211_hw* ieee,
4408 struct ieee80211_vif *vif,
4409 struct ieee80211_if_conf *conf)
4411 acx_device_t *adev = ieee2adev(ieee);
4412 unsigned long flags;
4413 int err = -ENODEV;
4414 FN_ENTER;
4415 if (!adev->interface.operating)
4416 goto err_out;
4418 if (adev->initialized)
4419 acx_s_select_opmode(adev);
4421 acx_lock(adev, flags);
4423 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4424 && (adev->vif == vif)) {
4425 if (conf->bssid)
4427 adev->interface.bssid = conf->bssid;
4428 MAC_COPY(adev->bssid,conf->bssid);
4431 if ((conf->type == IEEE80211_IF_TYPE_AP)
4432 && (adev->vif == vif)) {
4433 #else
4434 int acx_config_interface(struct ieee80211_hw* ieee, int if_id,
4435 struct ieee80211_if_conf *conf)
4437 acx_device_t *adev = ieee2adev(ieee);
4438 unsigned long flags;
4439 int err = -ENODEV;
4440 FN_ENTER;
4441 if (!adev->interface.operating)
4442 goto err_out;
4444 if (adev->initialized)
4445 acx_s_select_opmode(adev);
4447 acx_lock(adev, flags);
4449 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4450 && (adev->interface.if_id == if_id)) {
4451 if (conf->bssid)
4453 adev->interface.bssid = conf->bssid;
4454 MAC_COPY(adev->bssid,conf->bssid);
4457 if ((conf->type == IEEE80211_IF_TYPE_AP)
4458 && (adev->interface.if_id == if_id)) {
4459 #endif
4461 if ((conf->ssid_len > 0) && conf->ssid)
4463 adev->essid_len = conf->ssid_len;
4464 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4465 SET_BIT(adev->set_mask, SET_TEMPLATES);
4468 if (conf->beacon != 0)
4470 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4471 adev->beacon_cache = conf->beacon;
4472 SET_BIT(adev->set_mask, SET_TEMPLATES);
4475 acx_unlock(adev, flags);
4477 if (adev->set_mask != 0)
4478 acx_s_update_card_settings(adev);
4479 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4480 err = 0;
4481 err_out:
4482 FN_EXIT1(err);
4483 return err;
4487 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4491 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4492 struct ieee80211_tx_queue_stats *stats)
4494 // acx_device_t *adev = ndev2adev(net_dev);
4495 struct ieee80211_tx_queue_stats_data *data;
4496 int err = -ENODEV;
4498 FN_ENTER;
4500 // acx_lock(adev, flags);
4501 data = &(stats->data[0]);
4502 data->len = 0;
4503 data->limit = TX_CNT;
4504 data->count = 0;
4505 // acx_unlock(adev, flags);
4507 FN_EXIT0;
4508 return err;
4511 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4515 int acx_net_conf_tx(struct ieee80211_hw *hw,
4516 int queue, const struct ieee80211_tx_queue_params *params)
4518 FN_ENTER;
4519 // TODO();
4520 FN_EXIT0;
4521 return 0;
4524 static void keymac_write(acx_device_t * adev, u16 index, const u32 * addr)
4526 /* for keys 0-3 there is no associated mac address */
4527 if (index < 4)
4528 return;
4530 index -= 4;
4531 if (1) {
4532 TODO();
4534 bcm43xx_shm_write32(bcm,
4535 BCM43xx_SHM_HWMAC,
4536 index * 2,
4537 cpu_to_be32(*addr));
4538 bcm43xx_shm_write16(bcm,
4539 BCM43xx_SHM_HWMAC,
4540 (index * 2) + 1,
4541 cpu_to_be16(*((u16 *)(addr + 1))));
4543 } else {
4544 if (index < 8) {
4545 TODO(); /* Put them in the macaddress filter */
4546 } else {
4547 TODO();
4548 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4549 Keep in mind to update the count of keymacs in 0x003 */
4555 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4559 int acx_clear_keys(acx_device_t * adev)
4561 static const u32 zero_mac[2] = { 0 };
4562 unsigned int i, j, nr_keys = 54;
4563 u16 offset;
4565 /* FixMe:Check for Number of Keys available */
4567 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4569 for (i = 0; i < nr_keys; i++) {
4570 adev->key[i].enabled = 0;
4571 /* returns for i < 4 immediately */
4572 keymac_write(adev, i, zero_mac);
4574 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4575 0x100 + (i * 2), 0x0000);
4577 for (j = 0; j < 8; j++) {
4578 offset =
4579 adev->security_offset + (j * 4) +
4580 (i * ACX_SEC_KEYSIZE);
4582 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4583 offset, 0x0000);
4587 return 1;
4591 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4595 int acx_key_write(acx_device_t * adev,
4596 u16 index, u8 algorithm,
4597 const struct ieee80211_key_conf *key, const u8 * mac_addr)
4599 // struct iw_point *dwrq = &wrqu->encoding;
4600 int result;
4602 FN_ENTER;
4604 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4605 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4607 // acx_sem_lock(adev);
4609 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4610 if (key->keylen > 0) {
4611 /* if index is 0 or invalid, use default key */
4612 if (index > 3)
4613 index = (int)adev->wep_current_index;
4614 if ((algorithm == ACX_SEC_ALGO_WEP) ||
4615 (algorithm == ACX_SEC_ALGO_WEP104)) {
4616 switch(key->keylen) {
4617 case 40 / 8:
4618 /* WEP 40-bit =
4619 40-bit entered key + 24 bit IV = 64-bit */
4620 adev->wep_keys[index].size = 13;
4621 break;
4622 case 104 / 8:
4623 /* WEP 104-bit =
4624 104-bit entered key + 24-bit IV = 128-bit */
4625 adev->wep_keys[index].size = 29;
4626 break;
4627 case 128 / 8:
4628 /* WEP 128-bit =
4629 128-bit entered key + 24 bit IV = 152-bit */
4630 adev->wep_keys[index].size = 16;
4631 break;
4632 default:
4633 adev->wep_keys[index].size = 0;
4634 return -EINVAL; /* shouldn't happen */
4637 memset(adev->wep_keys[index].key, 0,
4638 sizeof(adev->wep_keys[index].key));
4639 memcpy(adev->wep_keys[index].key, key, key->keylen);
4640 } else {
4641 /* set transmit key */
4642 if (index <= 3)
4643 adev->wep_current_index = index;
4644 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4645 /* complain if we were not just setting
4646 * the key mode */
4647 // result = -EINVAL;
4648 // goto end_unlock;
4649 // }
4653 adev->wep_enabled = (algorithm == ALG_WEP);
4655 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4657 if (algorithm & IW_ENCODE_OPEN) {
4658 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4659 adev->wep_restricted = 0;
4661 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4662 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4663 adev->wep_restricted = 1;
4666 // adev->auth_alg = algorithm;
4667 /* set flag to make sure the card WEP settings get updated */
4668 if (adev->wep_enabled) {
4669 SET_BIT(adev->set_mask, GETSET_WEP);
4670 acx_s_update_card_settings(adev);
4671 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4674 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4675 dwrq->length, extra, dwrq->flags);
4676 for (index = 0; index <= 3; index++) {
4677 if (adev->wep_keys[index].size) {
4678 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4679 adev->wep_keys[index].index,
4680 (int) adev->wep_keys[index].size,
4681 adev->wep_keys[index].key);
4685 result = -EINPROGRESS;
4686 // acx_sem_unlock(adev);
4688 FN_EXIT1(result);
4689 return result;
4695 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4699 int acx_net_set_key(struct ieee80211_hw *ieee,
4700 enum set_key_cmd cmd, const u8 *local_addr,
4701 const u8 * addr, struct ieee80211_key_conf *key)
4703 // return 0;
4704 struct acx_device *adev = ieee2adev(ieee);
4705 unsigned long flags;
4706 u8 algorithm;
4707 u16 index;
4708 int err = -EINVAL;
4709 FN_ENTER;
4710 // TODO();
4711 switch (key->alg) {
4712 default:
4713 /* case ALG_NONE:
4714 case ALG_NULL:
4715 algorithm = ACX_SEC_ALGO_NONE;
4716 break;
4717 */ case ALG_WEP:
4718 if (key->keylen == 5)
4719 algorithm = ACX_SEC_ALGO_WEP;
4720 else
4721 algorithm = ACX_SEC_ALGO_WEP104;
4722 break;
4723 case ALG_TKIP:
4724 algorithm = ACX_SEC_ALGO_TKIP;
4725 break;
4726 case ALG_CCMP:
4727 algorithm = ACX_SEC_ALGO_AES;
4728 break;
4731 index = (u8) (key->keyidx);
4732 if (index >= ARRAY_SIZE(adev->key))
4733 goto out;
4734 acx_lock(adev, flags);
4735 switch (cmd) {
4736 case SET_KEY:
4737 err = acx_key_write(adev, index, algorithm, key, addr);
4738 if (err)
4739 goto out_unlock;
4740 key->hw_key_idx = index;
4741 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4742 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4743 adev->default_key_idx = index;*/
4744 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4745 adev->key[index].enabled = 1;
4746 break;
4747 case DISABLE_KEY:
4748 adev->key[index].enabled = 0;
4749 err = 0;
4750 break;
4751 /* case ENABLE_COMPRESSION:
4752 case DISABLE_COMPRESSION:
4753 err = 0;
4754 break; */
4756 out_unlock:
4757 acx_unlock(adev, flags);
4758 out:
4759 FN_EXIT0;
4760 return err;
4765 /***********************************************************************
4766 ** Common function to parse ALL configoption struct formats
4767 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4768 ** FIXME: logging should be removed here and added to a /proc file instead
4770 ** Look into bcm43xx
4772 void
4773 acx_s_parse_configoption(acx_device_t * adev,
4774 const acx111_ie_configoption_t * pcfg)
4776 const u8 *pEle;
4777 int i;
4778 int is_acx111 = IS_ACX111(adev);
4780 if (acx_debug & L_DEBUG) {
4781 printk("configoption struct content:\n");
4782 acx_dump_bytes(pcfg, sizeof(*pcfg));
4785 if ((is_acx111 && (adev->eeprom_version == 5))
4786 || (!is_acx111 && (adev->eeprom_version == 4))
4787 || (!is_acx111 && (adev->eeprom_version == 5))) {
4788 /* these versions are known to be supported */
4789 } else {
4790 printk("unknown chip and EEPROM version combination (%s, v%d), "
4791 "don't know how to parse config options yet. "
4792 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4793 adev->eeprom_version);
4794 return;
4797 /* first custom-parse the first part which has chip-specific layout */
4799 pEle = (const u8 *)pcfg;
4801 pEle += 4; /* skip (type,len) header */
4803 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4804 pEle += sizeof(adev->cfgopt_NVSv);
4806 if (is_acx111) {
4807 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4808 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4810 adev->cfgopt_probe_delay = 200; /* good default value? */
4811 pEle += 2; /* FIXME: unknown, value 0x0001 */
4812 } else {
4813 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4814 pEle += sizeof(adev->cfgopt_MAC);
4816 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4817 pEle += sizeof(adev->cfgopt_probe_delay);
4818 if ((adev->cfgopt_probe_delay < 100)
4819 || (adev->cfgopt_probe_delay > 500)) {
4820 printk("strange probe_delay value %d, "
4821 "tweaking to 200\n", adev->cfgopt_probe_delay);
4822 adev->cfgopt_probe_delay = 200;
4826 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4827 pEle += sizeof(adev->cfgopt_eof_memory);
4829 printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n",
4830 adev->cfgopt_NVS_vendor_offs,
4831 adev->cfgopt_probe_delay, adev->cfgopt_eof_memory);
4833 adev->cfgopt_dot11CCAModes = *pEle++;
4834 adev->cfgopt_dot11Diversity = *pEle++;
4835 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4836 adev->cfgopt_dot11PBCCOption = *pEle++;
4837 adev->cfgopt_dot11ChannelAgility = *pEle++;
4838 adev->cfgopt_dot11PhyType = *pEle++;
4839 adev->cfgopt_dot11TempType = *pEle++;
4840 printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4841 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4842 adev->cfgopt_dot11CCAModes,
4843 adev->cfgopt_dot11Diversity,
4844 adev->cfgopt_dot11ShortPreambleOption,
4845 adev->cfgopt_dot11PBCCOption,
4846 adev->cfgopt_dot11ChannelAgility,
4847 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4849 /* then use common parsing for next part which has common layout */
4851 pEle++; /* skip table_count (6) */
4853 adev->cfgopt_antennas.type = pEle[0];
4854 adev->cfgopt_antennas.len = pEle[1];
4855 printk("AntennaID:%02X Len:%02X Data:",
4856 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4857 for (i = 0; i < pEle[1]; i++) {
4858 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4859 printk("%02X ", pEle[i + 2]);
4861 printk("\n");
4863 pEle += pEle[1] + 2;
4864 adev->cfgopt_power_levels.type = pEle[0];
4865 adev->cfgopt_power_levels.len = pEle[1];
4866 printk("PowerLevelID:%02X Len:%02X Data:",
4867 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4868 for (i = 0; i < pEle[1]; i++) {
4869 adev->cfgopt_power_levels.list[i] =
4870 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4871 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4873 printk("\n");
4875 pEle += pEle[1] * 2 + 2;
4876 adev->cfgopt_data_rates.type = pEle[0];
4877 adev->cfgopt_data_rates.len = pEle[1];
4878 printk("DataRatesID:%02X Len:%02X Data:",
4879 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4880 for (i = 0; i < pEle[1]; i++) {
4881 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4882 printk("%02X ", pEle[i + 2]);
4884 printk("\n");
4886 pEle += pEle[1] + 2;
4887 adev->cfgopt_domains.type = pEle[0];
4888 adev->cfgopt_domains.len = pEle[1];
4889 printk("DomainID:%02X Len:%02X Data:",
4890 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4891 for (i = 0; i < pEle[1]; i++) {
4892 adev->cfgopt_domains.list[i] = pEle[i + 2];
4893 printk("%02X ", pEle[i + 2]);
4895 printk("\n");
4897 pEle += pEle[1] + 2;
4898 adev->cfgopt_product_id.type = pEle[0];
4899 adev->cfgopt_product_id.len = pEle[1];
4900 for (i = 0; i < pEle[1]; i++) {
4901 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4903 printk("ProductID:%02X Len:%02X Data:%.*s\n",
4904 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4905 adev->cfgopt_product_id.len,
4906 (char *)adev->cfgopt_product_id.list);
4908 pEle += pEle[1] + 2;
4909 adev->cfgopt_manufacturer.type = pEle[0];
4910 adev->cfgopt_manufacturer.len = pEle[1];
4911 for (i = 0; i < pEle[1]; i++) {
4912 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4914 printk("ManufacturerID:%02X Len:%02X Data:%.*s\n",
4915 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4916 adev->cfgopt_manufacturer.len,
4917 (char *)adev->cfgopt_manufacturer.list);
4919 printk("EEPROM part:\n");
4920 for (i=0; i<58; i++) {
4921 printk("%02X =======> 0x%02X\n",
4922 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4928 /***********************************************************************
4929 ** Linux Kernel Specific
4931 static int __init acx_e_init_module(void)
4933 int r1, r2;
4935 acx_struct_size_check();
4937 printk("acx: this driver is still EXPERIMENTAL\n"
4938 "acx: please read the README file and/or "
4939 "go to http://acx100.sourceforge.net/wiki for "
4940 "further information\n");
4942 #if defined(CONFIG_ACX_MAC80211_PCI)
4943 r1 = acxpci_e_init_module();
4944 #else
4945 r1 = -EINVAL;
4946 #endif
4947 #if defined(CONFIG_ACX_MAC80211_USB)
4948 r2 = acxusb_e_init_module();
4949 #else
4950 r2 = -EINVAL;
4951 #endif
4952 if (r2 && r1) /* both failed! */
4953 return r2 ? r2 : r1;
4954 /* return success if at least one succeeded */
4955 return 0;
4958 static void __exit acx_e_cleanup_module(void)
4960 #if defined(CONFIG_ACX_MAC80211_PCI)
4961 acxpci_e_cleanup_module();
4962 #endif
4963 #if defined(CONFIG_ACX_MAC80211_USB)
4964 acxusb_e_cleanup_module();
4965 #endif
4968 module_init(acx_e_init_module)
4969 module_exit(acx_e_cleanup_module)