Reverted refactoring of 'interrogate' cmds to 'query'
[acx-mac80211.git] / common.c
blob3ce83e137562b59b8fbf7624603dadd4049c4bd7
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"
26 #include "acx_debug.h"
27 #include "acx_log.h"
28 #include "acx_irq.h"
29 #include "acx_mmio.h"
32 /***********************************************************************
35 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf);
39 MODULE_LICENSE("GPL");
40 /* USB had this: MODULE_AUTHOR("Martin Wawro <martin.wawro AT uni-dortmund.de>"); */
41 MODULE_AUTHOR("ACX100 Open Source Driver development team");
42 MODULE_DESCRIPTION
43 ("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)");
45 MODULE_VERSION(ACX_RELEASE);
47 /***********************************************************************
49 /* Probably a number of acx's intermediate buffers for USB transfers,
50 ** not to be confused with number of descriptors in tx/rx rings
51 ** (which are not directly accessible to host in USB devices) */
52 #define USB_RX_CNT 10
53 #define USB_TX_CNT 10
56 /***********************************************************************
59 /* minutes to wait until next radio recalibration: */
60 #define RECALIB_PAUSE 5
62 /* Please keep acx_reg_domain_ids_len in sync... */
63 const u8 acx_reg_domain_ids[acx_reg_domain_ids_len] =
64 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 };
65 static const u16 reg_domain_channel_masks[acx_reg_domain_ids_len] =
66 { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc };
67 const char *const
68 acx_reg_domain_strings[] = {
69 /* 0 */ " 1-11 FCC (USA)",
70 /* 1 */ " 1-11 DOC/IC (Canada)",
71 /* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */
72 /* 2 */ " 1-13 ETSI (Europe)",
73 /* 3 */ "10-11 Spain",
74 /* 4 */ "10-13 France",
75 /* 5 */ " 14 MKK (Japan)",
76 /* 6 */ " 1-14 MKK1",
77 /* 7 */ " 3-9 Israel (not all firmware versions)",
78 NULL /* needs to remain as last entry */
83 /***********************************************************************
84 ** Debugging support
86 #ifdef PARANOID_LOCKING
87 static unsigned max_lock_time;
88 static unsigned max_sem_time;
90 /* Obvious or linux kernel specific derived code follows: */
92 void acx_lock_unhold()
94 max_lock_time = 0;
97 void acx_sem_unhold()
99 max_sem_time = 0;
102 static inline const char *sanitize_str(const char *s)
104 const char *t = strrchr(s, '/');
105 if (t)
106 return t + 1;
107 return s;
110 void acx_lock_debug(acx_device_t * adev, const char *where)
112 unsigned int count = 100 * 1000 * 1000;
113 where = sanitize_str(where);
114 while (--count) {
115 if (!spin_is_locked(&adev->spinlock))
116 break;
117 cpu_relax();
119 if (!count) {
120 printk(KERN_EMERG "LOCKUP: already taken at %s!\n",
121 adev->last_lock);
122 BUG();
124 adev->last_lock = where;
125 rdtscl(adev->lock_time);
128 void acx_unlock_debug(acx_device_t * adev, const char *where)
130 #ifdef SMP
131 if (!spin_is_locked(&adev->spinlock)) {
132 where = sanitize_str(where);
133 printk(KERN_EMERG "STRAY UNLOCK at %s!\n", where);
134 BUG();
136 #endif
137 if (acx_debug & L_LOCK) {
138 unsigned long diff;
139 rdtscl(diff);
140 diff -= adev->lock_time;
141 if (diff > max_lock_time) {
142 where = sanitize_str(where);
143 acx_log(LOG_DEBUG, L_LOCK, "max lock hold time "
144 "%ld CPU ticks from %s to %s\n", diff,
145 adev->last_lock, where);
146 max_lock_time = diff;
150 #endif /* PARANOID_LOCKING */
154 /***********************************************************************
155 ** Basically a mdelay/msleep with logging
157 void acx_s_mwait(int ms)
159 FN_ENTER;
160 msleep(ms);
161 FN_EXIT0;
165 /***********************************************************************
166 ** acx_cmd_status_str
168 const char *acx_cmd_status_str(unsigned int state)
170 static const char *const cmd_error_strings[] = {
171 "Idle",
172 "Success",
173 "Unknown Command",
174 "Invalid Information Element",
175 "Channel rejected",
176 "Channel invalid in current regulatory domain",
177 "MAC invalid",
178 "Command rejected (read-only information element)",
179 "Command rejected",
180 "Already asleep",
181 "TX in progress",
182 "Already awake",
183 "Write only",
184 "RX in progress",
185 "Invalid parameter",
186 "Scan in progress",
187 "Failed"
189 return state < ARRAY_SIZE(cmd_error_strings) ?
190 cmd_error_strings[state] : "?";
193 /***********************************************************************
194 ** acx_s_get_firmware_version
196 ** Obvious
198 void acx_s_get_firmware_version(acx_device_t * adev)
200 fw_ver_t fw;
201 u8 hexarr[4] = { 0, 0, 0, 0 };
202 int hexidx = 0, val = 0;
203 const char *num;
204 char c;
206 FN_ENTER;
208 memset(fw.fw_id, 'E', FW_ID_SIZE);
209 acx_s_interrogate(adev, &fw, ACX1xx_REG_FWREV);
210 memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE);
211 adev->firmware_version[FW_ID_SIZE] = '\0';
213 acx_log(LOG_DEBUG, L_ANY, "fw_ver: fw_id='%s' hw_id=%08X\n",
214 adev->firmware_version, fw.hw_id);
216 if (strncmp(fw.fw_id, "Rev ", 4) != 0) {
217 acx_log(LOG_WARNING, L_ANY, "acx: strange firmware version string "
218 "'%s', please report\n", adev->firmware_version);
219 adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */
220 } else {
221 num = &fw.fw_id[4];
222 while (1) {
223 c = *num++;
224 if ((c == '.') || (c == '\0')) {
225 hexarr[hexidx++] = val;
226 if ((hexidx > 3) || (c == '\0')) /* end? */
227 break;
228 val = 0;
229 continue;
231 if ((c >= '0') && (c <= '9'))
232 c -= '0';
233 else
234 c = c - 'a' + (char)10;
235 val = val * 16 + c;
238 adev->firmware_numver = (u32) ((hexarr[0] << 24) |
239 (hexarr[1] << 16)
240 | (hexarr[2] << 8) | hexarr[3]);
241 acx_log(LOG_DEBUG, L_ANY, "firmware_numver 0x%08X\n",
242 adev->firmware_numver);
245 adev->firmware_id = le32_to_cpu(fw.hw_id);
247 /* we're able to find out more detailed chip names now */
248 switch (adev->firmware_id & 0xffff0000) {
249 case 0x01010000:
250 case 0x01020000:
251 adev->chip_name = "TNETW1100A";
252 break;
253 case 0x01030000:
254 adev->chip_name = "TNETW1100B";
255 break;
256 case 0x03000000:
257 case 0x03010000:
258 adev->chip_name = "TNETW1130";
259 break;
260 case 0x04030000: /* 0x04030101 is TNETW1450 */
261 adev->chip_name = "TNETW1450";
262 break;
263 default:
264 acx_log(LOG_WARNING, L_ANY,"unknown chip ID 0x%08X, "
265 "please report\n", adev->firmware_id);
266 break;
269 FN_EXIT0;
273 /***********************************************************************
274 ** acx_display_hardware_details
276 ** Displays hw/fw version, radio type etc...
278 ** Obvious
280 void acx_display_hardware_details(acx_device_t * adev)
282 const char *radio_str, *form_str;
284 FN_ENTER;
286 switch (adev->radio_type) {
287 case RADIO_MAXIM_0D:
288 radio_str = "Maxim";
289 break;
290 case RADIO_RFMD_11:
291 radio_str = "RFMD";
292 break;
293 case RADIO_RALINK_15:
294 radio_str = "Ralink";
295 break;
296 case RADIO_RADIA_16:
297 radio_str = "Radia";
298 break;
299 case RADIO_UNKNOWN_17:
300 /* TI seems to have a radio which is
301 * additionally 802.11a capable, too */
302 radio_str = "802.11a/b/g radio?! Please report";
303 break;
304 case RADIO_UNKNOWN_19:
305 radio_str = "A radio used by Safecom cards?! Please report";
306 break;
307 case RADIO_UNKNOWN_1B:
308 radio_str = "An unknown radio used by TNETW1450 USB adapters";
309 break;
310 default:
311 radio_str = "UNKNOWN, please report radio type name!";
312 break;
315 switch (adev->form_factor) {
316 case 0x00:
317 form_str = "unspecified";
318 break;
319 case 0x01:
320 form_str = "(mini-)PCI / CardBus";
321 break;
322 case 0x02:
323 form_str = "USB";
324 break;
325 case 0x03:
326 form_str = "Compact Flash";
327 break;
328 default:
329 form_str = "UNKNOWN, please report";
330 break;
333 acx_log(LOG_INFO, L_ANY, "acx: chipset %s, radio type 0x%02X (%s), "
334 "form factor 0x%02X (%s), EEPROM version 0x%02X, "
335 "uploaded firmware '%s'\n",
336 adev->chip_name, adev->radio_type, radio_str,
337 adev->form_factor, form_str, adev->eeprom_version,
338 adev->firmware_version);
340 FN_EXIT0;
344 /***********************************************************************
345 ** acx_e_get_stats, acx_e_get_wireless_stats
348 acx_e_get_stats(struct ieee80211_hw *hw,
349 struct ieee80211_low_level_stats *stats)
351 acx_device_t *adev = ieee2adev(hw);
352 unsigned long flags;
353 acx_lock(adev, flags);
354 memcpy(stats, &adev->ieee_stats, sizeof(*stats));
355 acx_unlock(adev, flags);
356 return 0;
360 /***********************************************************************
361 ** maps acx111 tx descr rate field to acx100 one
363 const u8 acx_bitpos2rate100[] = {
364 RATE100_1, /* 0 */
365 RATE100_2, /* 1 */
366 RATE100_5, /* 2 */
367 RATE100_2, /* 3, should not happen */
368 RATE100_2, /* 4, should not happen */
369 RATE100_11, /* 5 */
370 RATE100_2, /* 6, should not happen */
371 RATE100_2, /* 7, should not happen */
372 RATE100_22, /* 8 */
373 RATE100_2, /* 9, should not happen */
374 RATE100_2, /* 10, should not happen */
375 RATE100_2, /* 11, should not happen */
376 RATE100_2, /* 12, should not happen */
377 RATE100_2, /* 13, should not happen */
378 RATE100_2, /* 14, should not happen */
379 RATE100_2, /* 15, should not happen */
382 u8 acx_rate111to100(u16 r)
384 return acx_bitpos2rate100[highest_bit(r)];
388 /***********************************************************************
389 ** Calculate level like the feb 2003 windows driver seems to do
391 * Note: the FreeBSD and DragonFlyBSD drivers seems to use different
392 * so-called correction constants depending on the chip. They will be
393 * defined for now, but as it is still unknown whether they are correct
394 * or not, only the original value will be used. Something else to take
395 * into account is that the OpenBSD driver uses another approach and
396 * defines the maximum RSSI value depending on the chip, rather than
397 * using a value of 100 for all of them, as it is currently done here.
399 #define ACX100_RSSI_CORR 8
400 #define ACX111_RSSI_CORR 5
401 static u8 acx_signal_to_winlevel(u8 rawlevel)
403 /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
404 u8 winlevel = (((ACX100_RSSI_CORR / 2) + (rawlevel * 5)) /
405 ACX100_RSSI_CORR);
407 if (winlevel > 100)
408 winlevel = 100;
409 return winlevel;
412 u8 acx_signal_determine_quality(u8 signal, u8 noise)
414 int qual;
416 qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2;
418 if (qual > 100)
419 return 100;
420 if (qual < 0)
421 return 0;
422 return qual;
426 /***********************************************************************
427 ** Interrogate/configure commands
430 /* FIXME: the lengths given here probably aren't always correct.
431 * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4",
432 * unless the firmware actually expects a different length than the struct length */
433 static const u16 acx100_ie_len[] = {
435 ACX100_REG_ACX_TIMER_LEN,
436 sizeof(acx100_ie_powersave_t) - 4, /* is that 6 or 8??? */
437 ACX1xx_REG_QUEUE_CONFIG_LEN,
438 ACX100_REG_BLOCK_SIZE_LEN,
439 ACX1xx_REG_MEMORY_CONFIG_OPTIONS_LEN,
440 ACX1xx_REG_RATE_FALLBACK_LEN,
441 ACX100_REG_WEP_OPTIONS_LEN,
442 ACX1xx_REG_MEMORY_MAP_LEN, /* ACX1xx_REG_SSID_LEN, */
444 ACX1xx_REG_ASSOC_ID_LEN,
446 ACX111_REG_CONFIG_OPTIONS_LEN,
447 ACX1xx_REG_FWREV_LEN,
448 ACX1xx_REG_FCS_ERROR_COUNT_LEN,
449 ACX1xx_REG_MEDIUM_USAGE_LEN,
450 ACX1xx_REG_RXCONFIG_LEN,
453 sizeof(fw_stats_t) - 4,
455 ACX1xx_REG_FEATURE_CONFIG_LEN,
456 ACX111_REG_KEY_CHOOSE_LEN,
457 ACX1FF_REG_MISC_CONFIG_TABLE_LEN,
458 ACX1FF_REG_WONE_CONFIG_LEN,
460 ACX1FF_REG_TID_CONFIG_LEN,
464 ACX1FF_REG_CALIB_ASSESSMENT_LEN,
465 ACX1FF_REG_BEACON_FILTER_OPTIONS_LEN,
466 ACX1FF_REG_LOW_RSSI_THRESH_OPT_LEN,
467 ACX1FF_REG_NOISE_HISTOGRAM_RESULTS_LEN,
469 ACX1FF_REG_PACKET_DETECT_THRESH_LEN,
470 ACX1FF_REG_TX_CONFIG_OPTIONS_LEN,
471 ACX1FF_REG_CCA_THRESHOLD_LEN,
472 ACX1FF_REG_EVENT_MASK_LEN,
473 ACX1FF_REG_DTIM_PERIOD_LEN,
475 ACX1FF_REG_ACI_CONFIG_SET_LEN,
482 ACX1FF_REG_EEPROM_VER_LEN,
485 static const u16 acx100_ie_len_dot11[] = {
487 ACX1xx_REG_DOT11_STATION_ID_LEN,
489 ACX100_REG_DOT11_BEACON_PERIOD_LEN,
490 ACX1xx_REG_DOT11_DTIM_PERIOD_LEN,
491 ACX1xx_REG_DOT11_SHORT_RETRY_LIMIT_LEN,
492 ACX1xx_REG_DOT11_LONG_RETRY_LIMIT_LEN,
493 ACX100_REG_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
494 ACX1xx_REG_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
496 ACX1xx_REG_DOT11_CURRENT_REG_DOMAIN_LEN,
497 ACX1xx_REG_DOT11_CURRENT_ANTENNA_LEN,
499 ACX1xx_REG_DOT11_TX_POWER_LEVEL_LEN,
500 ACX1xx_REG_DOT11_CURRENT_CCA_MODE_LEN,
501 ACX100_REG_DOT11_ED_THRESHOLD_LEN,
502 ACX1xx_REG_DOT11_WEP_DEFAULT_KEY_SET_LEN,
508 static const u16 acx111_ie_len[] = {
510 ACX100_REG_ACX_TIMER_LEN,
511 sizeof(acx111_ie_powersave_t) - 4,
512 ACX1xx_REG_QUEUE_CONFIG_LEN,
513 ACX100_REG_BLOCK_SIZE_LEN,
514 ACX1xx_REG_MEMORY_CONFIG_OPTIONS_LEN,
515 ACX1xx_REG_RATE_FALLBACK_LEN,
516 ACX100_REG_WEP_OPTIONS_LEN,
517 ACX1xx_REG_MEMORY_MAP_LEN, /* ACX1xx_REG_SSID_LEN, */
519 ACX1xx_REG_ASSOC_ID_LEN,
521 ACX111_REG_CONFIG_OPTIONS_LEN,
522 ACX1xx_REG_FWREV_LEN,
523 ACX1xx_REG_FCS_ERROR_COUNT_LEN,
524 ACX1xx_REG_MEDIUM_USAGE_LEN,
525 ACX1xx_REG_RXCONFIG_LEN,
528 sizeof(fw_stats_t) - 4,
530 ACX1xx_REG_FEATURE_CONFIG_LEN,
531 ACX111_REG_KEY_CHOOSE_LEN,
532 ACX1FF_REG_MISC_CONFIG_TABLE_LEN,
533 ACX1FF_REG_WONE_CONFIG_LEN,
535 ACX1FF_REG_TID_CONFIG_LEN,
539 ACX1FF_REG_CALIB_ASSESSMENT_LEN,
540 ACX1FF_REG_BEACON_FILTER_OPTIONS_LEN,
541 ACX1FF_REG_LOW_RSSI_THRESH_OPT_LEN,
542 ACX1FF_REG_NOISE_HISTOGRAM_RESULTS_LEN,
544 ACX1FF_REG_PACKET_DETECT_THRESH_LEN,
545 ACX1FF_REG_TX_CONFIG_OPTIONS_LEN,
546 ACX1FF_REG_CCA_THRESHOLD_LEN,
547 ACX1FF_REG_EVENT_MASK_LEN,
548 ACX1FF_REG_DTIM_PERIOD_LEN,
550 ACX1FF_REG_ACI_CONFIG_SET_LEN,
557 ACX1FF_REG_EEPROM_VER_LEN,
560 static const u16 acx111_ie_len_dot11[] = {
562 ACX1xx_REG_DOT11_STATION_ID_LEN,
564 ACX100_REG_DOT11_BEACON_PERIOD_LEN,
565 ACX1xx_REG_DOT11_DTIM_PERIOD_LEN,
566 ACX1xx_REG_DOT11_SHORT_RETRY_LIMIT_LEN,
567 ACX1xx_REG_DOT11_LONG_RETRY_LIMIT_LEN,
568 ACX100_REG_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
569 ACX1xx_REG_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
571 ACX1xx_REG_DOT11_CURRENT_REG_DOMAIN_LEN,
572 ACX1xx_REG_DOT11_CURRENT_ANTENNA_LEN,
574 ACX1xx_REG_DOT11_TX_POWER_LEVEL_LEN,
575 ACX1xx_REG_DOT11_CURRENT_CCA_MODE_LEN,
576 ACX100_REG_DOT11_ED_THRESHOLD_LEN,
577 ACX1xx_REG_DOT11_WEP_DEFAULT_KEY_SET_LEN,
584 #if !ACX_DEBUG
585 int acx_s_configure(acx_device_t * adev, void *pdr, int type)
587 #else
589 acx_s_configure_debug(acx_device_t * adev, void *pdr, int type,
590 const char *typestr)
592 #endif
593 u16 len;
594 int res;
596 if (type < 0x1000)
597 len = adev->ie_len[type];
598 else
599 len = adev->ie_len_dot11[type - 0x1000];
601 acx_log(LOG_DEBUG, L_CTL, "configure (type:%s,len:%u)\n", typestr, len);
602 if (unlikely(!len)) {
603 acx_log(LOG_DEBUG, L_ANY, "zero-length type %s?!\n", typestr);
606 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
607 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
608 res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4);
609 if (unlikely(OK != res)) {
610 #if ACX_DEBUG
611 acx_log(LOG_WARNING, L_ANY, "%s: configure (type:%s) FAILED\n",
612 wiphy_name(adev->ieee->wiphy), typestr);
613 #else
614 acx_log(LOG_WARNING, L_ANY,
615 "%s: configure (type:0x%X) FAILED\n",
616 wiphy_name(adev->ieee->wiphy), type);
617 #endif
618 /* dump_stack() is already done in issue_cmd() */
620 return res;
623 #if !ACX_DEBUG
624 int acx_s_interrogate(acx_device_t * adev, void *pdr, int type)
626 #else
628 acx_s_interrogate_debug(acx_device_t * adev, void *pdr, int type,
629 const char *typestr)
631 #endif
632 u16 len;
633 int res;
635 FN_ENTER;
637 /* FIXME: no check whether this exceeds the array yet.
638 * We should probably remember the number of entries... */
639 if (type < 0x1000)
640 len = adev->ie_len[type];
641 else
642 len = adev->ie_len_dot11[type - 0x1000];
644 acx_log(LOG_DEBUG, L_CTL, "query (type:%s,len:%u)\n",
645 typestr, len);
647 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
648 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
649 res = acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, pdr, len + 4);
650 if (unlikely(OK != res)) {
651 #if ACX_DEBUG
652 acx_log(LOG_WARNING, L_ANY,
653 "%s: query (type:%s) FAILED\n",
654 wiphy_name(adev->ieee->wiphy), typestr);
655 #else
656 acx_log(LOG_WARNING, L_ANY,
657 "%s: query (type:0x%X) FAILED\n",
658 wiphy_name(adev->ieee->wiphy), type);
659 #endif
660 /* dump_stack() is already done in issue_cmd() */
663 FN_EXIT1(res);
664 return res;
667 #if CMD_DISCOVERY
668 void great_inquisitor(acx_device_t * adev)
670 static struct {
671 u16 type;
672 u16 len;
673 /* 0x200 was too large here: */
674 u8 data[0x100 - 4];
675 } __attribute__ ((packed)) ie;
676 u16 type;
678 FN_ENTER;
680 /* 0..0x20, 0x1000..0x1020 */
681 for (type = 0; type <= 0x1020; type++) {
682 if (type == 0x21)
683 type = 0x1000;
684 ie.type = cpu_to_le16(type);
685 ie.len = cpu_to_le16(sizeof(ie) - 4);
686 acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie));
688 FN_EXIT0;
690 #endif
693 #ifdef CONFIG_PROC_FS
694 /***********************************************************************
695 ** /proc files
697 /***********************************************************************
698 ** acx_l_proc_output
699 ** Generate content for our /proc entry
701 ** Arguments:
702 ** buf is a pointer to write output to
703 ** adev is the usual pointer to our private struct acx_device
704 ** Returns:
705 ** number of bytes actually written to buf
706 ** Side effects:
707 ** none
709 static int acx_l_proc_output(char *buf, acx_device_t * adev)
711 char *p = buf;
713 FN_ENTER;
715 p += sprintf(p,
716 "acx driver version:\t\t" ACX_RELEASE "\n"
717 "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n"
718 "chip name:\t\t\t%s (0x%08X)\n"
719 "radio type:\t\t\t0x%02X\n"
720 "form factor:\t\t\t0x%02X\n"
721 "EEPROM version:\t\t\t0x%02X\n"
722 "firmware version:\t\t%s (0x%08X)\n",
723 adev->chip_name, adev->firmware_id,
724 adev->radio_type,
725 adev->form_factor,
726 adev->eeprom_version,
727 adev->firmware_version, adev->firmware_numver);
729 FN_EXIT1(p - buf);
730 return p - buf;
734 /***********************************************************************
736 static int acx_s_proc_diag_output(char *buf, acx_device_t * adev)
738 char *p = buf;
739 unsigned long flags;
740 ssize_t len = 0, partlen;
741 u32 temp1, temp2;
742 u8 *st, *st_end;
743 #ifdef __BIG_ENDIAN
744 u8 *st2;
745 #endif
746 fw_stats_t *fw_stats;
747 char *part_str = NULL;
748 fw_stats_tx_t *tx = NULL;
749 fw_stats_rx_t *rx = NULL;
750 fw_stats_dma_t *dma = NULL;
751 fw_stats_irq_t *irq = NULL;
752 fw_stats_wep_t *wep = NULL;
753 fw_stats_pwr_t *pwr = NULL;
754 fw_stats_mic_t *mic = NULL;
755 fw_stats_aes_t *aes = NULL;
756 fw_stats_event_t *evt = NULL;
758 FN_ENTER;
760 acx_lock(adev, flags);
762 if (IS_PCI(adev))
763 p = acxpci_s_proc_diag_output(p, adev);
765 p += sprintf(p,
766 "\n"
767 "** network status **\n"
768 "dev_state_mask 0x%04X\n"
769 "mode %u, channel %u, "
770 "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
771 adev->dev_state_mask,
772 adev->mode, adev->channel,
773 adev->reg_dom_id, adev->reg_dom_chanmask);
774 p += sprintf(p,
775 "ESSID \"%s\", essid_active %d, essid_len %d, "
776 "essid_for_assoc \"%s\", nick \"%s\"\n"
777 "WEP ena %d, restricted %d, idx %d\n",
778 adev->essid, adev->essid_active, (int)adev->essid_len,
779 adev->essid_for_assoc, adev->nick,
780 adev->wep_enabled, adev->wep_restricted,
781 adev->wep_current_index);
782 p += sprintf(p, "dev_addr " MACSTR "\n", MAC(adev->dev_addr));
783 p += sprintf(p, "bssid " MACSTR "\n", MAC(adev->bssid));
784 p += sprintf(p, "ap_filter " MACSTR "\n", MAC(adev->ap));
786 p += sprintf(p, "\n" "** PHY status **\n"
787 "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
788 "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
789 "rate_basic 0x%04X, rate_oper 0x%04X\n"
790 "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
791 "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
792 adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */
793 adev->sensitivity, adev->antenna, adev->ed_threshold,
794 adev->cca, adev->preamble_mode, adev->rate_basic, adev->rate_oper, adev->rts_threshold,
795 adev->frag_threshold, adev->short_retry, adev->long_retry,
796 adev->msdu_lifetime, adev->listen_interval,
797 adev->beacon_interval);
799 acx_unlock(adev, flags);
801 p += sprintf(p,
802 "\n"
803 "** Firmware **\n"
804 "NOTE: version dependent statistics layout, "
805 "please report if you suspect wrong parsing!\n"
806 "\n" "version \"%s\"\n", adev->firmware_version);
808 /* TODO: may replace kmalloc/memset with kzalloc once
809 * Linux 2.6.14 is widespread */
810 fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL);
811 if (!fw_stats) {
812 FN_EXIT1(0);
813 return 0;
815 memset(fw_stats, 0, sizeof(*fw_stats));
817 st = (u8 *) fw_stats;
819 part_str = "statistics query command";
821 if (OK != acx_s_interrogate(adev, st, ACX1xx_REG_FIRMWARE_STATISTICS))
822 goto fw_stats_end;
824 st += sizeof(u16);
825 len = *(u16 *) st;
827 if (len > sizeof(*fw_stats)) {
828 p += sprintf(p,
829 "firmware version with bigger fw_stats struct detected\n"
830 "(%zu vs. %zu), please report\n", len, sizeof(fw_stats_t));
831 if (len > sizeof(*fw_stats)) {
832 p += sprintf(p, "struct size exceeded allocation!\n");
833 len = sizeof(*fw_stats);
836 st += sizeof(u16);
837 st_end = st - 2 * sizeof(u16) + len;
839 #ifdef __BIG_ENDIAN
840 /* let's make one bold assumption here:
841 * (hopefully!) *all* statistics fields are u32 only,
842 * thus if we need to make endianness corrections
843 * we can simply do them in one go, in advance */
844 st2 = (u8 *) fw_stats;
845 for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4)
846 *(u32 *) st2 = le32_to_cpu(*(u32 *) st2);
847 #endif
849 part_str = "Rx/Tx";
851 /* directly at end of a struct part? --> no error! */
852 if (st == st_end)
853 goto fw_stats_end;
855 tx = (fw_stats_tx_t *) st;
856 st += sizeof(fw_stats_tx_t);
857 rx = (fw_stats_rx_t *) st;
858 st += sizeof(fw_stats_rx_t);
859 partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t);
861 if (IS_ACX100(adev)) {
862 /* at least ACX100 PCI F/W 1.9.8.b
863 * and ACX100 USB F/W 1.0.7-USB
864 * don't have those two fields... */
865 st -= 2 * sizeof(u32);
867 /* our parsing doesn't quite match this firmware yet,
868 * log failure */
869 if (st > st_end)
870 goto fw_stats_fail;
871 temp1 = temp2 = 999999999;
872 } else {
873 if (st > st_end)
874 goto fw_stats_fail;
875 temp1 = rx->rx_aci_events;
876 temp2 = rx->rx_aci_resets;
879 p += sprintf(p,
880 "%s:\n"
881 " tx_desc_overfl %u\n"
882 " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
883 " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n"
884 " rx_aci_events %u, rx_aci_resets %u\n",
885 part_str,
886 tx->tx_desc_of,
887 rx->rx_oom,
888 rx->rx_hdr_of,
889 rx->rx_hw_stuck,
890 rx->rx_dropped_frame,
891 rx->rx_frame_ptr_err, rx->rx_xfr_hint_trig, temp1, temp2);
893 part_str = "DMA";
895 if (st == st_end)
896 goto fw_stats_end;
898 dma = (fw_stats_dma_t *) st;
899 partlen = sizeof(fw_stats_dma_t);
900 st += partlen;
902 if (st > st_end)
903 goto fw_stats_fail;
905 p += sprintf(p,
906 "%s:\n"
907 " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n",
908 part_str,
909 dma->rx_dma_req,
910 dma->rx_dma_err, dma->tx_dma_req, dma->tx_dma_err);
912 part_str = "IRQ";
914 if (st == st_end)
915 goto fw_stats_end;
917 irq = (fw_stats_irq_t *) st;
918 partlen = sizeof(fw_stats_irq_t);
919 st += partlen;
921 if (st > st_end)
922 goto fw_stats_fail;
924 p += sprintf(p,
925 "%s:\n"
926 " cmd_cplt %u, fiq %u\n"
927 " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
928 " irqs %u, tx_procs %u, decrypt_done %u\n"
929 " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
930 " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
931 " host_acks %u, pci_pm %u, acm_wakeups %u\n",
932 part_str,
933 irq->cmd_cplt,
934 irq->fiq,
935 irq->rx_hdrs,
936 irq->rx_cmplt,
937 irq->rx_mem_of,
938 irq->rx_rdys,
939 irq->irqs,
940 irq->tx_procs,
941 irq->decrypt_done,
942 irq->dma_0_done,
943 irq->dma_1_done,
944 irq->tx_exch_complet,
945 irq->commands,
946 irq->rx_procs,
947 irq->hw_pm_mode_changes,
948 irq->host_acks, irq->pci_pm, irq->acm_wakeups);
950 part_str = "WEP";
952 if (st == st_end)
953 goto fw_stats_end;
955 wep = (fw_stats_wep_t *) st;
956 partlen = sizeof(fw_stats_wep_t);
957 st += partlen;
959 if (IS_ACX100(adev)) {
960 /* at least ACX100 PCI F/W 1.9.8.b
961 * and ACX100 USB F/W 1.0.7-USB
962 * don't have those two fields... */
963 st -= 2 * sizeof(u32);
964 if (st > st_end)
965 goto fw_stats_fail;
966 temp1 = temp2 = 999999999;
967 } else {
968 if (st > st_end)
969 goto fw_stats_fail;
970 temp1 = wep->wep_pkt_decrypt;
971 temp2 = wep->wep_decrypt_irqs;
974 p += sprintf(p,
975 "%s:\n"
976 " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
977 " wep_key_not_found %u, wep_decrypt_fail %u\n"
978 " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
979 part_str,
980 wep->wep_key_count,
981 wep->wep_default_key_count,
982 wep->dot11_def_key_mib,
983 wep->wep_key_not_found,
984 wep->wep_decrypt_fail, temp1, temp2);
986 part_str = "power";
988 if (st == st_end)
989 goto fw_stats_end;
991 pwr = (fw_stats_pwr_t *) st;
992 partlen = sizeof(fw_stats_pwr_t);
993 st += partlen;
995 if (st > st_end)
996 goto fw_stats_fail;
998 p += sprintf(p,
999 "%s:\n"
1000 " tx_start_ctr %u, no_ps_tx_too_short %u\n"
1001 " rx_start_ctr %u, no_ps_rx_too_short %u\n"
1002 " lppd_started %u\n"
1003 " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n",
1004 part_str,
1005 pwr->tx_start_ctr,
1006 pwr->no_ps_tx_too_short,
1007 pwr->rx_start_ctr,
1008 pwr->no_ps_rx_too_short,
1009 pwr->lppd_started,
1010 pwr->no_lppd_too_noisy,
1011 pwr->no_lppd_too_short, pwr->no_lppd_matching_frame);
1013 part_str = "MIC";
1015 if (st == st_end)
1016 goto fw_stats_end;
1018 mic = (fw_stats_mic_t *) st;
1019 partlen = sizeof(fw_stats_mic_t);
1020 st += partlen;
1022 if (st > st_end)
1023 goto fw_stats_fail;
1025 p += sprintf(p,
1026 "%s:\n"
1027 " mic_rx_pkts %u, mic_calc_fail %u\n",
1028 part_str, mic->mic_rx_pkts, mic->mic_calc_fail);
1030 part_str = "AES";
1032 if (st == st_end)
1033 goto fw_stats_end;
1035 aes = (fw_stats_aes_t *) st;
1036 partlen = sizeof(fw_stats_aes_t);
1037 st += partlen;
1039 if (st > st_end)
1040 goto fw_stats_fail;
1042 p += sprintf(p,
1043 "%s:\n"
1044 " aes_enc_fail %u, aes_dec_fail %u\n"
1045 " aes_enc_pkts %u, aes_dec_pkts %u\n"
1046 " aes_enc_irq %u, aes_dec_irq %u\n",
1047 part_str,
1048 aes->aes_enc_fail,
1049 aes->aes_dec_fail,
1050 aes->aes_enc_pkts,
1051 aes->aes_dec_pkts, aes->aes_enc_irq, aes->aes_dec_irq);
1053 part_str = "event";
1055 if (st == st_end)
1056 goto fw_stats_end;
1058 evt = (fw_stats_event_t *) st;
1059 partlen = sizeof(fw_stats_event_t);
1060 st += partlen;
1062 if (st > st_end)
1063 goto fw_stats_fail;
1065 p += sprintf(p,
1066 "%s:\n"
1067 " heartbeat %u, calibration %u\n"
1068 " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
1069 " oom_late %u\n"
1070 " phy_tx_err %u, tx_stuck %u\n",
1071 part_str,
1072 evt->heartbeat,
1073 evt->calibration,
1074 evt->rx_mismatch,
1075 evt->rx_mem_empty,
1076 evt->rx_pool,
1077 evt->oom_late, evt->phy_tx_err, evt->tx_stuck);
1079 if (st < st_end)
1080 goto fw_stats_bigger;
1082 goto fw_stats_end;
1084 fw_stats_fail:
1085 st -= partlen;
1086 p += sprintf(p,
1087 "failed at %s part (size %zu), offset %zu (struct size %zu), "
1088 "please report\n", part_str, partlen,
1089 ((void *)st - (void *)fw_stats), len);
1091 fw_stats_bigger:
1092 for (; st < st_end; st += 4)
1093 p += sprintf(p,
1094 "UNKN%3d: %u\n",
1095 (int)((void *)st - (void *)fw_stats), *(u32 *) st);
1097 fw_stats_end:
1098 kfree(fw_stats);
1100 FN_EXIT1(p - buf);
1101 return p - buf;
1105 /***********************************************************************
1107 static int acx_s_proc_phy_output(char *buf, acx_device_t * adev)
1109 char *p = buf;
1110 int i;
1112 FN_ENTER;
1115 if (RADIO_RFMD_11 != adev->radio_type) {
1116 printk("sorry, not yet adapted for radio types "
1117 "other than RFMD, please verify "
1118 "PHY size etc. first!\n");
1119 goto end;
1123 /* The PHY area is only 0x80 bytes long; further pages after that
1124 * only have some page number registers with altered value,
1125 * all other registers remain the same. */
1126 for (i = 0; i < 0x80; i++) {
1127 acx_s_read_phy_reg(adev, i, p++);
1130 FN_EXIT1(p - buf);
1131 return p - buf;
1135 /***********************************************************************
1136 ** acx_e_read_proc_XXXX
1137 ** Handle our /proc entry
1139 ** Arguments:
1140 ** standard kernel read_proc interface
1141 ** Returns:
1142 ** number of bytes written to buf
1143 ** Side effects:
1144 ** none
1146 static int
1147 acx_e_read_proc(char *buf, char **start, off_t offset, int count,
1148 int *eof, void *data)
1150 acx_device_t *adev = (acx_device_t *) data;
1151 unsigned long flags;
1152 int length;
1154 FN_ENTER;
1156 acx_sem_lock(adev);
1157 acx_lock(adev, flags);
1158 /* fill buf */
1159 length = acx_l_proc_output(buf, adev);
1160 acx_unlock(adev, flags);
1161 acx_sem_unlock(adev);
1163 /* housekeeping */
1164 if (length <= offset + count)
1165 *eof = 1;
1166 *start = buf + offset;
1167 length -= offset;
1168 if (length > count)
1169 length = count;
1170 if (length < 0)
1171 length = 0;
1172 FN_EXIT1(length);
1173 return length;
1176 static int
1177 acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count,
1178 int *eof, void *data)
1180 acx_device_t *adev = (acx_device_t *) data;
1181 int length;
1183 FN_ENTER;
1185 acx_sem_lock(adev);
1186 /* fill buf */
1187 length = acx_s_proc_diag_output(buf, adev);
1188 acx_sem_unlock(adev);
1190 /* housekeeping */
1191 if (length <= offset + count)
1192 *eof = 1;
1193 *start = buf + offset;
1194 length -= offset;
1195 if (length > count)
1196 length = count;
1197 if (length < 0)
1198 length = 0;
1199 FN_EXIT1(length);
1200 return length;
1203 static int
1204 acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count,
1205 int *eof, void *data)
1207 acx_device_t *adev = (acx_device_t *) data;
1208 int length;
1210 FN_ENTER;
1212 /* fill buf */
1213 length = 0;
1214 if (IS_PCI(adev)) {
1215 acx_sem_lock(adev);
1216 length = acxpci_proc_eeprom_output(buf, adev);
1217 acx_sem_unlock(adev);
1220 /* housekeeping */
1221 if (length <= offset + count)
1222 *eof = 1;
1223 *start = buf + offset;
1224 length -= offset;
1225 if (length > count)
1226 length = count;
1227 if (length < 0)
1228 length = 0;
1229 FN_EXIT1(length);
1230 return length;
1233 static int
1234 acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count,
1235 int *eof, void *data)
1237 acx_device_t *adev = (acx_device_t *) data;
1238 int length;
1240 FN_ENTER;
1242 acx_sem_lock(adev);
1243 /* fill buf */
1244 length = acx_s_proc_phy_output(buf, adev);
1245 acx_sem_unlock(adev);
1247 /* housekeeping */
1248 if (length <= offset + count)
1249 *eof = 1;
1250 *start = buf + offset;
1251 length -= offset;
1252 if (length > count)
1253 length = count;
1254 if (length < 0)
1255 length = 0;
1256 FN_EXIT1(length);
1257 return length;
1261 /***********************************************************************
1262 ** /proc files registration
1264 static const char *const
1265 proc_files[] = { "", "_diag", "_eeprom", "_phy" };
1267 static read_proc_t *const
1268 proc_funcs[] = {
1269 acx_e_read_proc,
1270 acx_e_read_proc_diag,
1271 acx_e_read_proc_eeprom,
1272 acx_e_read_proc_phy
1275 static int manage_proc_entries(struct ieee80211_hw *hw, int remove)
1277 acx_device_t *adev = ieee2adev(hw);
1278 char procbuf[80];
1279 int i;
1281 FN_ENTER;
1283 for (i = 0; i < ARRAY_SIZE(proc_files); i++) {
1284 snprintf(procbuf, sizeof(procbuf),
1285 "driver/acx%s", proc_files[i]);
1286 acx_log(LOG_INFO, L_INIT, "%sing /proc entry %s\n",
1287 remove ? "remov" : "creat", procbuf);
1288 if (!remove) {
1289 if (!create_proc_read_entry
1290 (procbuf, 0, NULL, proc_funcs[i], adev)) {
1291 acx_log(LOG_WARNING, L_ANY,
1292 "cannot register /proc entry %s\n", procbuf);
1293 FN_EXIT1(NOT_OK);
1294 return NOT_OK;
1296 } else {
1297 remove_proc_entry(procbuf, NULL);
1300 FN_EXIT0;
1301 return OK;
1304 int acx_proc_register_entries(struct ieee80211_hw *ieee)
1306 return manage_proc_entries(ieee, 0);
1309 int acx_proc_unregister_entries(struct ieee80211_hw *ieee)
1311 return manage_proc_entries(ieee, 1);
1313 #endif /* CONFIG_PROC_FS */
1315 /****
1316 ** Gathered From rt2x00 and bcm43xx_mac80211 projects
1318 void acx_free_modes(acx_device_t * adev)
1321 // kfree(adev->modes);
1322 // adev->modes = NULL;
1326 #define RATETAB_ENT(_rate, _rateid, _flags) \
1328 .rate = (_rate), \
1329 .val = (_rateid), \
1330 .val2 = (_rateid), \
1331 .flags = (_flags), \
1335 static struct ieee80211_rate __acx_rates[] = {
1336 { .rate = 10,
1337 .val = RATE111_1,
1338 .flags = IEEE80211_RATE_CCK },
1339 { .rate = 20,
1340 .val = RATE111_2,
1341 .flags = IEEE80211_RATE_CCK },
1342 { .rate = 55,
1343 .val = RATE111_5,
1344 .flags = IEEE80211_RATE_CCK },
1345 { .rate = 110,
1346 .val = RATE111_11,
1347 .flags = IEEE80211_RATE_CCK },
1348 { .rate = 60,
1349 .val = RATE111_6,
1350 .flags = IEEE80211_RATE_OFDM },
1351 { .rate = 90,
1352 .val = RATE111_9,
1353 .flags = IEEE80211_RATE_OFDM },
1354 { .rate = 120,
1355 .val = RATE111_12,
1356 .flags = IEEE80211_RATE_OFDM },
1357 { .rate = 180,
1358 .val = RATE111_18,
1359 .flags = IEEE80211_RATE_OFDM },
1360 { .rate = 240,
1361 .val = RATE111_24,
1362 .flags = IEEE80211_RATE_OFDM },
1363 { .rate = 360,
1364 .val = RATE111_36,
1365 .flags = IEEE80211_RATE_OFDM },
1366 { .rate = 480,
1367 .val = RATE111_48,
1368 .flags = IEEE80211_RATE_OFDM },
1369 { .rate = 540,
1370 .val = RATE111_54,
1371 .flags = IEEE80211_RATE_OFDM },
1374 static struct ieee80211_channel channels[] = {
1375 { .chan = 1,
1376 .freq = 2412},
1377 { .chan = 2,
1378 .freq = 2417},
1379 { .chan = 3,
1380 .freq = 2422},
1381 { .chan = 4,
1382 .freq = 2427},
1383 { .chan = 5,
1384 .freq = 2432},
1385 { .chan = 6,
1386 .freq = 2437},
1387 { .chan = 7,
1388 .freq = 2442},
1389 { .chan = 8,
1390 .freq = 2447},
1391 { .chan = 9,
1392 .freq = 2452},
1393 { .chan = 10,
1394 .freq = 2457},
1395 { .chan = 11,
1396 .freq = 2462},
1397 { .chan = 12,
1398 .freq = 2467},
1399 { .chan = 13,
1400 .freq = 2472},
1403 int acx_setup_modes(acx_device_t * adev)
1405 struct ieee80211_hw *hw = adev->ieee;
1406 struct ieee80211_hw_mode *mode;
1407 int err = -ENOMEM;
1409 FN_ENTER;
1411 if (IS_ACX111(adev)) {
1413 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);
1414 err = acx_setup_modes_gphy(adev);
1416 mode = &adev->modes[0];
1418 /* from the zd1211rw driver: - do we need to do the same? */
1420 memcpy(mode->channels, channels, sizeof(channels));
1421 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1424 mode->mode = MODE_IEEE80211G;
1425 mode->num_channels = ARRAY_SIZE(channels);
1426 mode->num_rates = 12;
1427 mode->rates = __acx_rates;
1428 } else {
1430 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1431 err = acx_setup_modes_bphy(adev);
1433 mode = &adev->modes[1];
1435 /* from the zd1211rw driver: - do we need to do the same? */
1437 memcpy(mode->channels, channels, sizeof(channels));
1438 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1441 mode->mode = MODE_IEEE80211B;
1442 mode->num_channels = ARRAY_SIZE(channels);
1443 mode->num_rates = 4;
1444 mode->rates = __acx_rates;
1447 /* if (err && adev->modes)
1448 kfree(adev->modes);*/
1450 mode->channels = channels;
1451 err = ieee80211_register_hwmode(hw, mode);
1453 FN_EXIT1(err);
1454 return err;
1458 /***********************************************************************
1459 ** acx_fill_beacon_or_proberesp_template
1461 ** Origin: derived from rt2x00 project
1463 static int
1464 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1465 struct acx_template_beacon *templ,
1466 struct sk_buff* skb /* in host order! */)
1468 FN_ENTER;
1470 memcpy(templ,skb->data, skb->len);
1471 FN_EXIT1(skb->len);
1472 return skb->len;
1475 /***********************************************************************
1476 ** acx_s_set_beacon_template
1480 static int
1481 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1483 struct acx_template_beacon bcn;
1484 int len, result;
1486 FN_ENTER;
1487 acx_log(LOG_INFO, L_ANY, "size of template: %08zX, "
1488 "size of beacon: %08X\n",
1489 sizeof(struct acx_template_beacon),skb->len);
1490 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1491 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1493 FN_EXIT1(result);
1494 return result;
1497 /***********************************************************************
1498 ** acx_cmd_join_bssid
1500 ** Common code for both acx100 and acx111.
1502 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1503 static const u8 bitpos2genframe_txrate[] = {
1504 10, /* 0. 1 Mbit/s */
1505 20, /* 1. 2 Mbit/s */
1506 55, /* 2. 5.5 Mbit/s */
1507 0x0B, /* 3. 6 Mbit/s */
1508 0x0F, /* 4. 9 Mbit/s */
1509 110, /* 5. 11 Mbit/s */
1510 0x0A, /* 6. 12 Mbit/s */
1511 0x0E, /* 7. 18 Mbit/s */
1512 220, /* 8. 22 Mbit/s */
1513 0x09, /* 9. 24 Mbit/s */
1514 0x0D, /* 10. 36 Mbit/s */
1515 0x08, /* 11. 48 Mbit/s */
1516 0x0C, /* 12. 54 Mbit/s */
1517 10, /* 13. 1 Mbit/s, should never happen */
1518 10, /* 14. 1 Mbit/s, should never happen */
1519 10, /* 15. 1 Mbit/s, should never happen */
1522 /* Looks scary, eh?
1523 ** Actually, each one compiled into one AND and one SHIFT,
1524 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1525 static inline unsigned int rate111to5bits(unsigned int rate)
1527 return (rate & 0x7)
1528 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1529 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1533 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1535 acx_joinbss_t tmp;
1536 int dtim_interval;
1537 int i;
1539 if (mac_is_zero(bssid))
1540 return;
1542 FN_ENTER;
1544 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1545 1 : adev->dtim_interval;
1547 memset(&tmp, 0, sizeof(tmp));
1549 for (i = 0; i < ETH_ALEN; i++) {
1550 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1553 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1555 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1556 ** are sent with one of these rates */
1557 if (IS_ACX111(adev)) {
1558 /* It was experimentally determined that rates_basic
1559 ** can take 11g rates as well, not only rates
1560 ** defined with JOINBSS_RATES_BASIC111_nnn.
1561 ** Just use RATE111_nnn constants... */
1562 tmp.u.acx111.dtim_interval = dtim_interval;
1563 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1564 acx_log(LOG_INFO, L_ASSOC, "rates_basic:%04X, "
1565 "rates_supported:%04X\n",
1566 adev->rate_basic, adev->rate_oper);
1567 } else {
1568 tmp.u.acx100.dtim_interval = dtim_interval;
1569 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1570 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1571 acx_log(LOG_INFO, L_ASSOC, "rates_basic:%04X->%02X, "
1572 "rates_supported:%04X->%02X\n",
1573 adev->rate_basic, tmp.u.acx100.rates_basic,
1574 adev->rate_oper, tmp.u.acx100.rates_supported);
1577 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1578 ** will be sent (rate/modulation/preamble) */
1579 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1580 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1581 /* we can use short pre *if* all peers can understand it */
1582 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1584 /* we switch fw to STA mode in MONITOR mode, it seems to be
1585 ** the only mode where fw does not emit beacons by itself
1586 ** but allows us to send anything (we really want to retain
1587 ** ability to tx arbitrary frames in MONITOR mode)
1589 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1590 tmp.channel = adev->channel;
1591 tmp.essid_len = adev->essid_len;
1593 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1594 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1596 acx_log(LOG_DEBUG, L_ASSOC, "BSS_Type = %u\n", tmp.macmode);
1597 acx_log(LOG_DEBUG, L_ASSOC, "JoinBSSID MAC:" MACSTR "\n",
1598 adev->bssid, "\n");
1600 /* acx_update_capabilities(adev); */
1601 FN_EXIT0;
1604 /***********************************************************************
1605 ** acxpci_i_set_multicast_list
1606 ** FIXME: most likely needs refinement
1609 void acx_i_set_multicast_list(struct ieee80211_hw *hw,
1610 unsigned int changed_flags,
1611 unsigned int *total_flags,
1612 int mc_count, struct dev_addr_list *mc_list)
1614 acx_device_t *adev = ieee2adev(hw);
1615 unsigned long flags;
1617 FN_ENTER;
1619 acx_lock(adev, flags);
1621 changed_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1622 FIF_CONTROL | FIF_OTHER_BSS);
1623 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1624 FIF_CONTROL | FIF_OTHER_BSS);
1625 /* if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1626 return; */
1628 if (*total_flags) {
1629 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1630 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1631 SET_BIT(adev->set_mask, SET_RXCONFIG);
1632 /* let kernel know in case *we* needed to set promiscuous */
1633 } else {
1634 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1635 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1636 SET_BIT(adev->set_mask, SET_RXCONFIG);
1639 /* cannot update card settings directly here, atomic context */
1640 acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
1642 acx_unlock(adev, flags);
1644 FN_EXIT0;
1647 /***********************************************************************
1648 ** acx111 feature config
1650 ** Obvious
1652 static int
1653 acx111_s_get_feature_config(acx_device_t * adev,
1654 u32 * feature_options, u32 * data_flow_options)
1656 struct acx111_ie_feature_config feat;
1658 FN_ENTER;
1660 if (!IS_ACX111(adev)) {
1661 return NOT_OK;
1664 memset(&feat, 0, sizeof(feat));
1666 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_REG_FEATURE_CONFIG)) {
1667 FN_EXIT1(NOT_OK);
1668 return NOT_OK;
1670 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
1671 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1672 feat.feature_options, feat.data_flow_options);
1674 if (feature_options)
1675 *feature_options = le32_to_cpu(feat.feature_options);
1676 if (data_flow_options)
1677 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1679 FN_EXIT0;
1680 return OK;
1684 static int
1685 acx111_s_set_feature_config(acx_device_t * adev,
1686 u32 feature_options, u32 data_flow_options,
1687 unsigned int mode
1688 /* 0 == remove, 1 == add, 2 == set */ )
1690 struct acx111_ie_feature_config feat;
1692 FN_ENTER;
1694 if (!IS_ACX111(adev)) {
1695 FN_EXIT1(NOT_OK);
1696 return NOT_OK;
1699 if ((mode < 0) || (mode > 2)) {
1700 FN_EXIT1(NOT_OK);
1701 return NOT_OK;
1704 if (mode != 2)
1705 /* need to modify old data */
1706 acx111_s_get_feature_config(adev, &feat.feature_options,
1707 &feat.data_flow_options);
1708 else {
1709 /* need to set a completely new value */
1710 feat.feature_options = 0;
1711 feat.data_flow_options = 0;
1714 if (mode == 0) { /* remove */
1715 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1716 CLEAR_BIT(feat.data_flow_options,
1717 cpu_to_le32(data_flow_options));
1718 } else { /* add or set */
1719 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1720 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1723 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
1724 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1725 "new: feature 0x%08X dataflow 0x%08X\n",
1726 feature_options, data_flow_options, mode,
1727 le32_to_cpu(feat.feature_options),
1728 le32_to_cpu(feat.data_flow_options));
1730 if (OK != acx_s_configure(adev, &feat, ACX1xx_REG_FEATURE_CONFIG)) {
1731 FN_EXIT1(NOT_OK);
1732 return NOT_OK;
1735 FN_EXIT0;
1736 return OK;
1739 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1741 return acx111_s_set_feature_config(adev, f, d, 0);
1743 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1745 return acx111_s_set_feature_config(adev, f, d, 1);
1747 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1749 return acx111_s_set_feature_config(adev, f, d, 2);
1753 /***********************************************************************
1754 ** acx100_s_init_memory_pools
1756 static int
1757 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1759 acx100_ie_memblocksize_t MemoryBlockSize;
1760 acx100_ie_memconfigoption_t MemoryConfigOption;
1761 int TotalMemoryBlocks;
1762 int RxBlockNum;
1763 int TotalRxBlockSize;
1764 int TxBlockNum;
1765 int TotalTxBlockSize;
1767 FN_ENTER;
1769 /* Let's see if we can follow this:
1770 first we select our memory block size (which I think is
1771 completely arbitrary) */
1772 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1774 /* Then we alert the card to our decision of block size */
1775 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_REG_BLOCK_SIZE)) {
1776 goto bad;
1779 /* We figure out how many total blocks we can create, using
1780 the block size we chose, and the beginning and ending
1781 memory pointers, i.e.: end-start/size */
1782 TotalMemoryBlocks =
1783 (le32_to_cpu(mmt->PoolEnd) -
1784 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1786 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "TotalMemoryBlocks=%u (%u bytes)\n",
1787 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1789 /* MemoryConfigOption.DMA_config bitmask:
1790 access to ACX memory is to be done:
1791 0x00080000 using PCI conf space?!
1792 0x00040000 using IO instructions?
1793 0x00000000 using memory access instructions
1794 0x00020000 using local memory block linked list (else what?)
1795 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1797 if (IS_PCI(adev)) {
1798 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1799 /* Declare start of the Rx host pool */
1800 MemoryConfigOption.pRxHostDesc =
1801 cpu2acx(adev->rxhostdesc_startphy);
1802 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "pRxHostDesc 0x%08X, "
1803 "rxhostdesc_startphy 0x%lX\n",
1804 acx2cpu(MemoryConfigOption.pRxHostDesc),
1805 (long)adev->rxhostdesc_startphy);
1806 } else {
1807 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1810 /* 50% of the allotment of memory blocks go to tx descriptors */
1811 TxBlockNum = TotalMemoryBlocks / 2;
1812 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1814 /* and 50% go to the rx descriptors */
1815 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1816 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1818 /* size of the tx and rx descriptor queues */
1819 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1820 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1821 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "TxBlockNum %u RxBlockNum %u "
1822 "TotalTxBlockSize %u TotalTxBlockSize %u\n",
1823 TxBlockNum, RxBlockNum, TotalTxBlockSize, TotalRxBlockSize);
1826 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1827 MemoryConfigOption.rx_mem =
1828 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1830 /* align the rx descriptor queue to units of 0x20
1831 * and offset it by the tx descriptor queue */
1832 MemoryConfigOption.tx_mem =
1833 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
1834 0x1f) & ~0x1f);
1835 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "rx_mem %08X rx_mem %08X\n",
1836 MemoryConfigOption.tx_mem, MemoryConfigOption.rx_mem);
1838 /* alert the device to our decision */
1839 if (OK !=
1840 acx_s_configure(adev, &MemoryConfigOption,
1841 ACX1xx_REG_MEMORY_CONFIG_OPTIONS)) {
1842 goto bad;
1845 /* and tell the device to kick it into gear */
1846 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
1847 goto bad;
1849 FN_EXIT1(OK);
1850 return OK;
1851 bad:
1852 FN_EXIT1(NOT_OK);
1853 return NOT_OK;
1857 /***********************************************************************
1858 ** acx100_s_create_dma_regions
1860 ** Note that this fn messes up heavily with hardware, but we cannot
1861 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1863 /* OLD CODE? - let's rewrite it! */
1864 static int acx100_s_create_dma_regions(acx_device_t * adev)
1866 acx100_ie_queueconfig_t queueconf;
1867 acx_ie_memmap_t memmap;
1868 int res = NOT_OK;
1869 u32 tx_queue_start, rx_queue_start;
1871 FN_ENTER;
1873 /* read out the acx100 physical start address for the queues */
1874 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_REG_MEMORY_MAP)) {
1875 goto fail;
1878 tx_queue_start = le32_to_cpu(memmap.QueueStart);
1879 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
1881 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "initializing Queue Indicator\n");
1883 memset(&queueconf, 0, sizeof(queueconf));
1885 /* Not needed for PCI, so we can avoid setting them altogether */
1886 if (IS_USB(adev)) {
1887 queueconf.NumTxDesc = USB_TX_CNT;
1888 queueconf.NumRxDesc = USB_RX_CNT;
1891 /* calculate size of queues */
1892 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
1893 RX_CNT * sizeof(rxdesc_t) + 8);
1894 queueconf.NumTxQueues = 1; /* number of tx queues */
1895 /* sets the beginning of the tx descriptor queue */
1896 queueconf.TxQueueStart = memmap.QueueStart;
1897 /* done by memset: queueconf.TxQueuePri = 0; */
1898 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
1899 queueconf.QueueOptions = 1; /* auto reset descriptor */
1900 /* sets the end of the rx descriptor queue */
1901 queueconf.QueueEnd =
1902 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
1904 /* sets the beginning of the next queue */
1905 queueconf.HostQueueEnd =
1906 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
1907 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_REG_QUEUE_CONFIG)) {
1908 goto fail;
1911 if (IS_PCI(adev)) {
1912 /* sets the beginning of the rx descriptor queue, after the tx descrs */
1913 if (OK != acxpci_s_create_hostdesc_queues(adev))
1914 goto fail;
1915 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
1918 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_REG_MEMORY_MAP)) {
1919 goto fail;
1922 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
1923 0x1f) & ~0x1f);
1925 if (OK != acx_s_configure(adev, &memmap, ACX1xx_REG_MEMORY_MAP)) {
1926 goto fail;
1929 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
1930 goto fail;
1933 res = OK;
1934 goto end;
1936 fail:
1937 acx_s_mwait(1000); /* ? */
1938 if (IS_PCI(adev))
1939 acxpci_free_desc_queues(adev);
1940 end:
1941 FN_EXIT1(res);
1942 return res;
1946 /***********************************************************************
1947 ** acx111_s_create_dma_regions
1949 ** Note that this fn messes heavily with hardware, but we cannot
1950 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1952 #define ACX111_PERCENT(percent) ((percent)/5)
1954 static int acx111_s_create_dma_regions(acx_device_t * adev)
1956 struct acx111_ie_memoryconfig memconf;
1957 struct acx111_ie_queueconfig queueconf;
1958 u32 tx_queue_start, rx_queue_start;
1960 FN_ENTER;
1962 /* Calculate memory positions and queue sizes */
1964 /* Set up our host descriptor pool + data pool */
1965 if (IS_PCI(adev)) {
1966 if (OK != acxpci_s_create_hostdesc_queues(adev))
1967 goto fail;
1970 memset(&memconf, 0, sizeof(memconf));
1971 /* the number of STAs (STA contexts) to support
1972 ** NB: was set to 1 and everything seemed to work nevertheless... */
1973 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
1974 /* specify the memory block size. Default is 256 */
1975 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
1976 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
1977 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
1978 /* set the count of our queues
1979 ** NB: struct acx111_ie_memoryconfig shall be modified
1980 ** if we ever will switch to more than one rx and/or tx queue */
1981 memconf.count_rx_queues = 1;
1982 memconf.count_tx_queues = 1;
1983 /* 0 == Busmaster Indirect Memory Organization, which is what we want
1984 * (using linked host descs with their allocated mem).
1985 * 2 == Generic Bus Slave */
1986 /* done by memset: memconf.options = 0; */
1987 /* let's use 25% for fragmentations and 75% for frame transfers
1988 * (specified in units of 5%) */
1989 memconf.fragmentation = ACX111_PERCENT(75);
1990 /* Rx descriptor queue config */
1991 memconf.rx_queue1_count_descs = RX_CNT;
1992 memconf.rx_queue1_type = 7; /* must be set to 7 */
1993 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
1994 if (IS_PCI(adev)) {
1995 memconf.rx_queue1_host_rx_start =
1996 cpu2acx(adev->rxhostdesc_startphy);
1998 /* Tx descriptor queue config */
1999 memconf.tx_queue1_count_descs = TX_CNT;
2000 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2002 /* NB1: this looks wrong: (memconf,ACX1xx_REG_QUEUE_CONFIG),
2003 ** (queueconf,ACX1xx_REG_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2004 ** But it is actually correct wrt IE numbers.
2005 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_REG_QUEUE_CONFIG)
2006 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2007 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2008 if (OK != acx_s_configure(adev, &memconf, ACX1xx_REG_QUEUE_CONFIG)) {
2009 goto fail;
2012 acx_s_interrogate(adev, &queueconf, ACX1xx_REG_MEMORY_CONFIG_OPTIONS);
2014 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2015 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2017 acx_log(LOG_DEBUG, L_INIT, "dump queue head (from card):\n"
2018 "len: %u\n"
2019 "tx_memory_block_address: %X\n"
2020 "rx_memory_block_address: %X\n"
2021 "tx1_queue address: %X\n"
2022 "rx1_queue address: %X\n",
2023 le16_to_cpu(queueconf.len),
2024 le32_to_cpu(queueconf.tx_memory_block_address),
2025 le32_to_cpu(queueconf.rx_memory_block_address),
2026 tx_queue_start, rx_queue_start);
2028 if (IS_PCI(adev))
2029 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2031 FN_EXIT1(OK);
2032 return OK;
2033 fail:
2034 if (IS_PCI(adev))
2035 acxpci_free_desc_queues(adev);
2037 FN_EXIT1(NOT_OK);
2038 return NOT_OK;
2042 /***********************************************************************
2044 static void acx_s_initialize_rx_config(acx_device_t * adev)
2046 struct {
2047 u16 id;
2048 u16 len;
2049 u16 rx_cfg1;
2050 u16 rx_cfg2;
2051 } __attribute__ ((packed)) cfg;
2052 switch (adev->mode) {
2053 case ACX_MODE_MONITOR:
2054 adev->rx_config_1 = (u16) (0
2055 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2056 /* | RX_CFG1_FILTER_SSID */
2057 /* | RX_CFG1_FILTER_BCAST */
2058 /* | RX_CFG1_RCV_MC_ADDR1 */
2059 /* | RX_CFG1_RCV_MC_ADDR0 */
2060 /* | RX_CFG1_FILTER_ALL_MULTI */
2061 /* | RX_CFG1_FILTER_BSSID */
2062 /* | RX_CFG1_FILTER_MAC */
2063 | RX_CFG1_RCV_PROMISCUOUS
2064 | RX_CFG1_INCLUDE_FCS
2065 /* | RX_CFG1_INCLUDE_PHY_HDR */
2067 adev->rx_config_2 = (u16) (0
2068 | RX_CFG2_RCV_ASSOC_REQ
2069 | RX_CFG2_RCV_AUTH_FRAMES
2070 | RX_CFG2_RCV_BEACON_FRAMES
2071 | RX_CFG2_RCV_CONTENTION_FREE
2072 | RX_CFG2_RCV_CTRL_FRAMES
2073 | RX_CFG2_RCV_DATA_FRAMES
2074 | RX_CFG2_RCV_BROKEN_FRAMES
2075 | RX_CFG2_RCV_MGMT_FRAMES
2076 | RX_CFG2_RCV_PROBE_REQ
2077 | RX_CFG2_RCV_PROBE_RESP
2078 | RX_CFG2_RCV_ACK_FRAMES
2079 | RX_CFG2_RCV_OTHER);
2080 break;
2081 default:
2082 adev->rx_config_1 = (u16) (0
2083 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2084 /* | RX_CFG1_FILTER_SSID */
2085 /* | RX_CFG1_FILTER_BCAST */
2086 /* | RX_CFG1_RCV_MC_ADDR1 */
2087 /* | RX_CFG1_RCV_MC_ADDR0 */
2088 /* | RX_CFG1_FILTER_ALL_MULTI */
2089 /* | RX_CFG1_FILTER_BSSID */
2090 /* | RX_CFG1_FILTER_MAC */
2091 | RX_CFG1_RCV_PROMISCUOUS
2092 /* | RX_CFG1_INCLUDE_FCS */
2093 /* | RX_CFG1_INCLUDE_PHY_HDR */
2095 adev->rx_config_2 = (u16) (0
2096 | RX_CFG2_RCV_ASSOC_REQ
2097 | RX_CFG2_RCV_AUTH_FRAMES
2098 | RX_CFG2_RCV_BEACON_FRAMES
2099 | RX_CFG2_RCV_CONTENTION_FREE
2100 | RX_CFG2_RCV_CTRL_FRAMES
2101 | RX_CFG2_RCV_DATA_FRAMES
2102 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2103 | RX_CFG2_RCV_MGMT_FRAMES
2104 | RX_CFG2_RCV_PROBE_REQ
2105 | RX_CFG2_RCV_PROBE_RESP
2106 | RX_CFG2_RCV_ACK_FRAMES
2107 | RX_CFG2_RCV_OTHER);
2108 break;
2110 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2112 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2113 || (adev->firmware_numver >= 0x02000000))
2114 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2115 else
2116 adev->phy_header_len = 0;
2118 acx_log(LOG_DEBUG, L_INIT, "setting RXconfig to %04X:%04X\n",
2119 adev->rx_config_1, adev->rx_config_2);
2121 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2122 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2123 acx_s_configure(adev, &cfg, ACX1xx_REG_RXCONFIG);
2127 /***********************************************************************
2128 ** FIXME: this should be solved in a general way for all radio types
2129 ** by decoding the radio firmware module,
2130 ** since it probably has some standard structure describing how to
2131 ** set the power level of the radio module which it controls.
2132 ** Or maybe not, since the radio module probably has a function interface
2133 ** instead which then manages Tx level programming :-\
2135 ** Obvious
2137 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2139 struct acx111_ie_tx_level tx_level;
2141 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2142 * 1 (30mW) [15dBm]
2143 * 2 (10mW) [10dBm]
2144 * For now, just assume all other acx111 cards have the same.
2145 * FIXME: Ideally we would query it here, but we first need a
2146 * standard way to query individual configoptions easily.
2147 * Well, now we have proper cfgopt txpower variables, but this still
2148 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2149 if (level_dbm <= 12) {
2150 tx_level.level = 2; /* 10 dBm */
2151 adev->tx_level_dbm = 10;
2152 } else {
2153 tx_level.level = 1; /* 15 dBm */
2154 adev->tx_level_dbm = 15;
2156 if (level_dbm != adev->tx_level_dbm)
2157 acx_log(LOG_WARNING, L_INIT, "only predefined transmission "
2158 "power levels are supported at this time: "
2159 "adjusted %d dBm to %d dBm\n", level_dbm,
2160 adev->tx_level_dbm);
2162 return acx_s_configure(adev, &tx_level, ACX1xx_REG_DOT11_TX_POWER_LEVEL);
2165 static int acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
2167 if (IS_ACX111(adev)) {
2168 return acx111_s_set_tx_level(adev, level_dbm);
2170 if (IS_PCI(adev)) {
2171 return acx100pci_s_set_tx_level(adev, level_dbm);
2174 return OK;
2178 /***********************************************************************
2179 ** acx_s_set_defaults
2181 void acx_s_set_defaults(acx_device_t * adev)
2183 struct ieee80211_conf *conf = &adev->ieee->conf;
2184 unsigned long flags;
2185 u16 default_irq_mask = (IS_ACX111(adev)) ?
2186 ACX111_DEFAULT_IRQ_MASK :
2187 ACX100_DEFAULT_IRQ_MASK;
2189 FN_ENTER;
2191 acx_lock(adev, flags);
2192 /* do it before getting settings, prevent bogus channel 0 warning */
2193 adev->channel = 1;
2195 /* query some settings from the card.
2196 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2197 * query is REQUIRED, otherwise the card won't work correctly! */
2198 adev->get_mask =
2199 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2200 GETSET_REG_DOMAIN;
2201 /* Only ACX100 supports ED and CCA */
2202 if (IS_ACX100(adev))
2203 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2205 acx_unlock(adev, flags);
2207 acx_s_update_card_settings(adev);
2209 acx_lock(adev, flags);
2211 /* set our global interrupt mask */
2212 if (IS_PCI(adev))
2213 adev->irq_mask = default_irq_mask;
2215 adev->led_power = 1; /* LED is active on startup */
2216 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2217 adev->brange_time_last_state_change = jiffies;
2219 /* copy the MAC address we just got from the card
2220 * into our MAC address used during current 802.11 session */
2221 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
2222 MAC_BCAST(adev->ap);
2224 adev->essid_len =
2225 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2226 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2227 adev->essid_active = 1;
2229 /* we have a nick field to waste, so why not abuse it
2230 * to announce the driver version? ;-) */
2231 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2233 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2234 /* first regulatory domain entry in EEPROM == default reg. domain */
2235 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2238 /* 0xffff would be better, but then we won't get a "scan complete"
2239 * interrupt, so our current infrastructure will fail: */
2240 adev->scan_count = 1;
2241 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2242 adev->scan_duration = 100;
2243 adev->scan_probe_delay = 200;
2244 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2245 adev->scan_rate = ACX_SCAN_RATE_1;
2248 adev->mode = ACX_MODE_2_STA;
2249 adev->listen_interval = 100;
2250 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2251 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2253 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2255 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2256 adev->frag_threshold = 2346;
2258 /* use standard default values for retry limits */
2259 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2260 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2262 adev->preamble_mode = 2; /* auto */
2263 adev->fallback_threshold = 3;
2264 adev->stepup_threshold = 10;
2265 adev->rate_bcast = RATE111_1;
2266 adev->rate_bcast100 = RATE100_1;
2267 adev->rate_basic = RATE111_1 | RATE111_2;
2268 adev->rate_auto = 1;
2269 if (IS_ACX111(adev)) {
2270 adev->rate_oper = RATE111_ALL;
2271 } else {
2272 adev->rate_oper = RATE111_ACX100_COMPAT;
2275 /* Supported Rates element - the rates here are given in units of
2276 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2277 acx_l_update_ratevector(adev);
2279 /* set some more defaults */
2280 if (IS_ACX111(adev)) {
2281 /* 30mW (15dBm) is default, at least in my acx111 card: */
2282 adev->tx_level_dbm = 15;
2283 conf->power_level = adev->tx_level_dbm;
2284 acx_unlock(adev, flags);
2285 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2286 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2287 acx_lock(adev, flags);
2288 } else {
2289 /* don't use max. level, since it might be dangerous
2290 * (e.g. WRT54G people experience
2291 * excessive Tx power damage!) */
2292 adev->tx_level_dbm = 18;
2293 conf->power_level = adev->tx_level_dbm;
2294 acx_unlock(adev, flags);
2295 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2296 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2297 acx_lock(adev, flags);
2300 /* adev->tx_level_auto = 1; */
2301 if (IS_ACX111(adev)) {
2302 /* start with sensitivity level 1 out of 3: */
2303 adev->sensitivity = 1;
2306 /* #define ENABLE_POWER_SAVE */
2307 #ifdef ENABLE_POWER_SAVE
2308 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2309 adev->ps_listen_interval = 1;
2310 adev->ps_options =
2311 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2312 adev->ps_hangover_period = 30;
2313 adev->ps_enhanced_transition_time = 0;
2314 #else
2315 adev->ps_wakeup_cfg = 0;
2316 adev->ps_listen_interval = 0;
2317 adev->ps_options = 0;
2318 adev->ps_hangover_period = 0;
2319 adev->ps_enhanced_transition_time = 0;
2320 #endif
2322 /* These settings will be set in fw on ifup */
2323 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2324 /* configure card to do rate fallback when in auto rate mode */
2325 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2326 /* better re-init the antenna value we got above */
2327 | GETSET_ANTENNA
2328 #if POWER_SAVE_80211
2329 | GETSET_POWER_80211
2330 #endif
2333 acx_unlock(adev, flags);
2334 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2336 acx_s_initialize_rx_config(adev);
2338 FN_EXIT0;
2342 /***********************************************************************
2343 ** acx_l_process_rxbuf
2345 ** NB: used by USB code also
2347 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2349 struct ieee80211_hdr *hdr;
2350 u16 fc, buf_len;
2352 FN_ENTER;
2354 hdr = acx_get_wlan_hdr(adev, rxbuf);
2355 fc = le16_to_cpu(hdr->frame_control);
2356 /* length of frame from control field to first byte of FCS */
2357 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2359 acx_log_dump(LOG_DEBUG, L_XFER | L_DATA, hdr, buf_len,
2360 "rx: 802.11 buffer:\n");
2362 acx_l_rx(adev, rxbuf);
2363 /* Now check Rx quality level, AFTER processing packet.
2364 * I tried to figure out how to map these levels to dBm
2365 * values, but for the life of me I really didn't
2366 * manage to get it. Either these values are not meant to
2367 * be expressed in dBm, or it's some pretty complicated
2368 * calculation. */
2370 /* TODO: only the RSSI seems to be reported */
2371 adev->rx_status.ssi = acx_signal_to_winlevel(rxbuf->phy_level);
2373 FN_EXIT0;
2377 /***********************************************************************
2378 ** acx_l_handle_txrate_auto
2380 ** Theory of operation:
2381 ** client->rate_cap is a bitmask of rates client is capable of.
2382 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2383 ** It is set as a result of iwconfig rate N [auto]
2384 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2385 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2386 ** auto (0x00ff == 18Mbit or any lower value),
2387 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2389 ** client->rate_cur is a value for rate111 field in tx descriptor.
2390 ** It is always set to txrate_cfg sans zero or more most significant
2391 ** bits. This routine handles selection of new rate_cur value depending on
2392 ** outcome of last tx event.
2394 ** client->rate_100 is a precalculated rate value for acx100
2395 ** (we can do without it, but will need to calculate it on each tx).
2397 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2398 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2399 ** In theory you can implement it, but so far it is considered not worth doing.
2401 ** 22Mbit, of course, is PBCC always. */
2403 /* maps acx100 tx descr rate field to acx111 one */
2405 static u16 rate100to111(u8 r)
2407 switch (r) {
2408 case RATE100_1:
2409 return RATE111_1;
2410 case RATE100_2:
2411 return RATE111_2;
2412 case RATE100_5:
2413 case (RATE100_5 | RATE100_PBCC511):
2414 return RATE111_5;
2415 case RATE100_11:
2416 case (RATE100_11 | RATE100_PBCC511):
2417 return RATE111_11;
2418 case RATE100_22:
2419 return RATE111_22;
2420 default:
2421 printk("acx: unexpected acx100 txrate: %u! "
2422 "Please report\n", r);
2423 return RATE111_1;
2430 acx_i_start_xmit(struct ieee80211_hw *hw,
2431 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2433 acx_device_t *adev = ieee2adev(hw);
2434 tx_t *tx;
2435 void *txbuf;
2436 unsigned long flags;
2438 int txresult = NOT_OK;
2440 FN_ENTER;
2442 if (unlikely(!skb)) {
2443 /* indicate success */
2444 txresult = OK;
2445 goto out;
2448 if (unlikely(!adev)) {
2449 goto out;
2452 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2453 goto out;
2455 if (unlikely(!adev->initialized)) {
2456 goto out;
2459 acx_lock(adev, flags);
2461 tx = acx_l_alloc_tx(adev);
2463 if (unlikely(!tx)) {
2464 acx_log_ratelimited(LOG_WARNING, L_ANY, "%s: start_xmit: "
2465 "txdesc ring is full, dropping tx\n",
2466 wiphy_name(adev->ieee->wiphy));
2467 txresult = NOT_OK;
2468 goto out_unlock;
2471 txbuf = acx_l_get_txbuf(adev, tx);
2473 if (unlikely(!txbuf)) {
2474 /* Card was removed */
2475 txresult = NOT_OK;
2476 acx_l_dealloc_tx(adev, tx);
2477 goto out_unlock;
2479 memcpy(txbuf, skb->data, skb->len);
2481 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2483 txresult = OK;
2484 adev->stats.tx_packets++;
2485 adev->stats.tx_bytes += skb->len;
2487 out_unlock:
2488 acx_unlock(adev, flags);
2490 out:
2491 FN_EXIT1(txresult);
2492 return txresult;
2494 /***********************************************************************
2495 ** acx_l_update_ratevector
2497 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2499 const u8 acx_bitpos2ratebyte[] = {
2500 DOT11RATEBYTE_1,
2501 DOT11RATEBYTE_2,
2502 DOT11RATEBYTE_5_5,
2503 DOT11RATEBYTE_6_G,
2504 DOT11RATEBYTE_9_G,
2505 DOT11RATEBYTE_11,
2506 DOT11RATEBYTE_12_G,
2507 DOT11RATEBYTE_18_G,
2508 DOT11RATEBYTE_22,
2509 DOT11RATEBYTE_24_G,
2510 DOT11RATEBYTE_36_G,
2511 DOT11RATEBYTE_48_G,
2512 DOT11RATEBYTE_54_G,
2515 void acx_l_update_ratevector(acx_device_t * adev)
2517 u16 bcfg = adev->rate_basic;
2518 u16 ocfg = adev->rate_oper;
2519 u8 *supp = adev->rate_supported;
2520 const u8 *dot11 = acx_bitpos2ratebyte;
2522 FN_ENTER;
2524 while (ocfg) {
2525 if (ocfg & 1) {
2526 *supp = *dot11;
2527 if (bcfg & 1) {
2528 *supp |= 0x80;
2530 supp++;
2532 dot11++;
2533 ocfg >>= 1;
2534 bcfg >>= 1;
2536 adev->rate_supported_len = supp - adev->rate_supported;
2538 acx_log_dump(LOG_DEBUG, L_ASSOC, adev->rate_supported,
2539 adev->rate_supported_len, "new ratevector:\n");
2541 FN_EXIT0;
2544 /***********************************************************************
2545 ** acx_i_timer
2547 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2549 ** Obvious
2551 void acx_i_timer(unsigned long address)
2553 unsigned long flags;
2554 acx_device_t *adev = (acx_device_t *) address;
2556 FN_ENTER;
2558 acx_lock(adev, flags);
2560 FIXME();
2561 /* We need calibration and stats gather tasks to perform here */
2563 acx_unlock(adev, flags);
2565 FN_EXIT0;
2569 /***********************************************************************
2570 ** acx_set_timer
2572 ** Sets the 802.11 state management timer's timeout.
2574 ** Linux derived
2576 void acx_set_timer(acx_device_t * adev, int timeout_us)
2578 FN_ENTER;
2580 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_IRQ,
2581 "%s(%u ms)\n", __func__, timeout_us / 1000);
2583 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2584 acx_log(LOG_WARNING, L_ANY, "attempt to set the timer "
2585 "when the card interface is not up!\n");
2586 goto end;
2589 /* first check if the timer was already initialized, THEN modify it */
2590 if (adev->mgmt_timer.function) {
2591 mod_timer(&adev->mgmt_timer,
2592 jiffies + (timeout_us * HZ / 1000000));
2594 end:
2595 FN_EXIT0;
2598 /** acx_plcp_get_bitrate_cck
2600 ** Obvious
2602 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2604 switch (plcp) {
2605 case 0x0A:
2606 return ACX_CCK_RATE_1MB;
2607 case 0x14:
2608 return ACX_CCK_RATE_2MB;
2609 case 0x37:
2610 return ACX_CCK_RATE_5MB;
2611 case 0x6E:
2612 return ACX_CCK_RATE_11MB;
2614 return 0;
2617 /* Extract the bitrate out of an OFDM PLCP header. */
2618 /** Obvious **/
2619 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2621 switch (plcp & 0xF) {
2622 case 0xB:
2623 return ACX_OFDM_RATE_6MB;
2624 case 0xF:
2625 return ACX_OFDM_RATE_9MB;
2626 case 0xA:
2627 return ACX_OFDM_RATE_12MB;
2628 case 0xE:
2629 return ACX_OFDM_RATE_18MB;
2630 case 0x9:
2631 return ACX_OFDM_RATE_24MB;
2632 case 0xD:
2633 return ACX_OFDM_RATE_36MB;
2634 case 0x8:
2635 return ACX_OFDM_RATE_48MB;
2636 case 0xC:
2637 return ACX_OFDM_RATE_54MB;
2639 return 0;
2643 /***********************************************************************
2644 ** acx_l_rx
2646 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2647 ** buffer and feeds it to the network stack via netif_rx().
2649 ** Look to bcm43xx or p54
2651 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2654 struct ieee80211_rx_status* status = &adev->rx_status;
2655 struct ieee80211_hdr *w_hdr;
2656 struct sk_buff *skb;
2657 int buflen;
2658 FN_ENTER;
2660 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2661 acx_log_ratelimited(LOG_WARNING, L_ANY,
2662 "asked to receive a packet but interface is down??\n");
2663 goto out;
2666 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2667 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2669 * Allocate our skb
2671 skb = dev_alloc_skb(buflen + 2);
2673 if (!skb) {
2674 acx_log_ratelimited(LOG_WARNING, L_ANY,
2675 "skb allocation FAILED\n");
2676 goto out;
2679 skb_reserve(skb, 2);
2680 skb_put(skb, buflen);
2681 memcpy(skb->data, w_hdr, buflen);
2683 // memset(&status, 0, sizeof(status));
2685 status->mactime = rxbuf->time;
2686 status->ssi = acx_signal_to_winlevel(rxbuf->phy_level);
2687 /* TODO: they do not seem to be reported, at least on the acx111
2688 * (and TNETW1450?), therefore commenting them out
2689 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2690 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr); */
2691 status->flag = 0;
2692 status->rate = rxbuf->phy_plcp_signal;
2693 status->antenna = 1;
2694 if (rxbuf->phy_stat_baseband & (1 << 3)) { /* Uses OFDM */
2695 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2696 } else {
2697 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2701 * FIXME: should it really be done here??
2703 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2704 adev->stats.rx_packets++;
2705 adev->stats.rx_bytes += skb->len;
2706 out:
2707 FN_EXIT0;
2712 /***********************************************************************
2713 ** acx_s_read_fw
2715 ** Loads a firmware image
2717 ** Returns:
2718 ** 0 unable to load file
2719 ** pointer to firmware success
2721 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2722 u32 * size)
2724 firmware_image_t *res;
2725 const struct firmware *fw_entry;
2727 res = NULL;
2728 acx_log(LOG_INFO, L_INIT, "requesting firmware image '%s'\n", file);
2729 if (!request_firmware(&fw_entry, file, dev)) {
2730 *size = 8;
2731 if (fw_entry->size >= 8)
2732 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2733 if (fw_entry->size != *size) {
2734 acx_log(LOG_WARNING, L_ANY,
2735 "acx: firmware size does not match "
2736 "firmware header: %d != %d, "
2737 "aborting fw upload\n",
2738 (int)fw_entry->size, (int)*size);
2739 goto release_ret;
2741 res = vmalloc(*size);
2742 if (!res) {
2743 acx_log(LOG_INFO, L_ANY, "acx: no memory for firmware "
2744 "(%u bytes)\n", *size);
2745 goto release_ret;
2747 memcpy(res, fw_entry->data, fw_entry->size);
2748 release_ret:
2749 release_firmware(fw_entry);
2750 return res;
2752 acx_log(LOG_WARNING, L_ANY, "acx: firmware image '%s' was not provided. "
2753 "Check your hotplug scripts\n", file);
2755 /* checksum will be verified in write_fw, so don't bother here */
2756 return res;
2760 /***********************************************************************
2761 ** acx_s_set_wepkey
2763 static void acx100_s_set_wepkey(acx_device_t * adev)
2765 ie_dot11WEPDefaultKey_t dk;
2766 int i;
2768 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2769 if (adev->wep_keys[i].size != 0) {
2770 acx_log(LOG_DEBUG, L_INIT, "setting WEP key: %d with "
2771 "total size: %d\n",
2772 i, (int)adev->wep_keys[i].size);
2773 dk.action = 1;
2774 dk.keySize = adev->wep_keys[i].size;
2775 dk.defaultKeyNum = i;
2776 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2777 acx_s_configure(adev, &dk,
2778 ACX100_REG_DOT11_WEP_DEFAULT_KEY_WRITE);
2783 static void acx111_s_set_wepkey(acx_device_t * adev)
2785 acx111WEPDefaultKey_t dk;
2786 int i;
2788 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2789 if (adev->wep_keys[i].size != 0) {
2790 acx_log(LOG_DEBUG, L_INIT, "setting WEP key: %d with "
2791 "total size: %d\n", i,
2792 (int)adev->wep_keys[i].size);
2793 memset(&dk, 0, sizeof(dk));
2794 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2795 dk.keySize = adev->wep_keys[i].size;
2797 /* are these two lines necessary? */
2798 dk.type = 0; /* default WEP key */
2799 dk.index = 0; /* ignored when setting default key */
2801 dk.defaultKeyNum = i;
2802 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2803 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2804 sizeof(dk));
2808 /* Obvious */
2809 static void acx_s_set_wepkey(acx_device_t * adev)
2811 if (IS_ACX111(adev))
2812 acx111_s_set_wepkey(adev);
2813 else
2814 acx100_s_set_wepkey(adev);
2818 /***********************************************************************
2819 ** acx100_s_init_wep
2821 ** FIXME: this should probably be moved into the new card settings
2822 ** management, but since we're also modifying the memory map layout here
2823 ** due to the WEP key space we want, we should take care...
2825 static int acx100_s_init_wep(acx_device_t * adev)
2827 acx100_ie_wep_options_t options;
2828 ie_dot11WEPDefaultKeyID_t dk;
2829 acx_ie_memmap_t pt;
2830 int res = NOT_OK;
2832 FN_ENTER;
2834 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_REG_MEMORY_MAP)) {
2835 goto fail;
2838 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "CodeEnd:%X\n", pt.CodeEnd);
2840 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2841 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2843 if (OK != acx_s_configure(adev, &pt, ACX1xx_REG_MEMORY_MAP)) {
2844 goto fail;
2847 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2848 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2849 options.WEPOption = 0x00;
2851 acx_log(LOG_DEBUG, L_ASSOC, "writing WEP options\n");
2852 acx_s_configure(adev, &options, ACX100_REG_WEP_OPTIONS);
2854 acx100_s_set_wepkey(adev);
2856 if (adev->wep_keys[adev->wep_current_index].size != 0) {
2857 acx_log(LOG_DEBUG, L_ASSOC,
2858 "setting active default WEP key number: %d\n",
2859 adev->wep_current_index);
2860 dk.KeyID = adev->wep_current_index;
2861 acx_s_configure(adev, &dk, ACX1xx_REG_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
2863 /* FIXME!!! wep_key_struct is filled nowhere! But adev
2864 * is initialized to 0, and we don't REALLY need those keys either */
2865 /* for (i = 0; i < 10; i++) {
2866 if (adev->wep_key_struct[i].len != 0) {
2867 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
2868 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
2869 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
2870 wep_mgmt.Action = cpu_to_le16(1);
2871 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
2872 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
2873 adev->wep_key_struct[i].index = i;
2879 /* now retrieve the updated WEPCacheEnd pointer... */
2880 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_REG_MEMORY_MAP)) {
2881 acx_log(LOG_WARNING, L_ANY,
2882 "%s: ACX1xx_REG_MEMORY_MAP read #2 FAILED\n",
2883 wiphy_name(adev->ieee->wiphy));
2884 goto fail;
2886 /* ...and tell it to start allocating templates at that location */
2887 /* (no endianness conversion needed) */
2888 pt.PacketTemplateStart = pt.WEPCacheEnd;
2890 if (OK != acx_s_configure(adev, &pt, ACX1xx_REG_MEMORY_MAP)) {
2891 acx_log(LOG_WARNING, L_ANY,
2892 "%s: ACX1xx_REG_MEMORY_MAP write #2 FAILED\n",
2893 wiphy_name(adev->ieee->wiphy));
2894 goto fail;
2896 res = OK;
2898 fail:
2899 FN_EXIT1(res);
2900 return res;
2904 static int
2905 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
2906 unsigned int cmd)
2908 int res;
2909 union {
2910 acx_template_nullframe_t null;
2911 acx_template_beacon_t b;
2912 acx_template_tim_t tim;
2913 acx_template_probereq_t preq;
2914 acx_template_proberesp_t presp;
2915 } templ;
2917 memset(&templ, 0, len);
2918 templ.null.size = cpu_to_le16(len - 2);
2919 res = acx_s_issue_cmd(adev, cmd, &templ, len);
2920 return res;
2923 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
2925 return acx_s_init_max_template_generic(adev,
2926 sizeof(acx_template_nullframe_t),
2927 ACX1xx_CMD_CONFIG_NULL_DATA);
2930 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
2932 return acx_s_init_max_template_generic(adev,
2933 sizeof(acx_template_beacon_t),
2934 ACX1xx_CMD_CONFIG_BEACON);
2937 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
2939 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
2940 ACX1xx_CMD_CONFIG_TIM);
2943 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
2945 return acx_s_init_max_template_generic(adev,
2946 sizeof(acx_template_proberesp_t),
2947 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
2950 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
2952 return acx_s_init_max_template_generic(adev,
2953 sizeof(acx_template_probereq_t),
2954 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
2957 /***********************************************************************
2958 ** acx_s_set_tim_template
2960 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
2961 ** by calling this function
2962 ** (it can be done by irq handler on each DTIM irq or by timer...)
2964 [802.11 7.3.2.6] TIM information element:
2965 - 1 EID
2966 - 1 Length
2967 1 1 DTIM Count
2968 indicates how many beacons (including this) appear before next DTIM
2969 (0=this one is a DTIM)
2970 2 1 DTIM Period
2971 number of beacons between successive DTIMs
2972 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
2973 3 1 Bitmap Control
2974 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
2975 set to 1 in TIM elements with a value of 0 in the DTIM Count field
2976 when one or more broadcast or multicast frames are buffered at the AP.
2977 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
2978 4 n Partial Virtual Bitmap
2979 Visible part of traffic-indication bitmap.
2980 Full bitmap consists of 2008 bits (251 octets) such that bit number N
2981 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
2982 in octet number N/8 where the low-order bit of each octet is bit0,
2983 and the high order bit is bit7.
2984 Each set bit in virtual bitmap corresponds to traffic buffered by AP
2985 for a specific station (with corresponding AID?).
2986 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
2987 Bitmap Offset is a number of skipped zero octets (see above).
2988 'Missing' octets at the tail are also assumed to be zero.
2989 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
2990 This means that traffic-indication bitmap is:
2991 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
2992 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
2994 static int acx_s_set_tim_template(acx_device_t * adev)
2996 /* For now, configure smallish test bitmap, all zero ("no pending data") */
2997 enum { bitmap_size = 5 };
2999 acx_template_tim_t t;
3000 int result;
3002 FN_ENTER;
3004 memset(&t, 0, sizeof(t));
3005 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3006 t.tim_eid = WLAN_EID_TIM;
3007 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3008 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3009 FN_EXIT1(result);
3010 return result;
3016 #if POWER_SAVE_80211
3017 /***********************************************************************
3018 ** acx_s_set_null_data_template
3020 static int acx_s_set_null_data_template(acx_device_t * adev)
3022 struct acx_template_nullframe b;
3023 int result;
3025 FN_ENTER;
3027 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3029 b.size = cpu_to_le16(sizeof(b) - 2);
3030 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3031 b.hdr.dur = 0;
3032 MAC_BCAST(b.hdr.a1);
3033 MAC_COPY(b.hdr.a2, adev->dev_addr);
3034 MAC_COPY(b.hdr.a3, adev->bssid);
3035 b.hdr.seq = 0;
3037 result =
3038 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3040 FN_EXIT1(result);
3041 return result;
3043 #endif
3050 /***********************************************************************
3051 ** acx_s_init_packet_templates()
3053 ** NOTE: order is very important here, to have a correct memory layout!
3054 ** init templates: max Probe Request (station mode), max NULL data,
3055 ** max Beacon, max TIM, max Probe Response.
3057 static int acx_s_init_packet_templates(acx_device_t * adev)
3059 acx_ie_memmap_t mm; /* ACX100 only */
3060 int result = NOT_OK;
3062 FN_ENTER;
3064 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_INIT,
3065 "initializing max packet templates\n");
3067 if (OK != acx_s_init_max_probe_request_template(adev))
3068 goto failed;
3070 if (OK != acx_s_init_max_null_data_template(adev))
3071 goto failed;
3073 if (OK != acx_s_init_max_beacon_template(adev))
3074 goto failed;
3076 if (OK != acx_s_init_max_tim_template(adev))
3077 goto failed;
3079 if (OK != acx_s_init_max_probe_response_template(adev))
3080 goto failed;
3082 if (IS_ACX111(adev)) {
3083 /* ACX111 doesn't need the memory map magic below,
3084 * and the other templates will be set later (acx_start) */
3085 result = OK;
3086 goto success;
3089 /* ACX100 will have its TIM template set,
3090 * and we also need to update the memory map */
3092 if (OK != acx_s_set_tim_template(adev))
3093 goto failed_acx100;
3095 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
3096 "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3098 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_REG_MEMORY_MAP))
3099 goto failed_acx100;
3101 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3102 if (OK != acx_s_configure(adev, &mm, ACX1xx_REG_MEMORY_MAP))
3103 goto failed_acx100;
3105 result = OK;
3106 goto success;
3108 failed_acx100:
3109 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_INIT,
3110 /* "cb=0x%X\n" */
3111 "ACXMemoryMap:\n"
3112 ".CodeStart=0x%X\n"
3113 ".CodeEnd=0x%X\n"
3114 ".WEPCacheStart=0x%X\n"
3115 ".WEPCacheEnd=0x%X\n"
3116 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3117 /* len, */
3118 le32_to_cpu(mm.CodeStart),
3119 le32_to_cpu(mm.CodeEnd),
3120 le32_to_cpu(mm.WEPCacheStart),
3121 le32_to_cpu(mm.WEPCacheEnd),
3122 le32_to_cpu(mm.PacketTemplateStart),
3123 le32_to_cpu(mm.PacketTemplateEnd));
3125 failed:
3126 acx_log(LOG_WARNING, L_ANY, "%s: %s() FAILED\n",
3127 wiphy_name(adev->ieee->wiphy), __func__);
3129 success:
3130 FN_EXIT1(result);
3131 return result;
3136 /***********************************************************************
3137 ** acx_s_init_mac
3139 int acx_s_init_mac(acx_device_t * adev)
3141 int result = NOT_OK;
3143 FN_ENTER;
3145 if (IS_ACX111(adev)) {
3146 adev->ie_len = acx111_ie_len;
3147 adev->ie_len_dot11 = acx111_ie_len_dot11;
3148 } else {
3149 adev->ie_len = acx100_ie_len;
3150 adev->ie_len_dot11 = acx100_ie_len_dot11;
3153 if (IS_PCI(adev)) {
3154 adev->memblocksize = 256; /* 256 is default */
3155 /* try to load radio for both ACX100 and ACX111, since both
3156 * chips have at least some firmware versions making use of an
3157 * external radio module */
3158 acxpci_s_upload_radio(adev);
3159 } else {
3160 adev->memblocksize = 128;
3163 if (IS_ACX111(adev)) {
3164 /* for ACX111, the order is different from ACX100
3165 1. init packet templates
3166 2. create station context and create dma regions
3167 3. init wep default keys
3169 if (OK != acx_s_init_packet_templates(adev))
3170 goto fail;
3171 if (OK != acx111_s_create_dma_regions(adev)) {
3172 acx_log(LOG_WARNING, L_ANY,
3173 "%s: acx111_create_dma_regions FAILED\n",
3174 wiphy_name(adev->ieee->wiphy));
3175 goto fail;
3177 } else {
3178 if (OK != acx100_s_init_wep(adev))
3179 goto fail;
3180 if (OK != acx_s_init_packet_templates(adev))
3181 goto fail;
3182 if (OK != acx100_s_create_dma_regions(adev)) {
3183 acx_log(LOG_WARNING, L_ANY,
3184 "%s: acx100_create_dma_regions FAILED\n",
3185 wiphy_name(adev->ieee->wiphy));
3186 goto fail;
3190 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3191 result = OK;
3193 fail:
3194 if (result)
3195 acx_log(LOG_WARNING, L_ANY, "init_mac() FAILED\n");
3196 FN_EXIT1(result);
3197 return result;
3202 #if POWER_SAVE_80211
3203 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3205 /* merge both structs in a union to be able to have common code */
3206 union {
3207 acx111_ie_powersave_t acx111;
3208 acx100_ie_powersave_t acx100;
3209 } pm;
3211 /* change 802.11 power save mode settings */
3212 acx_log(LOG_DEBUG, L_INIT, "updating 802.11 power save mode settings: "
3213 "wakeup_cfg 0x%02X, listen interval %u, "
3214 "options 0x%02X, hangover period %u, "
3215 "enhanced_ps_transition_time %u\n",
3216 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3217 adev->ps_options, adev->ps_hangover_period,
3218 adev->ps_enhanced_transition_time);
3219 acx_s_interrogate(adev, &pm, ACX1xx_REG_POWER_MGMT);
3220 acx_log(LOG_DEBUG, L_INIT, "Previous PS mode settings: "
3221 "wakeup_cfg 0x%02X, "
3222 "listen interval %u, options 0x%02X, "
3223 "hangover period %u, "
3224 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3225 pm.acx111.wakeup_cfg,
3226 pm.acx111.listen_interval,
3227 pm.acx111.options,
3228 pm.acx111.hangover_period,
3229 IS_ACX111(adev) ?
3230 pm.acx111.enhanced_ps_transition_time
3231 : pm.acx100.enhanced_ps_transition_time,
3232 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3233 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3234 pm.acx111.listen_interval = adev->ps_listen_interval;
3235 pm.acx111.options = adev->ps_options;
3236 pm.acx111.hangover_period = adev->ps_hangover_period;
3237 if (IS_ACX111(adev)) {
3238 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3239 pm.acx111.enhanced_ps_transition_time =
3240 cpu_to_le32(adev->ps_enhanced_transition_time);
3241 } else {
3242 pm.acx100.enhanced_ps_transition_time =
3243 cpu_to_le16(adev->ps_enhanced_transition_time);
3245 acx_s_configure(adev, &pm, ACX1xx_REG_POWER_MGMT);
3246 acx_s_interrogate(adev, &pm, ACX1xx_REG_POWER_MGMT);
3247 acx_log(LOG_DEBUG, L_INIT, "wakeup_cfg: 0x%02X\n",
3248 pm.acx111.wakeup_cfg);
3249 acx_s_mwait(40);
3250 acx_s_interrogate(adev, &pm, ACX1xx_REG_POWER_MGMT);
3251 acx_log(LOG_DEBUG, L_INIT, "wakeup_cfg: 0x%02X\n",
3252 pm.acx111.wakeup_cfg);
3253 acx_log(LOG_DEBUG, L_INIT, "power save mode change %s\n",
3254 (pm.acx111.wakeup_cfg & PS_CFG_PENDING) ?
3255 "FAILED" : "was successful");
3256 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3257 * that power save mode change was successful. */
3258 /* FIXME: we shouldn't trigger a scan immediately after
3259 * fiddling with power save mode (since the firmware is sending
3260 * a NULL frame then). */
3262 #endif
3265 /***********************************************************************
3266 ** acx_s_update_card_settings
3268 ** Applies accumulated changes in various adev->xxxx members
3269 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3270 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3272 void acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
3274 unsigned mask;
3276 unsigned int i;
3278 for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
3279 if (acx_reg_domain_ids[i] == adev->reg_dom_id)
3280 break;
3282 if (sizeof(acx_reg_domain_ids) == i) {
3283 acx_log(LOG_WARNING, L_INIT,
3284 "Invalid or unsupported regulatory domain"
3285 " 0x%02X specified, falling back to FCC (USA)!"
3286 " Please report if this sounds fishy!\n",
3287 adev->reg_dom_id);
3288 i = 0;
3289 adev->reg_dom_id = acx_reg_domain_ids[i];
3291 /* since there was a mismatch, we need to force updating */
3292 do_set = 1;
3295 if (do_set) {
3296 acx_ie_generic_t dom;
3297 dom.m.bytes[0] = adev->reg_dom_id;
3298 acx_s_configure(adev, &dom, ACX1xx_REG_DOT11_CURRENT_REG_DOMAIN);
3301 adev->reg_dom_chanmask = reg_domain_channel_masks[i];
3303 mask = (1 << (adev->channel - 1));
3306 * Check our channels wrt the current regulatory domain
3308 if (adev->reg_dom_chanmask & mask)
3309 return;
3312 * Hmm nope, need to adjust channels!
3315 mask = 1;
3316 for (i = 1; i <= 14; i++) {
3317 if (!(adev->reg_dom_chanmask & mask)) {
3318 mask <<= 1;
3319 continue;
3321 acx_log(LOG_INFO, L_ANY, "%s: adjusting selected channel "
3322 "from %d to %d due to new regulatory domain\n",
3323 wiphy_name(adev->ieee->wiphy), adev->channel, i);
3324 adev->channel = i;
3325 break;
3329 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3331 u32 feature1, feature2;
3333 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3334 acx_log(LOG_WARNING, L_ANY,
3335 "%s: invalid sensitivity setting (1..3), "
3336 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3337 adev->sensitivity = 1;
3339 acx111_s_get_feature_config(adev, &feature1, &feature2);
3340 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3341 if (adev->sensitivity > 1)
3342 SET_BIT(feature1, FEATURE1_LOW_RX);
3343 if (adev->sensitivity > 2)
3344 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3345 acx111_s_feature_set(adev, feature1, feature2);
3349 void acx_s_update_card_settings(acx_device_t *adev)
3351 unsigned long flags;
3352 unsigned int start_scan = 0;
3353 int i;
3355 FN_ENTER;
3357 acx_log(LOG_DEBUG, L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3358 adev->get_mask, adev->set_mask);
3360 /* Track dependencies betweed various settings */
3362 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3363 acx_log(LOG_DEBUG, L_INIT,
3364 "important setting has been changed. "
3365 "Need to update packet templates, too\n");
3366 SET_BIT(adev->set_mask, SET_TEMPLATES);
3368 if (adev->set_mask & GETSET_CHANNEL) {
3369 /* This will actually tune RX/TX to the channel */
3370 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3371 switch (adev->mode) {
3372 case ACX_MODE_0_ADHOC:
3373 case ACX_MODE_3_AP:
3374 /* Beacons contain channel# - update them */
3375 SET_BIT(adev->set_mask, SET_TEMPLATES);
3378 switch (adev->mode) {
3379 case ACX_MODE_0_ADHOC:
3380 case ACX_MODE_2_STA:
3381 start_scan = 1;
3385 /* Apply settings */
3388 if (adev->get_mask & GETSET_STATION_ID) {
3389 u8 stationID[4 + ACX1xx_REG_DOT11_STATION_ID_LEN];
3390 const u8 *paddr;
3392 acx_s_interrogate(adev, &stationID, ACX1xx_REG_DOT11_STATION_ID);
3393 paddr = &stationID[4];
3394 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3395 for (i = 0; i < ETH_ALEN; i++) {
3396 /* we copy the MAC address (reversed in
3397 * the card) to the netdevice's MAC
3398 * address, and on ifup it will be
3399 * copied into iwadev->dev_addr */
3400 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3402 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3403 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3406 if (adev->get_mask & GETSET_SENSITIVITY) {
3407 if ((RADIO_RFMD_11 == adev->radio_type)
3408 || (RADIO_MAXIM_0D == adev->radio_type)
3409 || (RADIO_RALINK_15 == adev->radio_type)) {
3410 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3411 } else {
3412 acx_log(LOG_WARNING, L_INIT,
3413 "don't know how to get sensitivity "
3414 "for radio type 0x%02X\n", adev->radio_type);
3415 adev->sensitivity = 0;
3417 acx_log(LOG_DEBUG, L_INIT, "got sensitivity value %u\n",
3418 adev->sensitivity);
3420 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3423 if (adev->get_mask & GETSET_ANTENNA) {
3424 u8 antenna[4 + ACX1xx_REG_DOT11_CURRENT_ANTENNA_LEN];
3426 memset(antenna, 0, sizeof(antenna));
3427 acx_s_interrogate(adev, antenna,
3428 ACX1xx_REG_DOT11_CURRENT_ANTENNA);
3429 adev->antenna = antenna[4];
3430 acx_log(LOG_INFO, L_INIT, "got antenna value 0x%02X\n",
3431 adev->antenna);
3432 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3435 if (adev->get_mask & GETSET_ED_THRESH) {
3436 if (IS_ACX100(adev)) {
3437 u8 ed_threshold[4 + ACX100_REG_DOT11_ED_THRESHOLD_LEN];
3439 memset(ed_threshold, 0, sizeof(ed_threshold));
3440 acx_s_interrogate(adev, ed_threshold,
3441 ACX100_REG_DOT11_ED_THRESHOLD);
3442 adev->ed_threshold = ed_threshold[4];
3443 } else {
3444 acx_log(LOG_WARNING, L_INIT,
3445 "acx111 doesn't support ED\n");
3446 adev->ed_threshold = 0;
3448 acx_log(LOG_INFO, L_INIT,
3449 "got Energy Detect (ED) threshold %u\n",
3450 adev->ed_threshold);
3451 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3454 if (adev->get_mask & GETSET_CCA) {
3455 if (IS_ACX100(adev)) {
3456 u8 cca[4 + ACX1xx_REG_DOT11_CURRENT_CCA_MODE_LEN];
3458 memset(cca, 0, sizeof(adev->cca));
3459 acx_s_interrogate(adev, cca,
3460 ACX1xx_REG_DOT11_CURRENT_CCA_MODE);
3461 adev->cca = cca[4];
3462 } else {
3463 acx_log(LOG_WARNING, L_INIT,
3464 "acx111 doesn't support CCA\n");
3465 adev->cca = 0;
3467 acx_log(LOG_INFO, L_INIT,
3468 "got Channel Clear Assessment (CCA) value %u\n",
3469 adev->cca);
3470 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3473 if (adev->get_mask & GETSET_REG_DOMAIN) {
3474 acx_ie_generic_t dom;
3476 acx_s_interrogate(adev, &dom,
3477 ACX1xx_REG_DOT11_CURRENT_REG_DOMAIN);
3478 adev->reg_dom_id = dom.m.bytes[0];
3479 acx_s_set_sane_reg_domain(adev, 0);
3480 acx_log(LOG_INFO, L_INIT,
3481 "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3482 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3485 if (adev->set_mask & GETSET_STATION_ID) {
3486 u8 stationID[4 + ACX1xx_REG_DOT11_STATION_ID_LEN];
3487 u8 *paddr;
3489 paddr = &stationID[4];
3490 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3491 for (i = 0; i < ETH_ALEN; i++) {
3492 /* copy the MAC address we obtained when we noticed
3493 * that the ethernet iface's MAC changed
3494 * to the card (reversed in
3495 * the card!) */
3496 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3498 acx_s_configure(adev, &stationID, ACX1xx_REG_DOT11_STATION_ID);
3499 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3502 if (adev->set_mask & SET_STA_LIST) {
3503 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3505 if (adev->set_mask & SET_RATE_FALLBACK) {
3506 u8 rate[4 + ACX1xx_REG_RATE_FALLBACK_LEN];
3508 /* configure to not do fallbacks when not in auto rate mode */
3509 rate[4] =
3510 (adev->
3511 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3512 acx_log(LOG_DEBUG, L_INIT,
3513 "updating Tx fallback to %u retries\n", rate[4]);
3514 acx_s_configure(adev, &rate, ACX1xx_REG_RATE_FALLBACK);
3515 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3517 if (adev->set_mask & GETSET_TXPOWER) {
3518 acx_log(LOG_DEBUG, L_INIT, "updating transmit power: %u dBm\n",
3519 adev->tx_level_dbm);
3520 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3521 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3524 if (adev->set_mask & GETSET_SENSITIVITY) {
3525 acx_log(LOG_DEBUG, L_INIT, "updating sensitivity value: %u\n",
3526 adev->sensitivity);
3527 switch (adev->radio_type) {
3528 case RADIO_RFMD_11:
3529 case RADIO_MAXIM_0D:
3530 case RADIO_RALINK_15:
3531 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3532 break;
3533 case RADIO_RADIA_16:
3534 case RADIO_UNKNOWN_17:
3535 acx111_s_sens_radio_16_17(adev);
3536 break;
3537 default:
3538 acx_log(LOG_WARNING, L_INIT,
3539 "don't know how to modify sensitivity "
3540 "for radio type 0x%02X\n", adev->radio_type);
3542 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3545 if (adev->set_mask & GETSET_ANTENNA) {
3546 /* antenna */
3547 u8 antenna[4 + ACX1xx_REG_DOT11_CURRENT_ANTENNA_LEN];
3549 memset(antenna, 0, sizeof(antenna));
3550 antenna[4] = adev->antenna;
3551 acx_log(LOG_DEBUG, L_INIT, "updating antenna value: 0x%02X\n",
3552 adev->antenna);
3553 acx_s_configure(adev, &antenna,
3554 ACX1xx_REG_DOT11_CURRENT_ANTENNA);
3555 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3558 if (adev->set_mask & GETSET_ED_THRESH) {
3559 /* ed_threshold */
3560 acx_log(LOG_INFO, L_INIT,
3561 "updating Energy Detect (ED) threshold: %u\n",
3562 adev->ed_threshold);
3563 if (IS_ACX100(adev)) {
3564 u8 ed_threshold[4 + ACX100_REG_DOT11_ED_THRESHOLD_LEN];
3566 memset(ed_threshold, 0, sizeof(ed_threshold));
3567 ed_threshold[4] = adev->ed_threshold;
3568 acx_s_configure(adev, &ed_threshold,
3569 ACX100_REG_DOT11_ED_THRESHOLD);
3570 } else
3571 acx_log(LOG_WARNING, L_INIT,
3572 "acx111 doesn't support ED!\n");
3573 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3576 if (adev->set_mask & GETSET_CCA) {
3577 /* CCA value */
3578 acx_log(LOG_DEBUG, L_INIT,
3579 "updating Channel Clear Assessment (CCA) value: "
3580 "0x%02X\n", adev->cca);
3581 if (IS_ACX100(adev)) {
3582 u8 cca[4 + ACX1xx_REG_DOT11_CURRENT_CCA_MODE_LEN];
3584 memset(cca, 0, sizeof(cca));
3585 cca[4] = adev->cca;
3586 acx_s_configure(adev, &cca,
3587 ACX1xx_REG_DOT11_CURRENT_CCA_MODE);
3588 } else
3589 acx_log(LOG_WARNING, L_INIT,
3590 "acx111 doesn't support CCA!\n");
3591 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3594 if (adev->set_mask & GETSET_LED_POWER) {
3595 /* Enable Tx */
3596 acx_log(LOG_INFO, L_INIT,
3597 "updating power LED status: %u\n", adev->led_power);
3599 acx_lock(adev, flags); /* acxpci_l_power_led expects that the lock is already taken! */
3600 if (IS_PCI(adev))
3601 acxpci_l_power_led(adev, adev->led_power);
3602 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3603 acx_unlock(adev, flags);
3606 if (adev->set_mask & GETSET_POWER_80211) {
3607 #if POWER_SAVE_80211
3608 acx_s_update_80211_powersave_mode(adev);
3609 #endif
3610 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3613 if (adev->set_mask & GETSET_CHANNEL) {
3614 /* channel */
3615 acx_log(LOG_INFO, L_INIT, "updating channel to: %u\n",
3616 adev->channel);
3617 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3620 if (adev->set_mask & GETSET_TX) {
3621 /* set Tx */
3622 acx_log(LOG_INFO, L_INIT, "updating: %s Tx\n",
3623 adev->tx_disabled ? "disable" : "enable");
3624 if (adev->tx_disabled)
3625 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3626 else {
3627 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3628 &adev->channel, 1);
3629 FIXME();
3630 /* This needs to be keyed on WEP? */
3631 /* acx111_s_feature_on(adev, 0,
3632 FEATURE2_NO_TXCRYPT |
3633 FEATURE2_SNIFFER); */
3634 acx_wake_queue(adev->ieee, NULL);
3636 CLEAR_BIT(adev->set_mask, GETSET_TX);
3639 if (adev->set_mask & GETSET_RX) {
3640 /* Enable Rx */
3641 acx_log(LOG_INFO, L_INIT,
3642 "updating: enable Rx on channel: %u\n", adev->channel);
3643 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3644 CLEAR_BIT(adev->set_mask, GETSET_RX);
3647 if (adev->set_mask & GETSET_RETRY) {
3648 u8 short_retry[4 + ACX1xx_REG_DOT11_SHORT_RETRY_LIMIT_LEN];
3649 u8 long_retry[4 + ACX1xx_REG_DOT11_LONG_RETRY_LIMIT_LEN];
3651 acx_log(LOG_INFO, L_INIT,
3652 "updating short retry limit: %u, "
3653 "long retry limit: %u\n",
3654 adev->short_retry, adev->long_retry);
3655 short_retry[0x4] = adev->short_retry;
3656 long_retry[0x4] = adev->long_retry;
3657 acx_s_configure(adev, &short_retry,
3658 ACX1xx_REG_DOT11_SHORT_RETRY_LIMIT);
3659 acx_s_configure(adev, &long_retry,
3660 ACX1xx_REG_DOT11_LONG_RETRY_LIMIT);
3661 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3664 if (adev->set_mask & SET_MSDU_LIFETIME) {
3665 u8 xmt_msdu_lifetime[4 +
3666 ACX1xx_REG_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3668 acx_log(LOG_DEBUG, L_INIT, "updating tx MSDU lifetime: %u\n",
3669 adev->msdu_lifetime);
3670 *(u32 *) & xmt_msdu_lifetime[4] =
3671 cpu_to_le32((u32) adev->msdu_lifetime);
3672 acx_s_configure(adev, &xmt_msdu_lifetime,
3673 ACX1xx_REG_DOT11_MAX_XMIT_MSDU_LIFETIME);
3674 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3677 if (adev->set_mask & GETSET_REG_DOMAIN) {
3678 acx_log(LOG_INFO, L_INIT,
3679 "updating regulatory domain: 0x%02X\n",
3680 adev->reg_dom_id);
3681 acx_s_set_sane_reg_domain(adev, 1);
3682 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3684 if (adev->set_mask & GETSET_MODE ) {
3685 acx111_s_feature_on(adev, 0,
3686 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3687 switch (adev->mode) {
3688 case ACX_MODE_3_AP:
3689 adev->aid = 0;
3690 //acx111_s_feature_off(adev, 0,
3691 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3692 MAC_COPY(adev->bssid, adev->dev_addr);
3693 acx_s_cmd_join_bssid(adev, adev->dev_addr);
3694 break;
3695 case ACX_MODE_MONITOR:
3696 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3697 break;
3698 case ACX_MODE_0_ADHOC:
3699 case ACX_MODE_2_STA:
3700 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3701 break;
3702 default:
3703 break;
3705 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3707 if (adev->set_mask & SET_TEMPLATES) {
3708 switch (adev->mode)
3710 case ACX_MODE_3_AP:
3711 acx_s_set_tim_template(adev);
3712 break;
3713 default:
3714 break;
3716 if (adev->beacon_cache)
3718 acx_s_set_beacon_template(adev, adev->beacon_cache);
3719 dev_kfree_skb(adev->beacon_cache);
3720 adev->beacon_cache = NULL;
3722 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3725 if (adev->set_mask & SET_RXCONFIG) {
3726 acx_s_initialize_rx_config(adev);
3727 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3730 if (adev->set_mask & GETSET_RESCAN) {
3731 /* switch (adev->mode) {
3732 case ACX_MODE_0_ADHOC:
3733 case ACX_MODE_2_STA:
3734 start_scan = 1;
3735 break;
3737 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3740 if (adev->set_mask & GETSET_WEP) {
3741 /* encode */
3743 ie_dot11WEPDefaultKeyID_t dkey;
3744 #ifdef DEBUG_WEP
3745 struct {
3746 u16 type;
3747 u16 len;
3748 u8 val;
3749 } __attribute__ ((packed)) keyindic;
3750 #endif
3751 acx_log(LOG_DEBUG, L_INIT, "updating WEP key settings\n");
3753 acx_s_set_wepkey(adev);
3754 if (adev->wep_enabled) {
3755 dkey.KeyID = adev->wep_current_index;
3756 acx_log(LOG_DEBUG, L_INIT,
3757 "setting WEP key %u as default\n",
3758 dkey.KeyID);
3759 acx_s_configure(adev, &dkey,
3760 ACX1xx_REG_DOT11_WEP_DEFAULT_KEY_SET);
3761 #ifdef DEBUG_WEP
3762 keyindic.val = 3;
3763 acx_s_configure(adev, &keyindic, ACX111_REG_KEY_CHOOSE);
3764 #endif
3767 // start_scan = 1;
3768 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3771 if (adev->set_mask & SET_WEP_OPTIONS) {
3772 acx100_ie_wep_options_t options;
3774 if (IS_ACX111(adev)) {
3775 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
3776 "setting WEP Options for acx111 "
3777 "is not supported\n");
3778 } else {
3779 acx_log(LOG_DEBUG, L_INIT, "setting WEP Options\n");
3781 /* let's choose maximum setting: 4 default keys,
3782 * plus 10 other keys: */
3783 options.NumKeys =
3784 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3785 /* don't decrypt default key only,
3786 * don't override decryption: */
3787 options.WEPOption = 0;
3788 if (adev->mode == ACX_MODE_3_AP) {
3789 /* don't decrypt default key only,
3790 * override decryption mechanism: */
3791 options.WEPOption = 2;
3794 acx_s_configure(adev, &options, ACX100_REG_WEP_OPTIONS);
3796 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3800 /* debug, rate, and nick don't need any handling */
3801 /* what about sniffing mode?? */
3803 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3804 adev->get_mask, adev->set_mask);
3806 /* end: */
3807 FN_EXIT0;
3810 #if 0
3811 /***********************************************************************
3812 ** acx_e_after_interrupt_task
3814 static int acx_s_recalib_radio(acx_device_t * adev)
3816 if (IS_ACX111(adev)) {
3817 acx111_cmd_radiocalib_t cal;
3819 /* automatic recalibration, choose all methods: */
3820 cal.methods = cpu_to_le32(0x8000000f);
3821 /* automatic recalibration every 60 seconds (value in TUs)
3822 * I wonder what the firmware default here is? */
3823 cal.interval = cpu_to_le32(58594);
3824 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3825 &cal, sizeof(cal),
3826 CMD_TIMEOUT_MS(100));
3827 } else {
3828 /* On ACX100, we need to recalibrate the radio
3829 * by issuing a GETSET_TX|GETSET_RX */
3830 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3831 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3832 (OK ==
3833 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3834 &adev->channel, 1))
3835 && (OK ==
3836 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3837 &adev->channel, 1)))
3838 return OK;
3839 return NOT_OK;
3842 #endif // if 0
3843 #if 0
3844 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3846 int res;
3848 /* this helps with ACX100 at least;
3849 * hopefully ACX111 also does a
3850 * recalibration here */
3852 /* clear flag beforehand, since we want to make sure
3853 * it's cleared; then only set it again on specific circumstances */
3854 CLEAR_BIT(adev->after_interrupt_jobs, ACX_TASKLET_CMD_RADIO_RECALIB);
3856 /* better wait a bit between recalibrations to
3857 * prevent overheating due to torturing the card
3858 * into working too long despite high temperature
3859 * (just a safety measure) */
3860 if (adev->recalib_time_last_success
3861 && time_before(jiffies, adev->recalib_time_last_success
3862 + RECALIB_PAUSE * 60 * HZ)) {
3863 if (adev->recalib_msg_ratelimit <= 4) {
3864 printk("%s: less than " STRING(RECALIB_PAUSE)
3865 " minutes since last radio recalibration, "
3866 "not recalibrating (maybe card is too hot?)\n",
3867 wiphy_name(adev->ieee->wiphy));
3868 adev->recalib_msg_ratelimit++;
3869 if (adev->recalib_msg_ratelimit == 5)
3870 printk("disabling above message until next recalib\n");
3872 return;
3875 adev->recalib_msg_ratelimit = 0;
3877 /* note that commands sometimes fail (card busy),
3878 * so only clear flag if we were fully successful */
3879 res = acx_s_recalib_radio(adev);
3880 if (res == OK) {
3881 printk("%s: successfully recalibrated radio\n",
3882 wiphy_name(adev->ieee->wiphy));
3883 adev->recalib_time_last_success = jiffies;
3884 adev->recalib_failure_count = 0;
3885 } else {
3886 /* failed: resubmit, but only limited
3887 * amount of times within some time range
3888 * to prevent endless loop */
3890 adev->recalib_time_last_success = 0; /* we failed */
3892 /* if some time passed between last
3893 * attempts, then reset failure retry counter
3894 * to be able to do next recalib attempt */
3895 if (time_after
3896 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3897 adev->recalib_failure_count = 0;
3899 if (adev->recalib_failure_count < 5) {
3900 /* increment inside only, for speedup of outside path */
3901 adev->recalib_failure_count++;
3902 adev->recalib_time_last_attempt = jiffies;
3903 acx_schedule_task(adev,
3904 ACX_TASKLET_CMD_RADIO_RECALIB);
3908 #endif // if 0
3910 void acx_e_after_interrupt_task(struct work_struct *work)
3912 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
3913 unsigned long flags;
3915 FN_ENTER;
3917 acx_lock(adev, flags);
3919 if (!adev->after_interrupt_jobs || !adev->initialized)
3920 goto end; /* no jobs to do */
3922 /* we see lotsa tx errors */
3923 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_RADIO_RECALIB) {
3924 acx_log_ratelimited(LOG_WARNING, L_ANY,
3925 "too many TX errors??\n");
3926 // acx_s_after_interrupt_recalib(adev);
3929 /* a poor interrupt code wanted to do update_card_settings() */
3930 if (adev->after_interrupt_jobs & ACX_TASKLET_UPDATE_CARD_CFG) {
3931 if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
3932 acx_unlock(adev, flags);
3933 acx_s_update_card_settings(adev);
3934 acx_lock(adev, flags);
3936 CLEAR_BIT(adev->after_interrupt_jobs,
3937 ACX_TASKLET_UPDATE_CARD_CFG);
3940 /* 1) we detected that no Scan_Complete IRQ came from fw, or
3941 ** 2) we found too many STAs */
3942 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_STOP_SCAN) {
3943 acx_log(LOG_DEBUG, L_IRQ, "sending a stop scan cmd...\n");
3944 acx_unlock(adev, flags);
3945 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
3946 acx_lock(adev, flags);
3947 /* HACK: set the IRQ bit, since we won't get a
3948 * scan complete IRQ any more on ACX111 (works on ACX100!),
3949 * since _we_, not a fw, have stopped the scan */
3950 SET_BIT(adev->irq_status, ACX_IRQ_SCAN_COMPLETE);
3951 CLEAR_BIT(adev->after_interrupt_jobs,
3952 ACX_TASKLET_CMD_STOP_SCAN);
3955 /* either fw sent Scan_Complete or we detected that
3956 ** no Scan_Complete IRQ came from fw. Finish scanning,
3957 ** pick join partner if any */
3958 if (adev->after_interrupt_jobs & ACX_TASKLET_COMPLETE_SCAN) {
3959 /* + scan kills current join status - restore it
3960 ** (do we need it for STA?) */
3961 /* + does it happen only with active scans?
3962 ** active and passive scans? ALL scans including
3963 ** background one? */
3964 /* + was not verified that everything is restored
3965 ** (but at least we start to emit beacons again) */
3966 CLEAR_BIT(adev->after_interrupt_jobs,
3967 ACX_TASKLET_COMPLETE_SCAN);
3970 /* STA auth or assoc timed out, start over again */
3972 if (adev->after_interrupt_jobs & ACX_TASKLET_RESTART_SCAN) {
3973 acx_log(LOG_DEBUG, L_IRQ, "sending a start_scan cmd...\n");
3974 CLEAR_BIT(adev->after_interrupt_jobs,
3975 ACX_TASKLET_RESTART_SCAN);
3978 /* whee, we got positive assoc response! 8) */
3979 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_ASSOCIATE) {
3980 CLEAR_BIT(adev->after_interrupt_jobs,
3981 ACX_TASKLET_CMD_ASSOCIATE);
3983 end:
3984 if(adev->after_interrupt_jobs)
3986 acx_log(LOG_DEBUG, L_ANY, "Jobs still to be run: %x\n",
3987 adev->after_interrupt_jobs);
3988 adev->after_interrupt_jobs = 0;
3990 acx_unlock(adev, flags);
3991 // acx_sem_unlock(adev);
3992 FN_EXIT0;
3996 /***********************************************************************
3997 ** acx_schedule_task
3999 ** Schedule the call of the after_interrupt method after leaving
4000 ** the interrupt context.
4002 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
4004 if (!adev->after_interrupt_jobs)
4006 SET_BIT(adev->after_interrupt_jobs, set_flag);
4007 schedule_work(&adev->after_interrupt_task);
4012 /***********************************************************************
4014 void acx_init_task_scheduler(acx_device_t * adev)
4016 /* configure task scheduler */
4017 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4021 /***********************************************************************
4022 ** acx_s_start
4024 void acx_s_start(acx_device_t * adev)
4026 FN_ENTER;
4029 * Ok, now we do everything that can possibly be done with ioctl
4030 * calls to make sure that when it was called before the card
4031 * was up we get the changes asked for
4034 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4035 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4036 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4037 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4039 acx_log(LOG_INFO, L_INIT,
4040 "updating initial settings on iface activation\n");
4041 acx_s_update_card_settings(adev);
4043 FN_EXIT0;
4047 /***********************************************************************
4048 ** acx_update_capabilities
4049 *//*
4050 void acx_update_capabilities(acx_device_t * adev)
4052 u16 cap = 0;
4054 switch (adev->mode) {
4055 case ACX_MODE_3_AP:
4056 SET_BIT(cap, WF_MGMT_CAP_ESS);
4057 break;
4058 case ACX_MODE_0_ADHOC:
4059 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4060 break;
4061 */ /* other types of stations do not emit beacons */
4062 /* }
4064 if (adev->wep_restricted) {
4065 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4067 if (adev->cfgopt_dot11ShortPreambleOption) {
4068 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4070 if (adev->cfgopt_dot11PBCCOption) {
4071 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4073 if (adev->cfgopt_dot11ChannelAgility) {
4074 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4076 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4077 adev->capabilities, cap);
4078 adev->capabilities = cap;
4082 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4085 static void acx_s_select_opmode(acx_device_t * adev)
4087 int changed = 0;
4088 FN_ENTER;
4090 if (adev->interface.operating) {
4091 switch (adev->interface.type) {
4092 case IEEE80211_IF_TYPE_AP:
4093 if (adev->mode != ACX_MODE_3_AP)
4095 adev->mode = ACX_MODE_3_AP;
4096 changed = 1;
4098 break;
4099 case IEEE80211_IF_TYPE_IBSS:
4100 if (adev->mode != ACX_MODE_0_ADHOC)
4102 adev->mode = ACX_MODE_0_ADHOC;
4103 changed = 1;
4105 break;
4106 case IEEE80211_IF_TYPE_STA:
4107 if (adev->mode != ACX_MODE_2_STA)
4109 adev->mode = ACX_MODE_2_STA;
4110 changed = 1;
4112 break;
4113 case IEEE80211_IF_TYPE_WDS:
4114 default:
4115 if (adev->mode != ACX_MODE_OFF)
4117 adev->mode = ACX_MODE_OFF;
4118 changed = 1;
4120 break;
4122 } else {
4123 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4125 if (adev->mode != ACX_MODE_MONITOR)
4127 adev->mode = ACX_MODE_MONITOR;
4128 changed = 1;
4131 else
4133 if (adev->mode != ACX_MODE_OFF)
4135 adev->mode = ACX_MODE_OFF;
4136 changed = 1;
4140 if (changed)
4142 SET_BIT(adev->set_mask, GETSET_MODE);
4143 acx_s_update_card_settings(adev);
4144 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4147 FN_EXIT0;
4151 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4155 int acx_add_interface(struct ieee80211_hw *ieee,
4156 struct ieee80211_if_init_conf *conf)
4158 acx_device_t *adev = ieee2adev(ieee);
4159 unsigned long flags;
4160 int err = -EOPNOTSUPP;
4162 DECLARE_MAC_BUF(mac);
4164 FN_ENTER;
4165 acx_lock(adev, flags);
4167 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4168 adev->interface.monitor++;
4169 } else {
4170 if (adev->interface.operating)
4171 goto out_unlock;
4172 adev->interface.operating = 1;
4173 adev->interface.mac_addr = conf->mac_addr;
4174 adev->interface.type = conf->type;
4176 // adev->mode = conf->type;
4178 acx_unlock(adev, flags);
4180 if (adev->initialized)
4181 acx_s_select_opmode(adev);
4183 acx_lock(adev, flags);
4185 err = 0;
4187 acx_log(LOG_INFO, L_ANY, "Virtual interface added "
4188 "(type: 0x%08X, ID: %d, MAC: %s)\n",
4189 conf->type,
4190 adev->interface.if_id,
4191 print_mac(mac, conf->mac_addr));
4193 out_unlock:
4194 acx_unlock(adev, flags);
4196 FN_EXIT0;
4197 return err;
4200 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4204 void acx_remove_interface(struct ieee80211_hw *hw,
4205 struct ieee80211_if_init_conf *conf)
4207 acx_device_t *adev = ieee2adev(hw);
4209 DECLARE_MAC_BUF(mac);
4211 FN_ENTER;
4213 acx_sem_lock(adev);
4214 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4215 adev->interface.monitor--;
4216 // assert(bcm->interface.monitor >= 0);
4217 } else {
4218 adev->interface.operating = 0;
4221 acx_log(LOG_INFO, L_ANY, "Removing interface: %d %d\n",
4222 adev->interface.operating, conf->type);
4223 acx_sem_unlock(adev);
4225 if (adev->initialized)
4226 acx_s_select_opmode(adev);
4227 flush_scheduled_work();
4229 acx_log(LOG_INFO, L_ANY, "Virtual interface removed "
4230 "(type: 0x%08X, ID: %d, MAC: %s)\n",
4231 conf->type, adev->interface.if_id,
4232 print_mac(mac, conf->mac_addr));
4234 FN_EXIT0;
4237 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4241 int acx_net_reset(struct ieee80211_hw *ieee)
4243 acx_device_t *adev = ieee2adev(ieee);
4244 FN_ENTER;
4245 if (IS_PCI(adev))
4246 acxpci_s_reset_dev(adev);
4247 else
4248 TODO();
4250 FN_EXIT0;
4251 return 0;
4255 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4258 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4260 int result;
4262 FN_ENTER;
4264 acx_sem_lock(adev);
4265 adev->rx_status.channel = channel;
4266 adev->rx_status.freq = freq;
4268 adev->channel = channel;
4269 /* hmm, the following code part is strange, but this is how
4270 * it was being done before... */
4271 acx_log(LOG_DEBUG, L_IOCTL, "Changing to channel %d\n", channel);
4272 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4273 result = -EINPROGRESS; /* need to call commit handler */
4275 acx_sem_unlock(adev);
4276 FN_EXIT1(result);
4277 return result;
4281 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4284 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4286 acx_device_t *adev = ieee2adev(hw);
4287 unsigned long flags;
4289 FN_ENTER;
4291 acx_lock(adev, flags);
4292 //FIXME();
4293 if (!adev->initialized) {
4294 acx_unlock(adev, flags);
4295 return 0;
4297 if (conf->beacon_int != adev->beacon_interval)
4298 adev->beacon_interval = conf->beacon_int;
4299 if (conf->channel != adev->channel) {
4300 acx_unlock(adev, flags);
4301 acx_selectchannel(adev, conf->channel,conf->freq);
4302 acx_lock(adev, flags);
4303 /* acx_schedule_task(adev,
4304 ACX_TASKLET_UPDATE_CARD_CFG
4305 */ /*+ ACX_TASKLET_RESTART_SCAN */ /*);*/
4308 if (conf->short_slot_time != adev->short_slot) {
4309 // assert(phy->type == BCM43xx_PHYTYPE_G);
4310 if (conf->short_slot_time)
4311 acx_short_slot_timing_enable(adev);
4312 else
4313 acx_short_slot_timing_disable(adev);
4314 acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4317 adev->tx_disabled = !conf->radio_enabled;
4318 /* if (conf->power_level != 0){
4319 adev->tx_level_dbm = conf->power_level;
4320 acx_s_set_tx_level(adev, adev->tx_level_dbm);
4321 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4322 //acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4325 //FIXME: This does not seem to wake up:
4326 #if 0
4327 if (conf->power_level == 0) {
4328 if (radio->enabled)
4329 bcm43xx_radio_turn_off(bcm);
4330 } else {
4331 if (!radio->enabled)
4332 bcm43xx_radio_turn_on(bcm);
4334 #endif
4336 //TODO: phymode
4337 //TODO: antennas
4338 if (adev->set_mask > 0) {
4339 acx_unlock(adev, flags);
4340 acx_s_update_card_settings(adev);
4341 acx_lock(adev, flags);
4343 acx_unlock(adev, flags);
4345 FN_EXIT0;
4346 return 0;
4350 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4354 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
4355 extern int acx_config_interface(struct ieee80211_hw* ieee,
4356 struct ieee80211_vif *vif,
4357 struct ieee80211_if_conf *conf)
4359 acx_device_t *adev = ieee2adev(ieee);
4360 unsigned long flags;
4361 int err = -ENODEV;
4362 FN_ENTER;
4363 if (!adev->interface.operating)
4364 goto err_out;
4366 if (adev->initialized)
4367 acx_s_select_opmode(adev);
4369 acx_lock(adev, flags);
4371 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4372 && (adev->vif == vif)) {
4373 if (conf->bssid)
4375 adev->interface.bssid = conf->bssid;
4376 MAC_COPY(adev->bssid,conf->bssid);
4379 if ((conf->type == IEEE80211_IF_TYPE_AP)
4380 && (adev->vif == vif)) {
4381 #else
4382 int acx_config_interface(struct ieee80211_hw* ieee, int if_id,
4383 struct ieee80211_if_conf *conf)
4385 acx_device_t *adev = ieee2adev(ieee);
4386 unsigned long flags;
4387 int err = -ENODEV;
4388 FN_ENTER;
4389 if (!adev->interface.operating)
4390 goto err_out;
4392 if (adev->initialized)
4393 acx_s_select_opmode(adev);
4395 acx_lock(adev, flags);
4397 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4398 && (adev->interface.if_id == if_id)) {
4399 if (conf->bssid)
4401 adev->interface.bssid = conf->bssid;
4402 MAC_COPY(adev->bssid,conf->bssid);
4405 if ((conf->type == IEEE80211_IF_TYPE_AP)
4406 && (adev->interface.if_id == if_id)) {
4407 #endif
4409 if ((conf->ssid_len > 0) && conf->ssid)
4411 adev->essid_len = conf->ssid_len;
4412 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4413 SET_BIT(adev->set_mask, SET_TEMPLATES);
4416 if (conf->beacon != 0)
4418 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4419 adev->beacon_cache = conf->beacon;
4420 SET_BIT(adev->set_mask, SET_TEMPLATES);
4423 acx_unlock(adev, flags);
4425 if (adev->set_mask != 0)
4426 acx_s_update_card_settings(adev);
4427 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4428 err = 0;
4429 err_out:
4430 FN_EXIT1(err);
4431 return err;
4435 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4439 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4440 struct ieee80211_tx_queue_stats *stats)
4442 // acx_device_t *adev = ndev2adev(net_dev);
4443 struct ieee80211_tx_queue_stats_data *data;
4444 int err = -ENODEV;
4446 FN_ENTER;
4448 // acx_lock(adev, flags);
4449 data = &(stats->data[0]);
4450 data->len = 0;
4451 data->limit = TX_CNT;
4452 data->count = 0;
4453 // acx_unlock(adev, flags);
4455 FN_EXIT0;
4456 return err;
4459 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4463 int acx_net_conf_tx(struct ieee80211_hw *hw,
4464 int queue, const struct ieee80211_tx_queue_params *params)
4466 FN_ENTER;
4467 // TODO();
4468 FN_EXIT0;
4469 return 0;
4472 static void keymac_write(acx_device_t * adev, u16 index, const u32 * addr)
4474 /* for keys 0-3 there is no associated mac address */
4475 if (index < 4)
4476 return;
4478 index -= 4;
4479 if (1) {
4480 TODO();
4482 bcm43xx_shm_write32(bcm,
4483 BCM43xx_SHM_HWMAC,
4484 index * 2,
4485 cpu_to_be32(*addr));
4486 bcm43xx_shm_write16(bcm,
4487 BCM43xx_SHM_HWMAC,
4488 (index * 2) + 1,
4489 cpu_to_be16(*((u16 *)(addr + 1))));
4491 } else {
4492 if (index < 8) {
4493 TODO(); /* Put them in the macaddress filter */
4494 } else {
4495 TODO();
4496 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4497 Keep in mind to update the count of keymacs in 0x003 */
4503 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4507 int acx_clear_keys(acx_device_t * adev)
4509 static const u32 zero_mac[2] = { 0 };
4510 unsigned int i, j, nr_keys = 54;
4511 u16 offset;
4513 /* FixMe:Check for Number of Keys available */
4515 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4517 for (i = 0; i < nr_keys; i++) {
4518 adev->key[i].enabled = 0;
4519 /* returns for i < 4 immediately */
4520 keymac_write(adev, i, zero_mac);
4522 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4523 0x100 + (i * 2), 0x0000);
4525 for (j = 0; j < 8; j++) {
4526 offset =
4527 adev->security_offset + (j * 4) +
4528 (i * ACX_SEC_KEYSIZE);
4530 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4531 offset, 0x0000);
4535 return 1;
4539 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4543 int acx_key_write(acx_device_t * adev,
4544 u16 index, u8 algorithm,
4545 const struct ieee80211_key_conf *key, const u8 * mac_addr)
4547 // struct iw_point *dwrq = &wrqu->encoding;
4548 int result;
4550 FN_ENTER;
4552 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4553 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4555 // acx_sem_lock(adev);
4557 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4558 if (key->keylen > 0) {
4559 /* if index is 0 or invalid, use default key */
4560 if (index > 3)
4561 index = (int)adev->wep_current_index;
4562 if ((algorithm == ACX_SEC_ALGO_WEP) ||
4563 (algorithm == ACX_SEC_ALGO_WEP104)) {
4564 switch(key->keylen) {
4565 case 40 / 8:
4566 /* WEP 40-bit =
4567 40-bit entered key + 24 bit IV = 64-bit */
4568 adev->wep_keys[index].size = 13;
4569 break;
4570 case 104 / 8:
4571 /* WEP 104-bit =
4572 104-bit entered key + 24-bit IV = 128-bit */
4573 adev->wep_keys[index].size = 29;
4574 break;
4575 case 128 / 8:
4576 /* WEP 128-bit =
4577 128-bit entered key + 24 bit IV = 152-bit */
4578 adev->wep_keys[index].size = 16;
4579 break;
4580 default:
4581 adev->wep_keys[index].size = 0;
4582 return -EINVAL; /* shouldn't happen */
4585 memset(adev->wep_keys[index].key, 0,
4586 sizeof(adev->wep_keys[index].key));
4587 memcpy(adev->wep_keys[index].key, key, key->keylen);
4588 } else {
4589 /* set transmit key */
4590 if (index <= 3)
4591 adev->wep_current_index = index;
4592 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4593 /* complain if we were not just setting
4594 * the key mode */
4595 // result = -EINVAL;
4596 // goto end_unlock;
4597 // }
4601 adev->wep_enabled = (algorithm == ALG_WEP);
4603 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4605 if (algorithm & IW_ENCODE_OPEN) {
4606 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4607 adev->wep_restricted = 0;
4609 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4610 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4611 adev->wep_restricted = 1;
4614 // adev->auth_alg = algorithm;
4615 /* set flag to make sure the card WEP settings get updated */
4616 if (adev->wep_enabled) {
4617 SET_BIT(adev->set_mask, GETSET_WEP);
4618 acx_s_update_card_settings(adev);
4619 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4622 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4623 dwrq->length, extra, dwrq->flags);
4624 for (index = 0; index <= 3; index++) {
4625 if (adev->wep_keys[index].size) {
4626 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4627 adev->wep_keys[index].index,
4628 (int) adev->wep_keys[index].size,
4629 adev->wep_keys[index].key);
4633 result = -EINPROGRESS;
4634 // acx_sem_unlock(adev);
4636 FN_EXIT1(result);
4637 return result;
4643 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4647 int acx_net_set_key(struct ieee80211_hw *ieee,
4648 enum set_key_cmd cmd, const u8 *local_addr,
4649 const u8 * addr, struct ieee80211_key_conf *key)
4651 // return 0;
4652 struct acx_device *adev = ieee2adev(ieee);
4653 unsigned long flags;
4654 u8 algorithm;
4655 u16 index;
4656 int err = -EINVAL;
4657 FN_ENTER;
4658 // TODO();
4659 switch (key->alg) {
4660 default:
4661 /* case ALG_NONE:
4662 case ALG_NULL:
4663 algorithm = ACX_SEC_ALGO_NONE;
4664 break;
4665 */ case ALG_WEP:
4666 if (key->keylen == 5)
4667 algorithm = ACX_SEC_ALGO_WEP;
4668 else
4669 algorithm = ACX_SEC_ALGO_WEP104;
4670 break;
4671 case ALG_TKIP:
4672 algorithm = ACX_SEC_ALGO_TKIP;
4673 break;
4674 case ALG_CCMP:
4675 algorithm = ACX_SEC_ALGO_AES;
4676 break;
4679 index = (u8) (key->keyidx);
4680 if (index >= ARRAY_SIZE(adev->key))
4681 goto out;
4682 acx_lock(adev, flags);
4683 switch (cmd) {
4684 case SET_KEY:
4685 err = acx_key_write(adev, index, algorithm, key, addr);
4686 if (err)
4687 goto out_unlock;
4688 key->hw_key_idx = index;
4689 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4690 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4691 adev->default_key_idx = index;*/
4692 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4693 adev->key[index].enabled = 1;
4694 break;
4695 case DISABLE_KEY:
4696 adev->key[index].enabled = 0;
4697 err = 0;
4698 break;
4699 /* case ENABLE_COMPRESSION:
4700 case DISABLE_COMPRESSION:
4701 err = 0;
4702 break; */
4704 out_unlock:
4705 acx_unlock(adev, flags);
4706 out:
4707 FN_EXIT0;
4708 return err;
4713 /***********************************************************************
4714 ** Common function to parse ALL configoption struct formats
4715 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4716 ** FIXME: logging should be removed here and added to a /proc file instead
4718 ** Look into bcm43xx
4720 void
4721 acx_s_parse_configoption(acx_device_t * adev,
4722 const acx111_ie_configoption_t * pcfg)
4724 const u8 *pEle;
4725 int i;
4726 int is_acx111 = IS_ACX111(adev);
4728 acx_log_dump(LOG_DEBUG, L_REALLYVERBOSE, pcfg, sizeof(*pcfg),
4729 "configoption struct content:\n");
4731 if ((is_acx111 && (adev->eeprom_version == 5))
4732 || (!is_acx111 && (adev->eeprom_version == 4))
4733 || (!is_acx111 && (adev->eeprom_version == 5))) {
4734 /* these versions are known to be supported */
4735 } else {
4736 acx_log(LOG_WARNING, L_ANY,
4737 "unknown chip and EEPROM version combination "
4738 "(%s, v%d), "
4739 "don't know how to parse config options yet. "
4740 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4741 adev->eeprom_version);
4742 return;
4745 /* first custom-parse the first part which has chip-specific layout */
4747 pEle = (const u8 *)pcfg;
4749 pEle += 4; /* skip (type,len) header */
4751 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4752 pEle += sizeof(adev->cfgopt_NVSv);
4754 if (is_acx111) {
4755 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4756 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4758 adev->cfgopt_probe_delay = 200; /* good default value? */
4759 pEle += 2; /* FIXME: unknown, value 0x0001 */
4760 } else {
4761 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4762 pEle += sizeof(adev->cfgopt_MAC);
4764 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4765 pEle += sizeof(adev->cfgopt_probe_delay);
4766 if ((adev->cfgopt_probe_delay < 100)
4767 || (adev->cfgopt_probe_delay > 500)) {
4768 acx_log(LOG_WARNING, L_ANY,
4769 "strange probe_delay value %d, "
4770 "tweaking to 200\n", adev->cfgopt_probe_delay);
4771 adev->cfgopt_probe_delay = 200;
4775 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4776 pEle += sizeof(adev->cfgopt_eof_memory);
4778 acx_log(LOG_INFO, L_ANY, "NVS_vendor_offs:%04X probe_delay:%d "
4779 "eof_memory:%d\n",
4780 adev->cfgopt_NVS_vendor_offs, adev->cfgopt_probe_delay,
4781 adev->cfgopt_eof_memory);
4783 adev->cfgopt_dot11CCAModes = *pEle++;
4784 adev->cfgopt_dot11Diversity = *pEle++;
4785 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4786 adev->cfgopt_dot11PBCCOption = *pEle++;
4787 adev->cfgopt_dot11ChannelAgility = *pEle++;
4788 adev->cfgopt_dot11PhyType = *pEle++;
4789 adev->cfgopt_dot11TempType = *pEle++;
4790 acx_log(LOG_INFO, L_ANY,
4791 "CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4792 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4793 adev->cfgopt_dot11CCAModes, adev->cfgopt_dot11Diversity,
4794 adev->cfgopt_dot11ShortPreambleOption,
4795 adev->cfgopt_dot11PBCCOption, adev->cfgopt_dot11ChannelAgility,
4796 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4798 /* then use common parsing for next part which has common layout */
4800 pEle++; /* skip table_count (6) */
4802 adev->cfgopt_antennas.type = pEle[0];
4803 adev->cfgopt_antennas.len = pEle[1];
4806 * FIXME: a candidate for acx_log_dump(), but the code is bizarre
4808 acx_log(LOG_INFO, L_ANY, "AntennaID:%02X Len:%02X Data:",
4809 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4810 for (i = 0; i < pEle[1]; i++) {
4811 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4812 printk("%02X ", pEle[i + 2]);
4814 printk("\n");
4816 pEle += pEle[1] + 2;
4817 adev->cfgopt_power_levels.type = pEle[0];
4818 adev->cfgopt_power_levels.len = pEle[1];
4821 * FIXME: see above
4823 acx_log(LOG_INFO, L_ANY, "PowerLevelID:%02X Len:%02X Data:\n",
4824 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4825 for (i = 0; i < pEle[1]; i++) {
4826 adev->cfgopt_power_levels.list[i] =
4827 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4828 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4830 printk("\n");
4832 pEle += pEle[1] * 2 + 2;
4833 adev->cfgopt_data_rates.type = pEle[0];
4834 adev->cfgopt_data_rates.len = pEle[1];
4837 * FIXME again
4839 acx_log(LOG_INFO, L_ANY, "DataRatesID:%02X Len:%02X Data:\n",
4840 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4841 for (i = 0; i < pEle[1]; i++) {
4842 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4843 printk("%02X ", pEle[i + 2]);
4845 printk("\n");
4847 pEle += pEle[1] + 2;
4848 adev->cfgopt_domains.type = pEle[0];
4849 adev->cfgopt_domains.len = pEle[1];
4852 * And again
4854 acx_log(LOG_INFO, L_ANY, "DomainID:%02X Len:%02X Data:\n",
4855 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4856 for (i = 0; i < pEle[1]; i++) {
4857 adev->cfgopt_domains.list[i] = pEle[i + 2];
4858 printk("%02X ", pEle[i + 2]);
4860 printk("\n");
4862 pEle += pEle[1] + 2;
4863 adev->cfgopt_product_id.type = pEle[0];
4864 adev->cfgopt_product_id.len = pEle[1];
4865 for (i = 0; i < pEle[1]; i++) {
4866 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4868 acx_log(LOG_INFO, L_ANY, "ProductID:%02X Len:%02X Data:%.*s\n",
4869 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4870 adev->cfgopt_product_id.len,
4871 (char *)adev->cfgopt_product_id.list);
4873 pEle += pEle[1] + 2;
4874 adev->cfgopt_manufacturer.type = pEle[0];
4875 adev->cfgopt_manufacturer.len = pEle[1];
4876 for (i = 0; i < pEle[1]; i++) {
4877 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4879 acx_log(LOG_INFO, L_ANY, "ManufacturerID:%02X Len:%02X Data:%.*s\n",
4880 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4881 adev->cfgopt_manufacturer.len,
4882 (char *)adev->cfgopt_manufacturer.list);
4884 printk("EEPROM part:\n");
4885 for (i=0; i<58; i++) {
4886 printk("%02X =======> 0x%02X\n",
4887 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4893 /***********************************************************************
4894 ** Linux Kernel Specific
4896 static int __init acx_e_init_module(void)
4898 int r1, r2;
4900 acx_struct_size_check();
4902 acx_log(LOG_INFO, L_ANY, "this driver is still EXPERIMENTAL\n");
4903 acx_log(LOG_INFO, L_ANY, "please read the README file and/or "
4904 "go to http://acx100.sourceforge.net/wiki for "
4905 "further information\n");
4907 #if defined(CONFIG_ACX_MAC80211_PCI)
4908 r1 = acxpci_e_init_module();
4909 #else
4910 r1 = -EINVAL;
4911 #endif
4912 #if defined(CONFIG_ACX_MAC80211_USB)
4913 r2 = acxusb_e_init_module();
4914 #else
4915 r2 = -EINVAL;
4916 #endif
4917 if (r2 && r1) /* both failed! */
4918 return r2 ? r2 : r1;
4919 /* return success if at least one succeeded */
4920 return 0;
4923 static void __exit acx_e_cleanup_module(void)
4925 #if defined(CONFIG_ACX_MAC80211_PCI)
4926 acxpci_e_cleanup_module();
4927 #endif
4928 #if defined(CONFIG_ACX_MAC80211_USB)
4929 acxusb_e_cleanup_module();
4930 #endif
4933 module_init(acx_e_init_module)
4934 module_exit(acx_e_cleanup_module)