common.c: change MODULE_LICENSE
[acx-mac80211.git] / common.c
blob868c0211f6553974ed9a3d4c1d56a059b2d66097
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"
31 /***********************************************************************
34 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf);
38 /***********************************************************************
40 #if ACX_DEBUG
41 unsigned int acx_debug /* will add __read_mostly later */ = ACX_DEFAULT_MSG;
42 /* parameter is 'debug', corresponding var is acx_debug */
43 module_param_named(debug, acx_debug, uint, 0);
44 MODULE_PARM_DESC(debug, "Debug level mask (see L_xxx constants)");
45 #endif
47 #ifdef MODULE_LICENSE
48 MODULE_LICENSE("GPLv2");
49 #endif
50 /* USB had this: MODULE_AUTHOR("Martin Wawro <martin.wawro AT uni-dortmund.de>"); */
51 MODULE_AUTHOR("ACX100 Open Source Driver development team");
52 MODULE_DESCRIPTION
53 ("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)");
55 #ifdef MODULE_VERSION
56 MODULE_VERSION(ACX_RELEASE);
57 #endif
59 /***********************************************************************
61 /* Probably a number of acx's intermediate buffers for USB transfers,
62 ** not to be confused with number of descriptors in tx/rx rings
63 ** (which are not directly accessible to host in USB devices) */
64 #define USB_RX_CNT 10
65 #define USB_TX_CNT 10
68 /***********************************************************************
71 /* minutes to wait until next radio recalibration: */
72 #define RECALIB_PAUSE 5
74 /* Please keep acx_reg_domain_ids_len in sync... */
75 const u8 acx_reg_domain_ids[acx_reg_domain_ids_len] =
76 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 };
77 static const u16 reg_domain_channel_masks[acx_reg_domain_ids_len] =
78 { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc };
79 const char *const
80 acx_reg_domain_strings[] = {
81 /* 0 */ " 1-11 FCC (USA)",
82 /* 1 */ " 1-11 DOC/IC (Canada)",
83 /* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */
84 /* 2 */ " 1-13 ETSI (Europe)",
85 /* 3 */ "10-11 Spain",
86 /* 4 */ "10-13 France",
87 /* 5 */ " 14 MKK (Japan)",
88 /* 6 */ " 1-14 MKK1",
89 /* 7 */ " 3-9 Israel (not all firmware versions)",
90 NULL /* needs to remain as last entry */
95 /***********************************************************************
96 ** Debugging support
98 #ifdef PARANOID_LOCKING
99 static unsigned max_lock_time;
100 static unsigned max_sem_time;
102 /* Obvious or linux kernel specific derived code follows: */
104 void acx_lock_unhold()
106 max_lock_time = 0;
109 void acx_sem_unhold()
111 max_sem_time = 0;
114 static inline const char *sanitize_str(const char *s)
116 const char *t = strrchr(s, '/');
117 if (t)
118 return t + 1;
119 return s;
122 void acx_lock_debug(acx_device_t * adev, const char *where)
124 unsigned int count = 100 * 1000 * 1000;
125 where = sanitize_str(where);
126 while (--count) {
127 if (!spin_is_locked(&adev->spinlock))
128 break;
129 cpu_relax();
131 if (!count) {
132 printk(KERN_EMERG "LOCKUP: already taken at %s!\n",
133 adev->last_lock);
134 BUG();
136 adev->last_lock = where;
137 rdtscl(adev->lock_time);
140 void acx_unlock_debug(acx_device_t * adev, const char *where)
142 #ifdef SMP
143 if (!spin_is_locked(&adev->spinlock)) {
144 where = sanitize_str(where);
145 printk(KERN_EMERG "STRAY UNLOCK at %s!\n", where);
146 BUG();
148 #endif
149 if (acx_debug & L_LOCK) {
150 unsigned long diff;
151 rdtscl(diff);
152 diff -= adev->lock_time;
153 if (diff > max_lock_time) {
154 where = sanitize_str(where);
155 acx_log(LOG_DEBUG, L_LOCK, "max lock hold time "
156 "%ld CPU ticks from %s to %s\n", diff,
157 adev->last_lock, where);
158 max_lock_time = diff;
162 #endif /* PARANOID_LOCKING */
166 /***********************************************************************
167 ** Basically a mdelay/msleep with logging
169 void acx_s_mwait(int ms)
171 FN_ENTER;
172 #ifdef CONFIG_X86
173 mdelay(ms);
174 #else
175 msleep(ms);
176 #endif
177 FN_EXIT0;
181 /***********************************************************************
182 ** Not inlined: it's larger than it seems
184 void acx_print_mac(const char *head, const u8 * mac, const char *tail)
186 printk("%s" MACSTR "%s", head, MAC(mac), tail);
192 /***********************************************************************
193 ** acx_cmd_status_str
195 const char *acx_cmd_status_str(unsigned int state)
197 static const char *const cmd_error_strings[] = {
198 "Idle",
199 "Success",
200 "Unknown Command",
201 "Invalid Information Element",
202 "Channel rejected",
203 "Channel invalid in current regulatory domain",
204 "MAC invalid",
205 "Command rejected (read-only information element)",
206 "Command rejected",
207 "Already asleep",
208 "TX in progress",
209 "Already awake",
210 "Write only",
211 "RX in progress",
212 "Invalid parameter",
213 "Scan in progress",
214 "Failed"
216 return state < ARRAY_SIZE(cmd_error_strings) ?
217 cmd_error_strings[state] : "?";
220 /***********************************************************************
221 ** acx_s_get_firmware_version
223 ** Obvious
225 void acx_s_get_firmware_version(acx_device_t * adev)
227 fw_ver_t fw;
228 u8 hexarr[4] = { 0, 0, 0, 0 };
229 int hexidx = 0, val = 0;
230 const char *num;
231 char c;
233 FN_ENTER;
235 memset(fw.fw_id, 'E', FW_ID_SIZE);
236 acx_s_interrogate(adev, &fw, ACX1xx_IE_FWREV);
237 memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE);
238 adev->firmware_version[FW_ID_SIZE] = '\0';
240 acx_log(LOG_DEBUG, L_ANY, "fw_ver: fw_id='%s' hw_id=%08X\n",
241 adev->firmware_version, fw.hw_id);
243 if (strncmp(fw.fw_id, "Rev ", 4) != 0) {
244 acx_log(LOG_WARNING, L_ANY, "acx: strange firmware version string "
245 "'%s', please report\n", adev->firmware_version);
246 adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */
247 } else {
248 num = &fw.fw_id[4];
249 while (1) {
250 c = *num++;
251 if ((c == '.') || (c == '\0')) {
252 hexarr[hexidx++] = val;
253 if ((hexidx > 3) || (c == '\0')) /* end? */
254 break;
255 val = 0;
256 continue;
258 if ((c >= '0') && (c <= '9'))
259 c -= '0';
260 else
261 c = c - 'a' + (char)10;
262 val = val * 16 + c;
265 adev->firmware_numver = (u32) ((hexarr[0] << 24) |
266 (hexarr[1] << 16)
267 | (hexarr[2] << 8) | hexarr[3]);
268 acx_log(LOG_DEBUG, L_ANY, "firmware_numver 0x%08X\n",
269 adev->firmware_numver);
271 if (IS_ACX111(adev)) {
272 if (adev->firmware_numver == 0x00010011) {
273 /* This one does not survive floodpinging */
274 acx_log(LOG_WARNING, L_ANY, "firmware '%s' is known "
275 "to be buggy, please upgrade\n",
276 adev->firmware_version);
280 adev->firmware_id = le32_to_cpu(fw.hw_id);
282 /* we're able to find out more detailed chip names now */
283 switch (adev->firmware_id & 0xffff0000) {
284 case 0x01010000:
285 case 0x01020000:
286 adev->chip_name = "TNETW1100A";
287 break;
288 case 0x01030000:
289 adev->chip_name = "TNETW1100B";
290 break;
291 case 0x03000000:
292 case 0x03010000:
293 adev->chip_name = "TNETW1130";
294 break;
295 case 0x04030000: /* 0x04030101 is TNETW1450 */
296 adev->chip_name = "TNETW1450";
297 break;
298 default:
299 acx_log(LOG_WARNING, L_ANY,"unknown chip ID 0x%08X, "
300 "please report\n", adev->firmware_id);
301 break;
304 FN_EXIT0;
308 /***********************************************************************
309 ** acx_display_hardware_details
311 ** Displays hw/fw version, radio type etc...
313 ** Obvious
315 void acx_display_hardware_details(acx_device_t * adev)
317 const char *radio_str, *form_str;
319 FN_ENTER;
321 switch (adev->radio_type) {
322 case RADIO_MAXIM_0D:
323 radio_str = "Maxim";
324 break;
325 case RADIO_RFMD_11:
326 radio_str = "RFMD";
327 break;
328 case RADIO_RALINK_15:
329 radio_str = "Ralink";
330 break;
331 case RADIO_RADIA_16:
332 radio_str = "Radia";
333 break;
334 case RADIO_UNKNOWN_17:
335 /* TI seems to have a radio which is
336 * additionally 802.11a capable, too */
337 radio_str = "802.11a/b/g radio?! Please report";
338 break;
339 case RADIO_UNKNOWN_19:
340 radio_str = "A radio used by Safecom cards?! Please report";
341 break;
342 case RADIO_UNKNOWN_1B:
343 radio_str = "An unknown radio used by TNETW1450 USB adapters";
344 break;
345 default:
346 radio_str = "UNKNOWN, please report radio type name!";
347 break;
350 switch (adev->form_factor) {
351 case 0x00:
352 form_str = "unspecified";
353 break;
354 case 0x01:
355 form_str = "(mini-)PCI / CardBus";
356 break;
357 case 0x02:
358 form_str = "USB";
359 break;
360 case 0x03:
361 form_str = "Compact Flash";
362 break;
363 default:
364 form_str = "UNKNOWN, please report";
365 break;
368 acx_log(LOG_INFO, L_ANY, "acx: chipset %s, radio type 0x%02X (%s), "
369 "form factor 0x%02X (%s), EEPROM version 0x%02X, "
370 "uploaded firmware '%s'\n",
371 adev->chip_name, adev->radio_type, radio_str,
372 adev->form_factor, form_str, adev->eeprom_version,
373 adev->firmware_version);
375 FN_EXIT0;
379 /***********************************************************************
380 ** acx_e_get_stats, acx_e_get_wireless_stats
383 acx_e_get_stats(struct ieee80211_hw *hw,
384 struct ieee80211_low_level_stats *stats)
386 acx_device_t *adev = ieee2adev(hw);
387 unsigned long flags;
388 acx_lock(adev, flags);
389 memcpy(stats, &adev->ieee_stats, sizeof(*stats));
390 acx_unlock(adev, flags);
391 return 0;
395 /***********************************************************************
396 ** maps acx111 tx descr rate field to acx100 one
398 const u8 acx_bitpos2rate100[] = {
399 RATE100_1, /* 0 */
400 RATE100_2, /* 1 */
401 RATE100_5, /* 2 */
402 RATE100_2, /* 3, should not happen */
403 RATE100_2, /* 4, should not happen */
404 RATE100_11, /* 5 */
405 RATE100_2, /* 6, should not happen */
406 RATE100_2, /* 7, should not happen */
407 RATE100_22, /* 8 */
408 RATE100_2, /* 9, should not happen */
409 RATE100_2, /* 10, should not happen */
410 RATE100_2, /* 11, should not happen */
411 RATE100_2, /* 12, should not happen */
412 RATE100_2, /* 13, should not happen */
413 RATE100_2, /* 14, should not happen */
414 RATE100_2, /* 15, should not happen */
417 u8 acx_rate111to100(u16 r)
419 return acx_bitpos2rate100[highest_bit(r)];
423 /***********************************************************************
424 ** Calculate level like the feb 2003 windows driver seems to do
426 static u8 acx_signal_to_winlevel(u8 rawlevel)
428 /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
429 u8 winlevel = ((4 + (rawlevel * 5)) / 8);
431 if (winlevel > 100)
432 winlevel = 100;
433 return winlevel;
436 u8 acx_signal_determine_quality(u8 signal, u8 noise)
438 int qual;
440 qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2;
442 if (qual > 100)
443 return 100;
444 if (qual < 0)
445 return 0;
446 return qual;
450 /***********************************************************************
451 ** Interrogate/configure commands
454 /* FIXME: the lengths given here probably aren't always correct.
455 * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4",
456 * unless the firmware actually expects a different length than the struct length */
457 static const u16 acx100_ie_len[] = {
459 ACX100_IE_ACX_TIMER_LEN,
460 sizeof(acx100_ie_powersave_t) - 4, /* is that 6 or 8??? */
461 ACX1xx_IE_QUEUE_CONFIG_LEN,
462 ACX100_IE_BLOCK_SIZE_LEN,
463 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
464 ACX1xx_IE_RATE_FALLBACK_LEN,
465 ACX100_IE_WEP_OPTIONS_LEN,
466 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
468 ACX1xx_IE_ASSOC_ID_LEN,
470 ACX111_IE_CONFIG_OPTIONS_LEN,
471 ACX1xx_IE_FWREV_LEN,
472 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
473 ACX1xx_IE_MEDIUM_USAGE_LEN,
474 ACX1xx_IE_RXCONFIG_LEN,
477 sizeof(fw_stats_t) - 4,
479 ACX1xx_IE_FEATURE_CONFIG_LEN,
480 ACX111_IE_KEY_CHOOSE_LEN,
481 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
482 ACX1FF_IE_WONE_CONFIG_LEN,
484 ACX1FF_IE_TID_CONFIG_LEN,
488 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
489 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
490 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
491 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
493 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
494 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
495 ACX1FF_IE_CCA_THRESHOLD_LEN,
496 ACX1FF_IE_EVENT_MASK_LEN,
497 ACX1FF_IE_DTIM_PERIOD_LEN,
499 ACX1FF_IE_ACI_CONFIG_SET_LEN,
506 ACX1FF_IE_EEPROM_VER_LEN,
509 static const u16 acx100_ie_len_dot11[] = {
511 ACX1xx_IE_DOT11_STATION_ID_LEN,
513 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
514 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
515 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
516 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
517 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
518 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
520 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
521 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
523 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
524 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
525 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
526 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
532 static const u16 acx111_ie_len[] = {
534 ACX100_IE_ACX_TIMER_LEN,
535 sizeof(acx111_ie_powersave_t) - 4,
536 ACX1xx_IE_QUEUE_CONFIG_LEN,
537 ACX100_IE_BLOCK_SIZE_LEN,
538 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
539 ACX1xx_IE_RATE_FALLBACK_LEN,
540 ACX100_IE_WEP_OPTIONS_LEN,
541 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
543 ACX1xx_IE_ASSOC_ID_LEN,
545 ACX111_IE_CONFIG_OPTIONS_LEN,
546 ACX1xx_IE_FWREV_LEN,
547 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
548 ACX1xx_IE_MEDIUM_USAGE_LEN,
549 ACX1xx_IE_RXCONFIG_LEN,
552 sizeof(fw_stats_t) - 4,
554 ACX1xx_IE_FEATURE_CONFIG_LEN,
555 ACX111_IE_KEY_CHOOSE_LEN,
556 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
557 ACX1FF_IE_WONE_CONFIG_LEN,
559 ACX1FF_IE_TID_CONFIG_LEN,
563 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
564 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
565 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
566 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
568 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
569 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
570 ACX1FF_IE_CCA_THRESHOLD_LEN,
571 ACX1FF_IE_EVENT_MASK_LEN,
572 ACX1FF_IE_DTIM_PERIOD_LEN,
574 ACX1FF_IE_ACI_CONFIG_SET_LEN,
581 ACX1FF_IE_EEPROM_VER_LEN,
584 static const u16 acx111_ie_len_dot11[] = {
586 ACX1xx_IE_DOT11_STATION_ID_LEN,
588 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
589 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
590 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
591 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
592 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
593 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
595 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
596 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
598 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
599 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
600 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
601 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
608 #undef FUNC
609 #define FUNC "configure"
610 #if !ACX_DEBUG
611 int acx_s_configure(acx_device_t * adev, void *pdr, int type)
613 #else
615 acx_s_configure_debug(acx_device_t * adev, void *pdr, int type,
616 const char *typestr)
618 #endif
619 u16 len;
620 int res;
622 if (type < 0x1000)
623 len = adev->ie_len[type];
624 else
625 len = adev->ie_len_dot11[type - 0x1000];
627 acx_log(LOG_DEBUG, L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
628 if (unlikely(!len)) {
629 acx_log(LOG_DEBUG, L_ANY, "zero-length type %s?!\n", typestr);
632 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
633 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
634 res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4);
635 if (unlikely(OK != res)) {
636 #if ACX_DEBUG
637 acx_log(LOG_WARNING, L_ANY, "%s: " FUNC "(type:%s) FAILED\n",
638 wiphy_name(adev->ieee->wiphy), typestr);
639 #else
640 acx_log(LOG_WARNING, L_ANY, "%s: " FUNC "(type:0x%X) FAILED\n",
641 wiphy_name(adev->ieee->wiphy), type);
642 #endif
643 /* dump_stack() is already done in issue_cmd() */
645 return res;
648 #undef FUNC
649 #define FUNC "interrogate"
650 #if !ACX_DEBUG
651 int acx_s_interrogate(acx_device_t * adev, void *pdr, int type)
653 #else
655 acx_s_interrogate_debug(acx_device_t * adev, void *pdr, int type,
656 const char *typestr)
658 #endif
659 u16 len;
660 int res;
662 FN_ENTER;
664 /* FIXME: no check whether this exceeds the array yet.
665 * We should probably remember the number of entries... */
666 if (type < 0x1000)
667 len = adev->ie_len[type];
668 else
669 len = adev->ie_len_dot11[type - 0x1000];
671 acx_log(LOG_DEBUG, L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
673 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
674 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
675 res = acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, pdr, len + 4);
676 if (unlikely(OK != res)) {
677 #if ACX_DEBUG
678 acx_log(LOG_WARNING, L_ANY, "%s: " FUNC "(type:%s) FAILED\n",
679 wiphy_name(adev->ieee->wiphy), typestr);
680 #else
681 acx_log(LOG_WARNING, L_ANY, "%s: " FUNC "(type:0x%X) FAILED\n",
682 wiphy_name(adev->ieee->wiphy), type);
683 #endif
684 /* dump_stack() is already done in issue_cmd() */
687 FN_EXIT1(res);
688 return res;
691 #if CMD_DISCOVERY
692 void great_inquisitor(acx_device_t * adev)
694 static struct {
695 u16 type;
696 u16 len;
697 /* 0x200 was too large here: */
698 u8 data[0x100 - 4];
699 } ACX_PACKED ie;
700 u16 type;
702 FN_ENTER;
704 /* 0..0x20, 0x1000..0x1020 */
705 for (type = 0; type <= 0x1020; type++) {
706 if (type == 0x21)
707 type = 0x1000;
708 ie.type = cpu_to_le16(type);
709 ie.len = cpu_to_le16(sizeof(ie) - 4);
710 acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie));
712 FN_EXIT0;
714 #endif
717 #ifdef CONFIG_PROC_FS
718 /***********************************************************************
719 ** /proc files
721 /***********************************************************************
722 ** acx_l_proc_output
723 ** Generate content for our /proc entry
725 ** Arguments:
726 ** buf is a pointer to write output to
727 ** adev is the usual pointer to our private struct acx_device
728 ** Returns:
729 ** number of bytes actually written to buf
730 ** Side effects:
731 ** none
733 static int acx_l_proc_output(char *buf, acx_device_t * adev)
735 char *p = buf;
737 FN_ENTER;
739 p += sprintf(p,
740 "acx driver version:\t\t" ACX_RELEASE "\n"
741 "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n"
742 "chip name:\t\t\t%s (0x%08X)\n"
743 "radio type:\t\t\t0x%02X\n"
744 "form factor:\t\t\t0x%02X\n"
745 "EEPROM version:\t\t\t0x%02X\n"
746 "firmware version:\t\t%s (0x%08X)\n",
747 adev->chip_name, adev->firmware_id,
748 adev->radio_type,
749 adev->form_factor,
750 adev->eeprom_version,
751 adev->firmware_version, adev->firmware_numver);
753 FN_EXIT1(p - buf);
754 return p - buf;
758 /***********************************************************************
760 static int acx_s_proc_diag_output(char *buf, acx_device_t * adev)
762 char *p = buf;
763 unsigned long flags;
764 ssize_t len = 0, partlen;
765 u32 temp1, temp2;
766 u8 *st, *st_end;
767 #ifdef __BIG_ENDIAN
768 u8 *st2;
769 #endif
770 fw_stats_t *fw_stats;
771 char *part_str = NULL;
772 fw_stats_tx_t *tx = NULL;
773 fw_stats_rx_t *rx = NULL;
774 fw_stats_dma_t *dma = NULL;
775 fw_stats_irq_t *irq = NULL;
776 fw_stats_wep_t *wep = NULL;
777 fw_stats_pwr_t *pwr = NULL;
778 fw_stats_mic_t *mic = NULL;
779 fw_stats_aes_t *aes = NULL;
780 fw_stats_event_t *evt = NULL;
782 FN_ENTER;
784 acx_lock(adev, flags);
786 if (IS_PCI(adev))
787 p = acxpci_s_proc_diag_output(p, adev);
789 p += sprintf(p,
790 "\n"
791 "** network status **\n"
792 "dev_state_mask 0x%04X\n"
793 "mode %u, channel %u, "
794 "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
795 adev->dev_state_mask,
796 adev->mode, adev->channel,
797 adev->reg_dom_id, adev->reg_dom_chanmask);
798 p += sprintf(p,
799 "ESSID \"%s\", essid_active %d, essid_len %d, "
800 "essid_for_assoc \"%s\", nick \"%s\"\n"
801 "WEP ena %d, restricted %d, idx %d\n",
802 adev->essid, adev->essid_active, (int)adev->essid_len,
803 adev->essid_for_assoc, adev->nick,
804 adev->wep_enabled, adev->wep_restricted,
805 adev->wep_current_index);
806 p += sprintf(p, "dev_addr " MACSTR "\n", MAC(adev->dev_addr));
807 p += sprintf(p, "bssid " MACSTR "\n", MAC(adev->bssid));
808 p += sprintf(p, "ap_filter " MACSTR "\n", MAC(adev->ap));
810 p += sprintf(p, "\n" "** PHY status **\n"
811 "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
812 "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
813 "rate_basic 0x%04X, rate_oper 0x%04X\n"
814 "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
815 "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
816 adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */
817 adev->sensitivity, adev->antenna, adev->ed_threshold,
818 adev->cca, adev->preamble_mode, adev->rate_basic, adev->rate_oper, adev->rts_threshold,
819 adev->frag_threshold, adev->short_retry, adev->long_retry,
820 adev->msdu_lifetime, adev->listen_interval,
821 adev->beacon_interval);
823 acx_unlock(adev, flags);
825 p += sprintf(p,
826 "\n"
827 "** Firmware **\n"
828 "NOTE: version dependent statistics layout, "
829 "please report if you suspect wrong parsing!\n"
830 "\n" "version \"%s\"\n", adev->firmware_version);
832 /* TODO: may replace kmalloc/memset with kzalloc once
833 * Linux 2.6.14 is widespread */
834 fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL);
835 if (!fw_stats) {
836 FN_EXIT1(0);
837 return 0;
839 memset(fw_stats, 0, sizeof(*fw_stats));
841 st = (u8 *) fw_stats;
843 part_str = "statistics query command";
845 if (OK != acx_s_interrogate(adev, st, ACX1xx_IE_FIRMWARE_STATISTICS))
846 goto fw_stats_end;
848 st += sizeof(u16);
849 len = *(u16 *) st;
851 if (len > sizeof(*fw_stats)) {
852 p += sprintf(p,
853 "firmware version with bigger fw_stats struct detected\n"
854 "(%zu vs. %zu), please report\n", len, sizeof(fw_stats_t));
855 if (len > sizeof(*fw_stats)) {
856 p += sprintf(p, "struct size exceeded allocation!\n");
857 len = sizeof(*fw_stats);
860 st += sizeof(u16);
861 st_end = st - 2 * sizeof(u16) + len;
863 #ifdef __BIG_ENDIAN
864 /* let's make one bold assumption here:
865 * (hopefully!) *all* statistics fields are u32 only,
866 * thus if we need to make endianness corrections
867 * we can simply do them in one go, in advance */
868 st2 = (u8 *) fw_stats;
869 for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4)
870 *(u32 *) st2 = le32_to_cpu(*(u32 *) st2);
871 #endif
873 part_str = "Rx/Tx";
875 /* directly at end of a struct part? --> no error! */
876 if (st == st_end)
877 goto fw_stats_end;
879 tx = (fw_stats_tx_t *) st;
880 st += sizeof(fw_stats_tx_t);
881 rx = (fw_stats_rx_t *) st;
882 st += sizeof(fw_stats_rx_t);
883 partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t);
885 if (IS_ACX100(adev)) {
886 /* at least ACX100 PCI F/W 1.9.8.b
887 * and ACX100 USB F/W 1.0.7-USB
888 * don't have those two fields... */
889 st -= 2 * sizeof(u32);
891 /* our parsing doesn't quite match this firmware yet,
892 * log failure */
893 if (st > st_end)
894 goto fw_stats_fail;
895 temp1 = temp2 = 999999999;
896 } else {
897 if (st > st_end)
898 goto fw_stats_fail;
899 temp1 = rx->rx_aci_events;
900 temp2 = rx->rx_aci_resets;
903 p += sprintf(p,
904 "%s:\n"
905 " tx_desc_overfl %u\n"
906 " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
907 " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n"
908 " rx_aci_events %u, rx_aci_resets %u\n",
909 part_str,
910 tx->tx_desc_of,
911 rx->rx_oom,
912 rx->rx_hdr_of,
913 rx->rx_hw_stuck,
914 rx->rx_dropped_frame,
915 rx->rx_frame_ptr_err, rx->rx_xfr_hint_trig, temp1, temp2);
917 part_str = "DMA";
919 if (st == st_end)
920 goto fw_stats_end;
922 dma = (fw_stats_dma_t *) st;
923 partlen = sizeof(fw_stats_dma_t);
924 st += partlen;
926 if (st > st_end)
927 goto fw_stats_fail;
929 p += sprintf(p,
930 "%s:\n"
931 " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n",
932 part_str,
933 dma->rx_dma_req,
934 dma->rx_dma_err, dma->tx_dma_req, dma->tx_dma_err);
936 part_str = "IRQ";
938 if (st == st_end)
939 goto fw_stats_end;
941 irq = (fw_stats_irq_t *) st;
942 partlen = sizeof(fw_stats_irq_t);
943 st += partlen;
945 if (st > st_end)
946 goto fw_stats_fail;
948 p += sprintf(p,
949 "%s:\n"
950 " cmd_cplt %u, fiq %u\n"
951 " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
952 " irqs %u, tx_procs %u, decrypt_done %u\n"
953 " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
954 " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
955 " host_acks %u, pci_pm %u, acm_wakeups %u\n",
956 part_str,
957 irq->cmd_cplt,
958 irq->fiq,
959 irq->rx_hdrs,
960 irq->rx_cmplt,
961 irq->rx_mem_of,
962 irq->rx_rdys,
963 irq->irqs,
964 irq->tx_procs,
965 irq->decrypt_done,
966 irq->dma_0_done,
967 irq->dma_1_done,
968 irq->tx_exch_complet,
969 irq->commands,
970 irq->rx_procs,
971 irq->hw_pm_mode_changes,
972 irq->host_acks, irq->pci_pm, irq->acm_wakeups);
974 part_str = "WEP";
976 if (st == st_end)
977 goto fw_stats_end;
979 wep = (fw_stats_wep_t *) st;
980 partlen = sizeof(fw_stats_wep_t);
981 st += partlen;
983 if ((IS_PCI(adev) && IS_ACX100(adev))
984 || (IS_USB(adev) && IS_ACX100(adev))
986 /* at least ACX100 PCI F/W 1.9.8.b
987 * and ACX100 USB F/W 1.0.7-USB
988 * don't have those two fields... */
989 st -= 2 * sizeof(u32);
990 if (st > st_end)
991 goto fw_stats_fail;
992 temp1 = temp2 = 999999999;
993 } else {
994 if (st > st_end)
995 goto fw_stats_fail;
996 temp1 = wep->wep_pkt_decrypt;
997 temp2 = wep->wep_decrypt_irqs;
1000 p += sprintf(p,
1001 "%s:\n"
1002 " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
1003 " wep_key_not_found %u, wep_decrypt_fail %u\n"
1004 " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
1005 part_str,
1006 wep->wep_key_count,
1007 wep->wep_default_key_count,
1008 wep->dot11_def_key_mib,
1009 wep->wep_key_not_found,
1010 wep->wep_decrypt_fail, temp1, temp2);
1012 part_str = "power";
1014 if (st == st_end)
1015 goto fw_stats_end;
1017 pwr = (fw_stats_pwr_t *) st;
1018 partlen = sizeof(fw_stats_pwr_t);
1019 st += partlen;
1021 if (st > st_end)
1022 goto fw_stats_fail;
1024 p += sprintf(p,
1025 "%s:\n"
1026 " tx_start_ctr %u, no_ps_tx_too_short %u\n"
1027 " rx_start_ctr %u, no_ps_rx_too_short %u\n"
1028 " lppd_started %u\n"
1029 " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n",
1030 part_str,
1031 pwr->tx_start_ctr,
1032 pwr->no_ps_tx_too_short,
1033 pwr->rx_start_ctr,
1034 pwr->no_ps_rx_too_short,
1035 pwr->lppd_started,
1036 pwr->no_lppd_too_noisy,
1037 pwr->no_lppd_too_short, pwr->no_lppd_matching_frame);
1039 part_str = "MIC";
1041 if (st == st_end)
1042 goto fw_stats_end;
1044 mic = (fw_stats_mic_t *) st;
1045 partlen = sizeof(fw_stats_mic_t);
1046 st += partlen;
1048 if (st > st_end)
1049 goto fw_stats_fail;
1051 p += sprintf(p,
1052 "%s:\n"
1053 " mic_rx_pkts %u, mic_calc_fail %u\n",
1054 part_str, mic->mic_rx_pkts, mic->mic_calc_fail);
1056 part_str = "AES";
1058 if (st == st_end)
1059 goto fw_stats_end;
1061 aes = (fw_stats_aes_t *) st;
1062 partlen = sizeof(fw_stats_aes_t);
1063 st += partlen;
1065 if (st > st_end)
1066 goto fw_stats_fail;
1068 p += sprintf(p,
1069 "%s:\n"
1070 " aes_enc_fail %u, aes_dec_fail %u\n"
1071 " aes_enc_pkts %u, aes_dec_pkts %u\n"
1072 " aes_enc_irq %u, aes_dec_irq %u\n",
1073 part_str,
1074 aes->aes_enc_fail,
1075 aes->aes_dec_fail,
1076 aes->aes_enc_pkts,
1077 aes->aes_dec_pkts, aes->aes_enc_irq, aes->aes_dec_irq);
1079 part_str = "event";
1081 if (st == st_end)
1082 goto fw_stats_end;
1084 evt = (fw_stats_event_t *) st;
1085 partlen = sizeof(fw_stats_event_t);
1086 st += partlen;
1088 if (st > st_end)
1089 goto fw_stats_fail;
1091 p += sprintf(p,
1092 "%s:\n"
1093 " heartbeat %u, calibration %u\n"
1094 " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
1095 " oom_late %u\n"
1096 " phy_tx_err %u, tx_stuck %u\n",
1097 part_str,
1098 evt->heartbeat,
1099 evt->calibration,
1100 evt->rx_mismatch,
1101 evt->rx_mem_empty,
1102 evt->rx_pool,
1103 evt->oom_late, evt->phy_tx_err, evt->tx_stuck);
1105 if (st < st_end)
1106 goto fw_stats_bigger;
1108 goto fw_stats_end;
1110 fw_stats_fail:
1111 st -= partlen;
1112 p += sprintf(p,
1113 "failed at %s part (size %zu), offset %zu (struct size %zu), "
1114 "please report\n", part_str, partlen,
1115 ((void *)st - (void *)fw_stats), len);
1117 fw_stats_bigger:
1118 for (; st < st_end; st += 4)
1119 p += sprintf(p,
1120 "UNKN%3d: %u\n",
1121 (int)((void *)st - (void *)fw_stats), *(u32 *) st);
1123 fw_stats_end:
1124 kfree(fw_stats);
1126 FN_EXIT1(p - buf);
1127 return p - buf;
1131 /***********************************************************************
1133 static int acx_s_proc_phy_output(char *buf, acx_device_t * adev)
1135 char *p = buf;
1136 int i;
1138 FN_ENTER;
1141 if (RADIO_RFMD_11 != adev->radio_type) {
1142 printk("sorry, not yet adapted for radio types "
1143 "other than RFMD, please verify "
1144 "PHY size etc. first!\n");
1145 goto end;
1149 /* The PHY area is only 0x80 bytes long; further pages after that
1150 * only have some page number registers with altered value,
1151 * all other registers remain the same. */
1152 for (i = 0; i < 0x80; i++) {
1153 acx_s_read_phy_reg(adev, i, p++);
1156 FN_EXIT1(p - buf);
1157 return p - buf;
1161 /***********************************************************************
1162 ** acx_e_read_proc_XXXX
1163 ** Handle our /proc entry
1165 ** Arguments:
1166 ** standard kernel read_proc interface
1167 ** Returns:
1168 ** number of bytes written to buf
1169 ** Side effects:
1170 ** none
1172 static int
1173 acx_e_read_proc(char *buf, char **start, off_t offset, int count,
1174 int *eof, void *data)
1176 acx_device_t *adev = (acx_device_t *) data;
1177 unsigned long flags;
1178 int length;
1180 FN_ENTER;
1182 acx_sem_lock(adev);
1183 acx_lock(adev, flags);
1184 /* fill buf */
1185 length = acx_l_proc_output(buf, adev);
1186 acx_unlock(adev, flags);
1187 acx_sem_unlock(adev);
1189 /* housekeeping */
1190 if (length <= offset + count)
1191 *eof = 1;
1192 *start = buf + offset;
1193 length -= offset;
1194 if (length > count)
1195 length = count;
1196 if (length < 0)
1197 length = 0;
1198 FN_EXIT1(length);
1199 return length;
1202 static int
1203 acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count,
1204 int *eof, void *data)
1206 acx_device_t *adev = (acx_device_t *) data;
1207 int length;
1209 FN_ENTER;
1211 acx_sem_lock(adev);
1212 /* fill buf */
1213 length = acx_s_proc_diag_output(buf, adev);
1214 acx_sem_unlock(adev);
1216 /* housekeeping */
1217 if (length <= offset + count)
1218 *eof = 1;
1219 *start = buf + offset;
1220 length -= offset;
1221 if (length > count)
1222 length = count;
1223 if (length < 0)
1224 length = 0;
1225 FN_EXIT1(length);
1226 return length;
1229 static int
1230 acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count,
1231 int *eof, void *data)
1233 acx_device_t *adev = (acx_device_t *) data;
1234 int length;
1236 FN_ENTER;
1238 /* fill buf */
1239 length = 0;
1240 if (IS_PCI(adev)) {
1241 acx_sem_lock(adev);
1242 length = acxpci_proc_eeprom_output(buf, adev);
1243 acx_sem_unlock(adev);
1246 /* housekeeping */
1247 if (length <= offset + count)
1248 *eof = 1;
1249 *start = buf + offset;
1250 length -= offset;
1251 if (length > count)
1252 length = count;
1253 if (length < 0)
1254 length = 0;
1255 FN_EXIT1(length);
1256 return length;
1259 static int
1260 acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count,
1261 int *eof, void *data)
1263 acx_device_t *adev = (acx_device_t *) data;
1264 int length;
1266 FN_ENTER;
1268 acx_sem_lock(adev);
1269 /* fill buf */
1270 length = acx_s_proc_phy_output(buf, adev);
1271 acx_sem_unlock(adev);
1273 /* housekeeping */
1274 if (length <= offset + count)
1275 *eof = 1;
1276 *start = buf + offset;
1277 length -= offset;
1278 if (length > count)
1279 length = count;
1280 if (length < 0)
1281 length = 0;
1282 FN_EXIT1(length);
1283 return length;
1287 /***********************************************************************
1288 ** /proc files registration
1290 static const char *const
1291 proc_files[] = { "", "_diag", "_eeprom", "_phy" };
1293 static read_proc_t *const
1294 proc_funcs[] = {
1295 acx_e_read_proc,
1296 acx_e_read_proc_diag,
1297 acx_e_read_proc_eeprom,
1298 acx_e_read_proc_phy
1301 static int manage_proc_entries(struct ieee80211_hw *hw, int remove)
1303 acx_device_t *adev = ieee2adev(hw);
1304 char procbuf[80];
1305 int i;
1307 FN_ENTER;
1309 for (i = 0; i < ARRAY_SIZE(proc_files); i++) {
1310 snprintf(procbuf, sizeof(procbuf),
1311 "driver/acx%s", proc_files[i]);
1312 acx_log(LOG_INFO, L_INIT, "%sing /proc entry %s\n",
1313 remove ? "remov" : "creat", procbuf);
1314 if (!remove) {
1315 if (!create_proc_read_entry
1316 (procbuf, 0, NULL, proc_funcs[i], adev)) {
1317 acx_log(LOG_WARNING, L_ANY,
1318 "cannot register /proc entry %s\n", procbuf);
1319 FN_EXIT1(NOT_OK);
1320 return NOT_OK;
1322 } else {
1323 remove_proc_entry(procbuf, NULL);
1326 FN_EXIT0;
1327 return OK;
1330 int acx_proc_register_entries(struct ieee80211_hw *ieee)
1332 return manage_proc_entries(ieee, 0);
1335 int acx_proc_unregister_entries(struct ieee80211_hw *ieee)
1337 return manage_proc_entries(ieee, 1);
1339 #endif /* CONFIG_PROC_FS */
1341 /****
1342 ** Gathered From rt2x00 and bcm43xx_mac80211 projects
1344 void acx_free_modes(acx_device_t * adev)
1347 // kfree(adev->modes);
1348 // adev->modes = NULL;
1352 #define RATETAB_ENT(_rate, _rateid, _flags) \
1354 .rate = (_rate), \
1355 .val = (_rateid), \
1356 .val2 = (_rateid), \
1357 .flags = (_flags), \
1361 static struct ieee80211_rate __acx_rates[] = {
1362 { .rate = 10,
1363 .val = RATE111_1,
1364 .flags = IEEE80211_RATE_CCK },
1365 { .rate = 20,
1366 .val = RATE111_2,
1367 .flags = IEEE80211_RATE_CCK },
1368 { .rate = 55,
1369 .val = RATE111_5,
1370 .flags = IEEE80211_RATE_CCK },
1371 { .rate = 110,
1372 .val = RATE111_11,
1373 .flags = IEEE80211_RATE_CCK },
1374 { .rate = 60,
1375 .val = RATE111_6,
1376 .flags = IEEE80211_RATE_OFDM },
1377 { .rate = 90,
1378 .val = RATE111_9,
1379 .flags = IEEE80211_RATE_OFDM },
1380 { .rate = 120,
1381 .val = RATE111_12,
1382 .flags = IEEE80211_RATE_OFDM },
1383 { .rate = 180,
1384 .val = RATE111_18,
1385 .flags = IEEE80211_RATE_OFDM },
1386 { .rate = 240,
1387 .val = RATE111_24,
1388 .flags = IEEE80211_RATE_OFDM },
1389 { .rate = 360,
1390 .val = RATE111_36,
1391 .flags = IEEE80211_RATE_OFDM },
1392 { .rate = 480,
1393 .val = RATE111_48,
1394 .flags = IEEE80211_RATE_OFDM },
1395 { .rate = 540,
1396 .val = RATE111_54,
1397 .flags = IEEE80211_RATE_OFDM },
1400 static struct ieee80211_channel channels[] = {
1401 { .chan = 1,
1402 .freq = 2412},
1403 { .chan = 2,
1404 .freq = 2417},
1405 { .chan = 3,
1406 .freq = 2422},
1407 { .chan = 4,
1408 .freq = 2427},
1409 { .chan = 5,
1410 .freq = 2432},
1411 { .chan = 6,
1412 .freq = 2437},
1413 { .chan = 7,
1414 .freq = 2442},
1415 { .chan = 8,
1416 .freq = 2447},
1417 { .chan = 9,
1418 .freq = 2452},
1419 { .chan = 10,
1420 .freq = 2457},
1421 { .chan = 11,
1422 .freq = 2462},
1423 { .chan = 12,
1424 .freq = 2467},
1425 { .chan = 13,
1426 .freq = 2472},
1429 int acx_setup_modes(acx_device_t * adev)
1431 struct ieee80211_hw *hw = adev->ieee;
1432 struct ieee80211_hw_mode *mode;
1433 int err = -ENOMEM;
1435 FN_ENTER;
1437 if (IS_ACX111(adev)) {
1439 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);
1440 err = acx_setup_modes_gphy(adev);
1442 mode = &adev->modes[0];
1444 /* from the zd1211rw driver: - do we need to do the same? */
1446 memcpy(mode->channels, channels, sizeof(channels));
1447 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1450 mode->mode = MODE_IEEE80211G;
1451 mode->num_channels = ARRAY_SIZE(channels);
1452 mode->num_rates = 12;
1453 mode->rates = __acx_rates;
1454 } else {
1456 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1457 err = acx_setup_modes_bphy(adev);
1459 mode = &adev->modes[1];
1461 /* from the zd1211rw driver: - do we need to do the same? */
1463 memcpy(mode->channels, channels, sizeof(channels));
1464 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1467 mode->mode = MODE_IEEE80211B;
1468 mode->num_channels = ARRAY_SIZE(channels);
1469 mode->num_rates = 4;
1470 mode->rates = __acx_rates;
1473 /* if (err && adev->modes)
1474 kfree(adev->modes);*/
1476 mode->channels = channels;
1477 err = ieee80211_register_hwmode(hw, mode);
1479 FN_EXIT1(err);
1480 return err;
1484 /***********************************************************************
1485 ** acx_fill_beacon_or_proberesp_template
1487 ** Origin: derived from rt2x00 project
1489 static int
1490 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1491 struct acx_template_beacon *templ,
1492 struct sk_buff* skb /* in host order! */)
1494 FN_ENTER;
1496 memcpy(templ,skb->data, skb->len);
1497 FN_EXIT1(skb->len);
1498 return skb->len;
1501 /***********************************************************************
1502 ** acx_s_set_beacon_template
1506 static int
1507 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1509 struct acx_template_beacon bcn;
1510 int len, result;
1512 FN_ENTER;
1513 acx_log(LOG_INFO, L_ANY, "size of template: %08zX, "
1514 "size of beacon: %08X\n",
1515 sizeof(struct acx_template_beacon),skb->len);
1516 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1517 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1519 FN_EXIT1(result);
1520 return result;
1523 /***********************************************************************
1524 ** acx_cmd_join_bssid
1526 ** Common code for both acx100 and acx111.
1528 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1529 static const u8 bitpos2genframe_txrate[] = {
1530 10, /* 0. 1 Mbit/s */
1531 20, /* 1. 2 Mbit/s */
1532 55, /* 2. 5.5 Mbit/s */
1533 0x0B, /* 3. 6 Mbit/s */
1534 0x0F, /* 4. 9 Mbit/s */
1535 110, /* 5. 11 Mbit/s */
1536 0x0A, /* 6. 12 Mbit/s */
1537 0x0E, /* 7. 18 Mbit/s */
1538 220, /* 8. 22 Mbit/s */
1539 0x09, /* 9. 24 Mbit/s */
1540 0x0D, /* 10. 36 Mbit/s */
1541 0x08, /* 11. 48 Mbit/s */
1542 0x0C, /* 12. 54 Mbit/s */
1543 10, /* 13. 1 Mbit/s, should never happen */
1544 10, /* 14. 1 Mbit/s, should never happen */
1545 10, /* 15. 1 Mbit/s, should never happen */
1548 /* Looks scary, eh?
1549 ** Actually, each one compiled into one AND and one SHIFT,
1550 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1551 static inline unsigned int rate111to5bits(unsigned int rate)
1553 return (rate & 0x7)
1554 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1555 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1559 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1561 acx_joinbss_t tmp;
1562 int dtim_interval;
1563 int i;
1565 if (mac_is_zero(bssid))
1566 return;
1568 FN_ENTER;
1570 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1571 1 : adev->dtim_interval;
1573 memset(&tmp, 0, sizeof(tmp));
1575 for (i = 0; i < ETH_ALEN; i++) {
1576 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1579 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1581 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1582 ** are sent with one of these rates */
1583 if (IS_ACX111(adev)) {
1584 /* It was experimentally determined that rates_basic
1585 ** can take 11g rates as well, not only rates
1586 ** defined with JOINBSS_RATES_BASIC111_nnn.
1587 ** Just use RATE111_nnn constants... */
1588 tmp.u.acx111.dtim_interval = dtim_interval;
1589 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1590 acx_log(LOG_INFO, L_ASSOC, "rates_basic:%04X, "
1591 "rates_supported:%04X\n",
1592 adev->rate_basic, adev->rate_oper);
1593 } else {
1594 tmp.u.acx100.dtim_interval = dtim_interval;
1595 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1596 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1597 acx_log(LOG_INFO, L_ASSOC, "rates_basic:%04X->%02X, "
1598 "rates_supported:%04X->%02X\n",
1599 adev->rate_basic, tmp.u.acx100.rates_basic,
1600 adev->rate_oper, tmp.u.acx100.rates_supported);
1603 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1604 ** will be sent (rate/modulation/preamble) */
1605 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1606 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1607 /* we can use short pre *if* all peers can understand it */
1608 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1610 /* we switch fw to STA mode in MONITOR mode, it seems to be
1611 ** the only mode where fw does not emit beacons by itself
1612 ** but allows us to send anything (we really want to retain
1613 ** ability to tx arbitrary frames in MONITOR mode)
1615 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1616 tmp.channel = adev->channel;
1617 tmp.essid_len = adev->essid_len;
1619 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1620 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1622 acx_log(LOG_DEBUG, L_ASSOC, "BSS_Type = %u\n", tmp.macmode);
1623 acx_log(LOG_DEBUG, L_ASSOC, "JoinBSSID MAC:" MACSTR "\n",
1624 adev->bssid, "\n");
1626 /* acx_update_capabilities(adev); */
1627 FN_EXIT0;
1630 /***********************************************************************
1631 ** acxpci_i_set_multicast_list
1632 ** FIXME: most likely needs refinement
1635 void acx_i_set_multicast_list(struct ieee80211_hw *hw,
1636 unsigned int changed_flags,
1637 unsigned int *total_flags,
1638 int mc_count, struct dev_addr_list *mc_list)
1640 acx_device_t *adev = ieee2adev(hw);
1641 unsigned long flags;
1643 FN_ENTER;
1645 acx_lock(adev, flags);
1647 changed_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1648 FIF_CONTROL | FIF_OTHER_BSS);
1649 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1650 FIF_CONTROL | FIF_OTHER_BSS);
1651 /* if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1652 return; */
1654 if (*total_flags) {
1655 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1656 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1657 SET_BIT(adev->set_mask, SET_RXCONFIG);
1658 /* let kernel know in case *we* needed to set promiscuous */
1659 } else {
1660 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1661 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1662 SET_BIT(adev->set_mask, SET_RXCONFIG);
1665 /* cannot update card settings directly here, atomic context */
1666 acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
1668 acx_unlock(adev, flags);
1670 FN_EXIT0;
1673 /***********************************************************************
1674 ** acx111 feature config
1676 ** Obvious
1678 static int
1679 acx111_s_get_feature_config(acx_device_t * adev,
1680 u32 * feature_options, u32 * data_flow_options)
1682 struct acx111_ie_feature_config feat;
1684 FN_ENTER;
1686 if (!IS_ACX111(adev)) {
1687 return NOT_OK;
1690 memset(&feat, 0, sizeof(feat));
1692 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1693 FN_EXIT1(NOT_OK);
1694 return NOT_OK;
1696 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
1697 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1698 feat.feature_options, feat.data_flow_options);
1700 if (feature_options)
1701 *feature_options = le32_to_cpu(feat.feature_options);
1702 if (data_flow_options)
1703 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1705 FN_EXIT0;
1706 return OK;
1710 static int
1711 acx111_s_set_feature_config(acx_device_t * adev,
1712 u32 feature_options, u32 data_flow_options,
1713 unsigned int mode
1714 /* 0 == remove, 1 == add, 2 == set */ )
1716 struct acx111_ie_feature_config feat;
1718 FN_ENTER;
1720 if (!IS_ACX111(adev)) {
1721 FN_EXIT1(NOT_OK);
1722 return NOT_OK;
1725 if ((mode < 0) || (mode > 2)) {
1726 FN_EXIT1(NOT_OK);
1727 return NOT_OK;
1730 if (mode != 2)
1731 /* need to modify old data */
1732 acx111_s_get_feature_config(adev, &feat.feature_options,
1733 &feat.data_flow_options);
1734 else {
1735 /* need to set a completely new value */
1736 feat.feature_options = 0;
1737 feat.data_flow_options = 0;
1740 if (mode == 0) { /* remove */
1741 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1742 CLEAR_BIT(feat.data_flow_options,
1743 cpu_to_le32(data_flow_options));
1744 } else { /* add or set */
1745 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1746 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1749 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
1750 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1751 "new: feature 0x%08X dataflow 0x%08X\n",
1752 feature_options, data_flow_options, mode,
1753 le32_to_cpu(feat.feature_options),
1754 le32_to_cpu(feat.data_flow_options));
1756 if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1757 FN_EXIT1(NOT_OK);
1758 return NOT_OK;
1761 FN_EXIT0;
1762 return OK;
1765 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1767 return acx111_s_set_feature_config(adev, f, d, 0);
1769 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1771 return acx111_s_set_feature_config(adev, f, d, 1);
1773 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1775 return acx111_s_set_feature_config(adev, f, d, 2);
1779 /***********************************************************************
1780 ** acx100_s_init_memory_pools
1782 static int
1783 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1785 acx100_ie_memblocksize_t MemoryBlockSize;
1786 acx100_ie_memconfigoption_t MemoryConfigOption;
1787 int TotalMemoryBlocks;
1788 int RxBlockNum;
1789 int TotalRxBlockSize;
1790 int TxBlockNum;
1791 int TotalTxBlockSize;
1793 FN_ENTER;
1795 /* Let's see if we can follow this:
1796 first we select our memory block size (which I think is
1797 completely arbitrary) */
1798 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1800 /* Then we alert the card to our decision of block size */
1801 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
1802 goto bad;
1805 /* We figure out how many total blocks we can create, using
1806 the block size we chose, and the beginning and ending
1807 memory pointers, i.e.: end-start/size */
1808 TotalMemoryBlocks =
1809 (le32_to_cpu(mmt->PoolEnd) -
1810 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1812 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "TotalMemoryBlocks=%u (%u bytes)\n",
1813 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1815 /* MemoryConfigOption.DMA_config bitmask:
1816 access to ACX memory is to be done:
1817 0x00080000 using PCI conf space?!
1818 0x00040000 using IO instructions?
1819 0x00000000 using memory access instructions
1820 0x00020000 using local memory block linked list (else what?)
1821 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1823 if (IS_PCI(adev)) {
1824 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1825 /* Declare start of the Rx host pool */
1826 MemoryConfigOption.pRxHostDesc =
1827 cpu2acx(adev->rxhostdesc_startphy);
1828 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "pRxHostDesc 0x%08X, "
1829 "rxhostdesc_startphy 0x%lX\n",
1830 acx2cpu(MemoryConfigOption.pRxHostDesc),
1831 (long)adev->rxhostdesc_startphy);
1832 } else {
1833 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1836 /* 50% of the allotment of memory blocks go to tx descriptors */
1837 TxBlockNum = TotalMemoryBlocks / 2;
1838 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1840 /* and 50% go to the rx descriptors */
1841 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1842 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1844 /* size of the tx and rx descriptor queues */
1845 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1846 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1847 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "TxBlockNum %u RxBlockNum %u "
1848 "TotalTxBlockSize %u TotalTxBlockSize %u\n",
1849 TxBlockNum, RxBlockNum, TotalTxBlockSize, TotalRxBlockSize);
1852 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1853 MemoryConfigOption.rx_mem =
1854 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1856 /* align the rx descriptor queue to units of 0x20
1857 * and offset it by the tx descriptor queue */
1858 MemoryConfigOption.tx_mem =
1859 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
1860 0x1f) & ~0x1f);
1861 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "rx_mem %08X rx_mem %08X\n",
1862 MemoryConfigOption.tx_mem, MemoryConfigOption.rx_mem);
1864 /* alert the device to our decision */
1865 if (OK !=
1866 acx_s_configure(adev, &MemoryConfigOption,
1867 ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
1868 goto bad;
1871 /* and tell the device to kick it into gear */
1872 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
1873 goto bad;
1875 FN_EXIT1(OK);
1876 return OK;
1877 bad:
1878 FN_EXIT1(NOT_OK);
1879 return NOT_OK;
1883 /***********************************************************************
1884 ** acx100_s_create_dma_regions
1886 ** Note that this fn messes up heavily with hardware, but we cannot
1887 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1889 /* OLD CODE? - let's rewrite it! */
1890 static int acx100_s_create_dma_regions(acx_device_t * adev)
1892 acx100_ie_queueconfig_t queueconf;
1893 acx_ie_memmap_t memmap;
1894 int res = NOT_OK;
1895 u32 tx_queue_start, rx_queue_start;
1897 FN_ENTER;
1899 /* read out the acx100 physical start address for the queues */
1900 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1901 goto fail;
1904 tx_queue_start = le32_to_cpu(memmap.QueueStart);
1905 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
1907 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "initializing Queue Indicator\n");
1909 memset(&queueconf, 0, sizeof(queueconf));
1911 /* Not needed for PCI, so we can avoid setting them altogether */
1912 if (IS_USB(adev)) {
1913 queueconf.NumTxDesc = USB_TX_CNT;
1914 queueconf.NumRxDesc = USB_RX_CNT;
1917 /* calculate size of queues */
1918 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
1919 RX_CNT * sizeof(rxdesc_t) + 8);
1920 queueconf.NumTxQueues = 1; /* number of tx queues */
1921 /* sets the beginning of the tx descriptor queue */
1922 queueconf.TxQueueStart = memmap.QueueStart;
1923 /* done by memset: queueconf.TxQueuePri = 0; */
1924 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
1925 queueconf.QueueOptions = 1; /* auto reset descriptor */
1926 /* sets the end of the rx descriptor queue */
1927 queueconf.QueueEnd =
1928 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
1930 /* sets the beginning of the next queue */
1931 queueconf.HostQueueEnd =
1932 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
1933 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
1934 goto fail;
1937 if (IS_PCI(adev)) {
1938 /* sets the beginning of the rx descriptor queue, after the tx descrs */
1939 if (OK != acxpci_s_create_hostdesc_queues(adev))
1940 goto fail;
1941 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
1944 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1945 goto fail;
1948 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
1949 0x1f) & ~0x1f);
1951 if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1952 goto fail;
1955 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
1956 goto fail;
1959 res = OK;
1960 goto end;
1962 fail:
1963 acx_s_mwait(1000); /* ? */
1964 if (IS_PCI(adev))
1965 acxpci_free_desc_queues(adev);
1966 end:
1967 FN_EXIT1(res);
1968 return res;
1972 /***********************************************************************
1973 ** acx111_s_create_dma_regions
1975 ** Note that this fn messes heavily with hardware, but we cannot
1976 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1978 #define ACX111_PERCENT(percent) ((percent)/5)
1980 static int acx111_s_create_dma_regions(acx_device_t * adev)
1982 struct acx111_ie_memoryconfig memconf;
1983 struct acx111_ie_queueconfig queueconf;
1984 u32 tx_queue_start, rx_queue_start;
1986 FN_ENTER;
1988 /* Calculate memory positions and queue sizes */
1990 /* Set up our host descriptor pool + data pool */
1991 if (IS_PCI(adev)) {
1992 if (OK != acxpci_s_create_hostdesc_queues(adev))
1993 goto fail;
1996 memset(&memconf, 0, sizeof(memconf));
1997 /* the number of STAs (STA contexts) to support
1998 ** NB: was set to 1 and everything seemed to work nevertheless... */
1999 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
2000 /* specify the memory block size. Default is 256 */
2001 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
2002 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
2003 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
2004 /* set the count of our queues
2005 ** NB: struct acx111_ie_memoryconfig shall be modified
2006 ** if we ever will switch to more than one rx and/or tx queue */
2007 memconf.count_rx_queues = 1;
2008 memconf.count_tx_queues = 1;
2009 /* 0 == Busmaster Indirect Memory Organization, which is what we want
2010 * (using linked host descs with their allocated mem).
2011 * 2 == Generic Bus Slave */
2012 /* done by memset: memconf.options = 0; */
2013 /* let's use 25% for fragmentations and 75% for frame transfers
2014 * (specified in units of 5%) */
2015 memconf.fragmentation = ACX111_PERCENT(75);
2016 /* Rx descriptor queue config */
2017 memconf.rx_queue1_count_descs = RX_CNT;
2018 memconf.rx_queue1_type = 7; /* must be set to 7 */
2019 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2020 if (IS_PCI(adev)) {
2021 memconf.rx_queue1_host_rx_start =
2022 cpu2acx(adev->rxhostdesc_startphy);
2024 /* Tx descriptor queue config */
2025 memconf.tx_queue1_count_descs = TX_CNT;
2026 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2028 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
2029 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2030 ** But it is actually correct wrt IE numbers.
2031 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
2032 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2033 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2034 if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
2035 goto fail;
2038 acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
2040 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2041 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2043 acx_log(LOG_DEBUG, L_INIT, "dump queue head (from card):\n"
2044 "len: %u\n"
2045 "tx_memory_block_address: %X\n"
2046 "rx_memory_block_address: %X\n"
2047 "tx1_queue address: %X\n"
2048 "rx1_queue address: %X\n",
2049 le16_to_cpu(queueconf.len),
2050 le32_to_cpu(queueconf.tx_memory_block_address),
2051 le32_to_cpu(queueconf.rx_memory_block_address),
2052 tx_queue_start, rx_queue_start);
2054 if (IS_PCI(adev))
2055 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2057 FN_EXIT1(OK);
2058 return OK;
2059 fail:
2060 if (IS_PCI(adev))
2061 acxpci_free_desc_queues(adev);
2063 FN_EXIT1(NOT_OK);
2064 return NOT_OK;
2068 /***********************************************************************
2070 static void acx_s_initialize_rx_config(acx_device_t * adev)
2072 struct {
2073 u16 id;
2074 u16 len;
2075 u16 rx_cfg1;
2076 u16 rx_cfg2;
2077 } ACX_PACKED cfg;
2078 switch (adev->mode) {
2079 case ACX_MODE_MONITOR:
2080 adev->rx_config_1 = (u16) (0
2081 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2082 /* | RX_CFG1_FILTER_SSID */
2083 /* | RX_CFG1_FILTER_BCAST */
2084 /* | RX_CFG1_RCV_MC_ADDR1 */
2085 /* | RX_CFG1_RCV_MC_ADDR0 */
2086 /* | RX_CFG1_FILTER_ALL_MULTI */
2087 /* | RX_CFG1_FILTER_BSSID */
2088 /* | RX_CFG1_FILTER_MAC */
2089 | RX_CFG1_RCV_PROMISCUOUS
2090 | RX_CFG1_INCLUDE_FCS
2091 /* | RX_CFG1_INCLUDE_PHY_HDR */
2093 adev->rx_config_2 = (u16) (0
2094 | RX_CFG2_RCV_ASSOC_REQ
2095 | RX_CFG2_RCV_AUTH_FRAMES
2096 | RX_CFG2_RCV_BEACON_FRAMES
2097 | RX_CFG2_RCV_CONTENTION_FREE
2098 | RX_CFG2_RCV_CTRL_FRAMES
2099 | RX_CFG2_RCV_DATA_FRAMES
2100 | RX_CFG2_RCV_BROKEN_FRAMES
2101 | RX_CFG2_RCV_MGMT_FRAMES
2102 | RX_CFG2_RCV_PROBE_REQ
2103 | RX_CFG2_RCV_PROBE_RESP
2104 | RX_CFG2_RCV_ACK_FRAMES
2105 | RX_CFG2_RCV_OTHER);
2106 break;
2107 default:
2108 adev->rx_config_1 = (u16) (0
2109 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2110 /* | RX_CFG1_FILTER_SSID */
2111 /* | RX_CFG1_FILTER_BCAST */
2112 /* | RX_CFG1_RCV_MC_ADDR1 */
2113 /* | RX_CFG1_RCV_MC_ADDR0 */
2114 /* | RX_CFG1_FILTER_ALL_MULTI */
2115 /* | RX_CFG1_FILTER_BSSID */
2116 /* | RX_CFG1_FILTER_MAC */
2117 | RX_CFG1_RCV_PROMISCUOUS
2118 /* | RX_CFG1_INCLUDE_FCS */
2119 /* | RX_CFG1_INCLUDE_PHY_HDR */
2121 adev->rx_config_2 = (u16) (0
2122 | RX_CFG2_RCV_ASSOC_REQ
2123 | RX_CFG2_RCV_AUTH_FRAMES
2124 | RX_CFG2_RCV_BEACON_FRAMES
2125 | RX_CFG2_RCV_CONTENTION_FREE
2126 | RX_CFG2_RCV_CTRL_FRAMES
2127 | RX_CFG2_RCV_DATA_FRAMES
2128 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2129 | RX_CFG2_RCV_MGMT_FRAMES
2130 | RX_CFG2_RCV_PROBE_REQ
2131 | RX_CFG2_RCV_PROBE_RESP
2132 | RX_CFG2_RCV_ACK_FRAMES
2133 | RX_CFG2_RCV_OTHER);
2134 break;
2136 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2138 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2139 || (adev->firmware_numver >= 0x02000000))
2140 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2141 else
2142 adev->phy_header_len = 0;
2144 acx_log(LOG_DEBUG, L_INIT, "setting RXconfig to %04X:%04X\n",
2145 adev->rx_config_1, adev->rx_config_2);
2147 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2148 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2149 acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
2153 /***********************************************************************
2154 ** FIXME: this should be solved in a general way for all radio types
2155 ** by decoding the radio firmware module,
2156 ** since it probably has some standard structure describing how to
2157 ** set the power level of the radio module which it controls.
2158 ** Or maybe not, since the radio module probably has a function interface
2159 ** instead which then manages Tx level programming :-\
2161 ** Obvious
2163 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2165 struct acx111_ie_tx_level tx_level;
2167 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2168 * 1 (30mW) [15dBm]
2169 * 2 (10mW) [10dBm]
2170 * For now, just assume all other acx111 cards have the same.
2171 * FIXME: Ideally we would query it here, but we first need a
2172 * standard way to query individual configoptions easily.
2173 * Well, now we have proper cfgopt txpower variables, but this still
2174 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2175 if (level_dbm <= 12) {
2176 tx_level.level = 2; /* 10 dBm */
2177 adev->tx_level_dbm = 10;
2178 } else {
2179 tx_level.level = 1; /* 15 dBm */
2180 adev->tx_level_dbm = 15;
2182 if (level_dbm != adev->tx_level_dbm)
2183 acx_log(LOG_WARNING, L_INIT, "acx111 firmware has specific "
2184 "power levels only: adjusted %d dBm to %d dBm!\n",
2185 level_dbm, adev->tx_level_dbm);
2187 return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
2190 static int acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
2192 if (IS_ACX111(adev)) {
2193 return acx111_s_set_tx_level(adev, level_dbm);
2195 if (IS_PCI(adev)) {
2196 return acx100pci_s_set_tx_level(adev, level_dbm);
2199 return OK;
2203 /***********************************************************************
2204 ** acx_s_set_defaults
2206 void acx_s_set_defaults(acx_device_t * adev)
2208 struct ieee80211_conf *conf = &adev->ieee->conf;
2209 unsigned long flags;
2210 u16 default_irq_mask = (IS_ACX111(adev)) ?
2211 ACX111_DEFAULT_IRQ_MASK :
2212 ACX100_DEFAULT_IRQ_MASK;
2214 FN_ENTER;
2216 acx_lock(adev, flags);
2217 /* do it before getting settings, prevent bogus channel 0 warning */
2218 adev->channel = 1;
2220 /* query some settings from the card.
2221 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2222 * query is REQUIRED, otherwise the card won't work correctly! */
2223 adev->get_mask =
2224 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2225 GETSET_REG_DOMAIN;
2226 /* Only ACX100 supports ED and CCA */
2227 if (IS_ACX100(adev))
2228 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2230 acx_unlock(adev, flags);
2232 acx_s_update_card_settings(adev);
2234 acx_lock(adev, flags);
2236 /* set our global interrupt mask */
2237 if (IS_PCI(adev))
2238 adev->irq_mask = default_irq_mask;
2240 adev->led_power = 1; /* LED is active on startup */
2241 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2242 adev->brange_time_last_state_change = jiffies;
2244 /* copy the MAC address we just got from the card
2245 * into our MAC address used during current 802.11 session */
2246 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
2247 MAC_BCAST(adev->ap);
2249 adev->essid_len =
2250 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2251 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2252 adev->essid_active = 1;
2254 /* we have a nick field to waste, so why not abuse it
2255 * to announce the driver version? ;-) */
2256 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2258 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2259 /* first regulatory domain entry in EEPROM == default reg. domain */
2260 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2263 /* 0xffff would be better, but then we won't get a "scan complete"
2264 * interrupt, so our current infrastructure will fail: */
2265 adev->scan_count = 1;
2266 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2267 adev->scan_duration = 100;
2268 adev->scan_probe_delay = 200;
2269 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2270 adev->scan_rate = ACX_SCAN_RATE_1;
2273 adev->mode = ACX_MODE_2_STA;
2274 adev->listen_interval = 100;
2275 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2276 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2278 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2280 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2281 adev->frag_threshold = 2346;
2283 /* use standard default values for retry limits */
2284 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2285 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2287 adev->preamble_mode = 2; /* auto */
2288 adev->fallback_threshold = 3;
2289 adev->stepup_threshold = 10;
2290 adev->rate_bcast = RATE111_1;
2291 adev->rate_bcast100 = RATE100_1;
2292 adev->rate_basic = RATE111_1 | RATE111_2;
2293 adev->rate_auto = 1;
2294 if (IS_ACX111(adev)) {
2295 adev->rate_oper = RATE111_ALL;
2296 } else {
2297 adev->rate_oper = RATE111_ACX100_COMPAT;
2300 /* Supported Rates element - the rates here are given in units of
2301 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2302 acx_l_update_ratevector(adev);
2304 /* set some more defaults */
2305 if (IS_ACX111(adev)) {
2306 /* 30mW (15dBm) is default, at least in my acx111 card: */
2307 adev->tx_level_dbm = 15;
2308 conf->power_level = adev->tx_level_dbm;
2309 acx_unlock(adev, flags);
2310 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2311 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2312 acx_lock(adev, flags);
2313 } else {
2314 /* don't use max. level, since it might be dangerous
2315 * (e.g. WRT54G people experience
2316 * excessive Tx power damage!) */
2317 adev->tx_level_dbm = 18;
2318 conf->power_level = adev->tx_level_dbm;
2319 acx_unlock(adev, flags);
2320 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2321 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2322 acx_lock(adev, flags);
2325 /* adev->tx_level_auto = 1; */
2326 if (IS_ACX111(adev)) {
2327 /* start with sensitivity level 1 out of 3: */
2328 adev->sensitivity = 1;
2331 /* #define ENABLE_POWER_SAVE */
2332 #ifdef ENABLE_POWER_SAVE
2333 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2334 adev->ps_listen_interval = 1;
2335 adev->ps_options =
2336 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2337 adev->ps_hangover_period = 30;
2338 adev->ps_enhanced_transition_time = 0;
2339 #else
2340 adev->ps_wakeup_cfg = 0;
2341 adev->ps_listen_interval = 0;
2342 adev->ps_options = 0;
2343 adev->ps_hangover_period = 0;
2344 adev->ps_enhanced_transition_time = 0;
2345 #endif
2347 /* These settings will be set in fw on ifup */
2348 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2349 /* configure card to do rate fallback when in auto rate mode */
2350 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2351 /* better re-init the antenna value we got above */
2352 | GETSET_ANTENNA
2353 #if POWER_SAVE_80211
2354 | GETSET_POWER_80211
2355 #endif
2358 acx_unlock(adev, flags);
2359 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2361 acx_s_initialize_rx_config(adev);
2363 FN_EXIT0;
2367 /***********************************************************************
2368 ** acx_l_process_rxbuf
2370 ** NB: used by USB code also
2372 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2374 struct ieee80211_hdr *hdr;
2375 u16 fc, buf_len;
2377 FN_ENTER;
2379 hdr = acx_get_wlan_hdr(adev, rxbuf);
2380 fc = le16_to_cpu(hdr->frame_control);
2381 /* length of frame from control field to first byte of FCS */
2382 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2384 acx_log_dump(LOG_DEBUG, L_DATA, hdr, buf_len, "RX: 802.11 buffer:\n");
2386 acx_l_rx(adev, rxbuf);
2387 /* Now check Rx quality level, AFTER processing packet.
2388 * I tried to figure out how to map these levels to dBm
2389 * values, but for the life of me I really didn't
2390 * manage to get it. Either these values are not meant to
2391 * be expressed in dBm, or it's some pretty complicated
2392 * calculation. */
2394 #ifdef FROM_SCAN_SOURCE_ONLY
2395 /* only consider packets originating from the MAC
2396 * address of the device that's managing our BSSID.
2397 * Disable it for now, since it removes information (levels
2398 * from different peers) and slows the Rx path. *//*
2399 if (adev->ap_client && mac_is_equal(hdr->a2, adev->ap_client->address)) {
2401 #endif
2403 FN_EXIT0;
2407 /***********************************************************************
2408 ** acx_l_handle_txrate_auto
2410 ** Theory of operation:
2411 ** client->rate_cap is a bitmask of rates client is capable of.
2412 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2413 ** It is set as a result of iwconfig rate N [auto]
2414 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2415 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2416 ** auto (0x00ff == 18Mbit or any lower value),
2417 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2419 ** client->rate_cur is a value for rate111 field in tx descriptor.
2420 ** It is always set to txrate_cfg sans zero or more most significant
2421 ** bits. This routine handles selection of new rate_cur value depending on
2422 ** outcome of last tx event.
2424 ** client->rate_100 is a precalculated rate value for acx100
2425 ** (we can do without it, but will need to calculate it on each tx).
2427 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2428 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2429 ** In theory you can implement it, but so far it is considered not worth doing.
2431 ** 22Mbit, of course, is PBCC always. */
2433 /* maps acx100 tx descr rate field to acx111 one */
2435 static u16 rate100to111(u8 r)
2437 switch (r) {
2438 case RATE100_1:
2439 return RATE111_1;
2440 case RATE100_2:
2441 return RATE111_2;
2442 case RATE100_5:
2443 case (RATE100_5 | RATE100_PBCC511):
2444 return RATE111_5;
2445 case RATE100_11:
2446 case (RATE100_11 | RATE100_PBCC511):
2447 return RATE111_11;
2448 case RATE100_22:
2449 return RATE111_22;
2450 default:
2451 printk("acx: unexpected acx100 txrate: %u! "
2452 "Please report\n", r);
2453 return RATE111_1;
2460 acx_i_start_xmit(struct ieee80211_hw *hw,
2461 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2463 acx_device_t *adev = ieee2adev(hw);
2464 tx_t *tx;
2465 void *txbuf;
2466 unsigned long flags;
2468 int txresult = NOT_OK;
2470 FN_ENTER;
2472 if (unlikely(!skb)) {
2473 /* indicate success */
2474 txresult = OK;
2475 goto out;
2478 if (unlikely(!adev)) {
2479 goto out;
2482 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2483 goto out;
2485 if (unlikely(!adev->initialized)) {
2486 goto out;
2489 acx_lock(adev, flags);
2491 tx = acx_l_alloc_tx(adev);
2493 if (unlikely(!tx)) {
2494 acx_log_ratelimited(LOG_WARNING, L_ANY, "%s: start_xmit: "
2495 "txdesc ring is full, dropping tx\n",
2496 wiphy_name(adev->ieee->wiphy));
2497 txresult = NOT_OK;
2498 goto out_unlock;
2501 txbuf = acx_l_get_txbuf(adev, tx);
2503 if (unlikely(!txbuf)) {
2504 /* Card was removed */
2505 txresult = NOT_OK;
2506 acx_l_dealloc_tx(adev, tx);
2507 goto out_unlock;
2509 memcpy(txbuf, skb->data, skb->len);
2511 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2513 txresult = OK;
2514 adev->stats.tx_packets++;
2515 adev->stats.tx_bytes += skb->len;
2517 out_unlock:
2518 acx_unlock(adev, flags);
2520 out:
2521 FN_EXIT1(txresult);
2522 return txresult;
2524 /***********************************************************************
2525 ** acx_l_update_ratevector
2527 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2529 const u8 acx_bitpos2ratebyte[] = {
2530 DOT11RATEBYTE_1,
2531 DOT11RATEBYTE_2,
2532 DOT11RATEBYTE_5_5,
2533 DOT11RATEBYTE_6_G,
2534 DOT11RATEBYTE_9_G,
2535 DOT11RATEBYTE_11,
2536 DOT11RATEBYTE_12_G,
2537 DOT11RATEBYTE_18_G,
2538 DOT11RATEBYTE_22,
2539 DOT11RATEBYTE_24_G,
2540 DOT11RATEBYTE_36_G,
2541 DOT11RATEBYTE_48_G,
2542 DOT11RATEBYTE_54_G,
2545 void acx_l_update_ratevector(acx_device_t * adev)
2547 u16 bcfg = adev->rate_basic;
2548 u16 ocfg = adev->rate_oper;
2549 u8 *supp = adev->rate_supported;
2550 const u8 *dot11 = acx_bitpos2ratebyte;
2552 FN_ENTER;
2554 while (ocfg) {
2555 if (ocfg & 1) {
2556 *supp = *dot11;
2557 if (bcfg & 1) {
2558 *supp |= 0x80;
2560 supp++;
2562 dot11++;
2563 ocfg >>= 1;
2564 bcfg >>= 1;
2566 adev->rate_supported_len = supp - adev->rate_supported;
2568 acx_log_dump(LOG_DEBUG, L_ASSOC, adev->rate_supported,
2569 adev->rate_supported_len, "new ratevector:\n");
2571 FN_EXIT0;
2574 /***********************************************************************
2575 ** acx_i_timer
2577 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2579 ** Obvious
2581 void acx_i_timer(unsigned long address)
2583 unsigned long flags;
2584 acx_device_t *adev = (acx_device_t *) address;
2586 FN_ENTER;
2588 acx_lock(adev, flags);
2590 FIXME();
2591 /* We need calibration and stats gather tasks to perform here */
2593 acx_unlock(adev, flags);
2595 FN_EXIT0;
2599 /***********************************************************************
2600 ** acx_set_timer
2602 ** Sets the 802.11 state management timer's timeout.
2604 ** Linux derived
2606 void acx_set_timer(acx_device_t * adev, int timeout_us)
2608 FN_ENTER;
2610 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_IRQ,
2611 "%s(%u ms)\n", __func__, timeout_us / 1000);
2613 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2614 acx_log(LOG_WARNING, L_ANY, "attempt to set the timer "
2615 "when the card interface is not up!\n");
2616 goto end;
2619 /* first check if the timer was already initialized, THEN modify it */
2620 if (adev->mgmt_timer.function) {
2621 mod_timer(&adev->mgmt_timer,
2622 jiffies + (timeout_us * HZ / 1000000));
2624 end:
2625 FN_EXIT0;
2628 /** acx_plcp_get_bitrate_cck
2630 ** Obvious
2632 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2634 switch (plcp) {
2635 case 0x0A:
2636 return ACX_CCK_RATE_1MB;
2637 case 0x14:
2638 return ACX_CCK_RATE_2MB;
2639 case 0x37:
2640 return ACX_CCK_RATE_5MB;
2641 case 0x6E:
2642 return ACX_CCK_RATE_11MB;
2644 return 0;
2647 /* Extract the bitrate out of an OFDM PLCP header. */
2648 /** Obvious **/
2649 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2651 switch (plcp & 0xF) {
2652 case 0xB:
2653 return ACX_OFDM_RATE_6MB;
2654 case 0xF:
2655 return ACX_OFDM_RATE_9MB;
2656 case 0xA:
2657 return ACX_OFDM_RATE_12MB;
2658 case 0xE:
2659 return ACX_OFDM_RATE_18MB;
2660 case 0x9:
2661 return ACX_OFDM_RATE_24MB;
2662 case 0xD:
2663 return ACX_OFDM_RATE_36MB;
2664 case 0x8:
2665 return ACX_OFDM_RATE_48MB;
2666 case 0xC:
2667 return ACX_OFDM_RATE_54MB;
2669 return 0;
2673 /***********************************************************************
2674 ** acx_l_rx
2676 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2677 ** buffer and feeds it to the network stack via netif_rx().
2679 ** Look to bcm43xx or p54
2681 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2684 struct ieee80211_rx_status* status = &adev->rx_status;
2685 struct ieee80211_hdr *w_hdr;
2686 struct sk_buff *skb;
2687 int buflen;
2688 FN_ENTER;
2690 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2691 acx_log_ratelimited(LOG_WARNING, L_ANY,
2692 "asked to receive a packet but interface is down??\n");
2693 goto out;
2696 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2697 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2699 * Allocate our skb
2701 skb = dev_alloc_skb(buflen + 2);
2703 if (!skb) {
2704 acx_log_ratelimited(LOG_WARNING, L_ANY,
2705 "skb allocation FAILED\n");
2706 goto out;
2709 skb_reserve(skb, 2);
2710 skb_put(skb, buflen);
2711 memcpy(skb->data, w_hdr, buflen);
2713 // memset(&status, 0, sizeof(status));
2715 status->mactime = rxbuf->time;
2716 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2717 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr);
2718 status->flag = 0;
2719 status->rate = rxbuf->phy_plcp_signal;
2720 status->antenna = 1;
2721 if (rxbuf->phy_stat_baseband & (1 << 3)) { /* Uses OFDM */
2722 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2723 } else {
2724 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2728 * FIXME: should it really be done here??
2730 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2731 adev->stats.rx_packets++;
2732 adev->stats.rx_bytes += skb->len;
2733 out:
2734 FN_EXIT0;
2739 /***********************************************************************
2740 ** acx_s_read_fw
2742 ** Loads a firmware image
2744 ** Returns:
2745 ** 0 unable to load file
2746 ** pointer to firmware success
2748 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2749 u32 * size)
2751 firmware_image_t *res;
2752 const struct firmware *fw_entry;
2754 res = NULL;
2755 acx_log(LOG_INFO, L_INIT, "requesting firmware image '%s'\n", file);
2756 if (!request_firmware(&fw_entry, file, dev)) {
2757 *size = 8;
2758 if (fw_entry->size >= 8)
2759 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2760 if (fw_entry->size != *size) {
2761 acx_log(LOG_WARNING, L_ANY,
2762 "acx: firmware size does not match "
2763 "firmware header: %d != %d, "
2764 "aborting fw upload\n",
2765 (int)fw_entry->size, (int)*size);
2766 goto release_ret;
2768 res = vmalloc(*size);
2769 if (!res) {
2770 acx_log(LOG_INFO, L_ANY, "acx: no memory for firmware "
2771 "(%u bytes)\n", *size);
2772 goto release_ret;
2774 memcpy(res, fw_entry->data, fw_entry->size);
2775 release_ret:
2776 release_firmware(fw_entry);
2777 return res;
2779 acx_log(LOG_WARNING, L_ANY, "acx: firmware image '%s' was not provided. "
2780 "Check your hotplug scripts\n", file);
2782 /* checksum will be verified in write_fw, so don't bother here */
2783 return res;
2787 /***********************************************************************
2788 ** acx_s_set_wepkey
2790 static void acx100_s_set_wepkey(acx_device_t * adev)
2792 ie_dot11WEPDefaultKey_t dk;
2793 int i;
2795 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2796 if (adev->wep_keys[i].size != 0) {
2797 acx_log(LOG_DEBUG, L_INIT, "setting WEP key: %d with "
2798 "total size: %d\n",
2799 i, (int)adev->wep_keys[i].size);
2800 dk.action = 1;
2801 dk.keySize = adev->wep_keys[i].size;
2802 dk.defaultKeyNum = i;
2803 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2804 acx_s_configure(adev, &dk,
2805 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
2810 static void acx111_s_set_wepkey(acx_device_t * adev)
2812 acx111WEPDefaultKey_t dk;
2813 int i;
2815 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2816 if (adev->wep_keys[i].size != 0) {
2817 acx_log(LOG_DEBUG, L_INIT, "setting WEP key: %d with "
2818 "total size: %d\n", i,
2819 (int)adev->wep_keys[i].size);
2820 memset(&dk, 0, sizeof(dk));
2821 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2822 dk.keySize = adev->wep_keys[i].size;
2824 /* are these two lines necessary? */
2825 dk.type = 0; /* default WEP key */
2826 dk.index = 0; /* ignored when setting default key */
2828 dk.defaultKeyNum = i;
2829 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2830 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2831 sizeof(dk));
2835 /* Obvious */
2836 static void acx_s_set_wepkey(acx_device_t * adev)
2838 if (IS_ACX111(adev))
2839 acx111_s_set_wepkey(adev);
2840 else
2841 acx100_s_set_wepkey(adev);
2845 /***********************************************************************
2846 ** acx100_s_init_wep
2848 ** FIXME: this should probably be moved into the new card settings
2849 ** management, but since we're also modifying the memory map layout here
2850 ** due to the WEP key space we want, we should take care...
2852 static int acx100_s_init_wep(acx_device_t * adev)
2854 acx100_ie_wep_options_t options;
2855 ie_dot11WEPDefaultKeyID_t dk;
2856 acx_ie_memmap_t pt;
2857 int res = NOT_OK;
2859 FN_ENTER;
2861 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2862 goto fail;
2865 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "CodeEnd:%X\n", pt.CodeEnd);
2867 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2868 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2870 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2871 goto fail;
2874 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2875 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2876 options.WEPOption = 0x00;
2878 acx_log(LOG_DEBUG, L_ASSOC, "writing WEP options\n");
2879 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
2881 acx100_s_set_wepkey(adev);
2883 if (adev->wep_keys[adev->wep_current_index].size != 0) {
2884 acx_log(LOG_DEBUG, L_ASSOC,
2885 "setting active default WEP key number: %d\n",
2886 adev->wep_current_index);
2887 dk.KeyID = adev->wep_current_index;
2888 acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
2890 /* FIXME!!! wep_key_struct is filled nowhere! But adev
2891 * is initialized to 0, and we don't REALLY need those keys either */
2892 /* for (i = 0; i < 10; i++) {
2893 if (adev->wep_key_struct[i].len != 0) {
2894 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
2895 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
2896 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
2897 wep_mgmt.Action = cpu_to_le16(1);
2898 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
2899 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
2900 adev->wep_key_struct[i].index = i;
2906 /* now retrieve the updated WEPCacheEnd pointer... */
2907 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2908 acx_log(LOG_WARNING, L_ANY,
2909 "%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
2910 wiphy_name(adev->ieee->wiphy));
2911 goto fail;
2913 /* ...and tell it to start allocating templates at that location */
2914 /* (no endianness conversion needed) */
2915 pt.PacketTemplateStart = pt.WEPCacheEnd;
2917 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2918 acx_log(LOG_WARNING, L_ANY,
2919 "%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
2920 wiphy_name(adev->ieee->wiphy));
2921 goto fail;
2923 res = OK;
2925 fail:
2926 FN_EXIT1(res);
2927 return res;
2931 static int
2932 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
2933 unsigned int cmd)
2935 int res;
2936 union {
2937 acx_template_nullframe_t null;
2938 acx_template_beacon_t b;
2939 acx_template_tim_t tim;
2940 acx_template_probereq_t preq;
2941 acx_template_proberesp_t presp;
2942 } templ;
2944 memset(&templ, 0, len);
2945 templ.null.size = cpu_to_le16(len - 2);
2946 res = acx_s_issue_cmd(adev, cmd, &templ, len);
2947 return res;
2950 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
2952 return acx_s_init_max_template_generic(adev,
2953 sizeof(acx_template_nullframe_t),
2954 ACX1xx_CMD_CONFIG_NULL_DATA);
2957 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
2959 return acx_s_init_max_template_generic(adev,
2960 sizeof(acx_template_beacon_t),
2961 ACX1xx_CMD_CONFIG_BEACON);
2964 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
2966 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
2967 ACX1xx_CMD_CONFIG_TIM);
2970 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
2972 return acx_s_init_max_template_generic(adev,
2973 sizeof(acx_template_proberesp_t),
2974 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
2977 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
2979 return acx_s_init_max_template_generic(adev,
2980 sizeof(acx_template_probereq_t),
2981 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
2984 /***********************************************************************
2985 ** acx_s_set_tim_template
2987 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
2988 ** by calling this function
2989 ** (it can be done by irq handler on each DTIM irq or by timer...)
2991 [802.11 7.3.2.6] TIM information element:
2992 - 1 EID
2993 - 1 Length
2994 1 1 DTIM Count
2995 indicates how many beacons (including this) appear before next DTIM
2996 (0=this one is a DTIM)
2997 2 1 DTIM Period
2998 number of beacons between successive DTIMs
2999 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
3000 3 1 Bitmap Control
3001 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
3002 set to 1 in TIM elements with a value of 0 in the DTIM Count field
3003 when one or more broadcast or multicast frames are buffered at the AP.
3004 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
3005 4 n Partial Virtual Bitmap
3006 Visible part of traffic-indication bitmap.
3007 Full bitmap consists of 2008 bits (251 octets) such that bit number N
3008 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
3009 in octet number N/8 where the low-order bit of each octet is bit0,
3010 and the high order bit is bit7.
3011 Each set bit in virtual bitmap corresponds to traffic buffered by AP
3012 for a specific station (with corresponding AID?).
3013 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
3014 Bitmap Offset is a number of skipped zero octets (see above).
3015 'Missing' octets at the tail are also assumed to be zero.
3016 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
3017 This means that traffic-indication bitmap is:
3018 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
3019 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
3021 static int acx_s_set_tim_template(acx_device_t * adev)
3023 /* For now, configure smallish test bitmap, all zero ("no pending data") */
3024 enum { bitmap_size = 5 };
3026 acx_template_tim_t t;
3027 int result;
3029 FN_ENTER;
3031 memset(&t, 0, sizeof(t));
3032 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3033 t.tim_eid = WLAN_EID_TIM;
3034 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3035 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3036 FN_EXIT1(result);
3037 return result;
3043 #if POWER_SAVE_80211
3044 /***********************************************************************
3045 ** acx_s_set_null_data_template
3047 static int acx_s_set_null_data_template(acx_device_t * adev)
3049 struct acx_template_nullframe b;
3050 int result;
3052 FN_ENTER;
3054 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3056 b.size = cpu_to_le16(sizeof(b) - 2);
3057 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3058 b.hdr.dur = 0;
3059 MAC_BCAST(b.hdr.a1);
3060 MAC_COPY(b.hdr.a2, adev->dev_addr);
3061 MAC_COPY(b.hdr.a3, adev->bssid);
3062 b.hdr.seq = 0;
3064 result =
3065 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3067 FN_EXIT1(result);
3068 return result;
3070 #endif
3077 /***********************************************************************
3078 ** acx_s_init_packet_templates()
3080 ** NOTE: order is very important here, to have a correct memory layout!
3081 ** init templates: max Probe Request (station mode), max NULL data,
3082 ** max Beacon, max TIM, max Probe Response.
3084 static int acx_s_init_packet_templates(acx_device_t * adev)
3086 acx_ie_memmap_t mm; /* ACX100 only */
3087 int result = NOT_OK;
3089 FN_ENTER;
3091 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_INIT,
3092 "initializing max packet templates\n");
3094 if (OK != acx_s_init_max_probe_request_template(adev))
3095 goto failed;
3097 if (OK != acx_s_init_max_null_data_template(adev))
3098 goto failed;
3100 if (OK != acx_s_init_max_beacon_template(adev))
3101 goto failed;
3103 if (OK != acx_s_init_max_tim_template(adev))
3104 goto failed;
3106 if (OK != acx_s_init_max_probe_response_template(adev))
3107 goto failed;
3109 if (IS_ACX111(adev)) {
3110 /* ACX111 doesn't need the memory map magic below,
3111 * and the other templates will be set later (acx_start) */
3112 result = OK;
3113 goto success;
3116 /* ACX100 will have its TIM template set,
3117 * and we also need to update the memory map */
3119 if (OK != acx_s_set_tim_template(adev))
3120 goto failed_acx100;
3122 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
3123 "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3125 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3126 goto failed_acx100;
3128 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3129 if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3130 goto failed_acx100;
3132 result = OK;
3133 goto success;
3135 failed_acx100:
3136 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_INIT,
3137 /* "cb=0x%X\n" */
3138 "ACXMemoryMap:\n"
3139 ".CodeStart=0x%X\n"
3140 ".CodeEnd=0x%X\n"
3141 ".WEPCacheStart=0x%X\n"
3142 ".WEPCacheEnd=0x%X\n"
3143 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3144 /* len, */
3145 le32_to_cpu(mm.CodeStart),
3146 le32_to_cpu(mm.CodeEnd),
3147 le32_to_cpu(mm.WEPCacheStart),
3148 le32_to_cpu(mm.WEPCacheEnd),
3149 le32_to_cpu(mm.PacketTemplateStart),
3150 le32_to_cpu(mm.PacketTemplateEnd));
3152 failed:
3153 acx_log(LOG_WARNING, L_ANY, "%s: %s() FAILED\n",
3154 wiphy_name(adev->ieee->wiphy), __func__);
3156 success:
3157 FN_EXIT1(result);
3158 return result;
3163 /***********************************************************************
3164 ** acx_s_init_mac
3166 int acx_s_init_mac(acx_device_t * adev)
3168 int result = NOT_OK;
3170 FN_ENTER;
3172 if (IS_ACX111(adev)) {
3173 adev->ie_len = acx111_ie_len;
3174 adev->ie_len_dot11 = acx111_ie_len_dot11;
3175 } else {
3176 adev->ie_len = acx100_ie_len;
3177 adev->ie_len_dot11 = acx100_ie_len_dot11;
3180 if (IS_PCI(adev)) {
3181 adev->memblocksize = 256; /* 256 is default */
3182 /* try to load radio for both ACX100 and ACX111, since both
3183 * chips have at least some firmware versions making use of an
3184 * external radio module */
3185 acxpci_s_upload_radio(adev);
3186 } else {
3187 adev->memblocksize = 128;
3190 if (IS_ACX111(adev)) {
3191 /* for ACX111, the order is different from ACX100
3192 1. init packet templates
3193 2. create station context and create dma regions
3194 3. init wep default keys
3196 if (OK != acx_s_init_packet_templates(adev))
3197 goto fail;
3198 if (OK != acx111_s_create_dma_regions(adev)) {
3199 acx_log(LOG_WARNING, L_ANY,
3200 "%s: acx111_create_dma_regions FAILED\n",
3201 wiphy_name(adev->ieee->wiphy));
3202 goto fail;
3204 } else {
3205 if (OK != acx100_s_init_wep(adev))
3206 goto fail;
3207 if (OK != acx_s_init_packet_templates(adev))
3208 goto fail;
3209 if (OK != acx100_s_create_dma_regions(adev)) {
3210 acx_log(LOG_WARNING, L_ANY,
3211 "%s: acx100_create_dma_regions FAILED\n",
3212 wiphy_name(adev->ieee->wiphy));
3213 goto fail;
3217 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3218 result = OK;
3220 fail:
3221 if (result)
3222 acx_log(LOG_WARNING, L_ANY, "init_mac() FAILED\n");
3223 FN_EXIT1(result);
3224 return result;
3229 #if POWER_SAVE_80211
3230 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3232 /* merge both structs in a union to be able to have common code */
3233 union {
3234 acx111_ie_powersave_t acx111;
3235 acx100_ie_powersave_t acx100;
3236 } pm;
3238 /* change 802.11 power save mode settings */
3239 acx_log(LOG_DEBUG, L_INIT, "updating 802.11 power save mode settings: "
3240 "wakeup_cfg 0x%02X, listen interval %u, "
3241 "options 0x%02X, hangover period %u, "
3242 "enhanced_ps_transition_time %u\n",
3243 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3244 adev->ps_options, adev->ps_hangover_period,
3245 adev->ps_enhanced_transition_time);
3246 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3247 acx_log(LOG_DEBUG, L_INIT, "Previous PS mode settings: "
3248 "wakeup_cfg 0x%02X, "
3249 "listen interval %u, options 0x%02X, "
3250 "hangover period %u, "
3251 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3252 pm.acx111.wakeup_cfg,
3253 pm.acx111.listen_interval,
3254 pm.acx111.options,
3255 pm.acx111.hangover_period,
3256 IS_ACX111(adev) ?
3257 pm.acx111.enhanced_ps_transition_time
3258 : pm.acx100.enhanced_ps_transition_time,
3259 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3260 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3261 pm.acx111.listen_interval = adev->ps_listen_interval;
3262 pm.acx111.options = adev->ps_options;
3263 pm.acx111.hangover_period = adev->ps_hangover_period;
3264 if (IS_ACX111(adev)) {
3265 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3266 pm.acx111.enhanced_ps_transition_time =
3267 cpu_to_le32(adev->ps_enhanced_transition_time);
3268 } else {
3269 pm.acx100.enhanced_ps_transition_time =
3270 cpu_to_le16(adev->ps_enhanced_transition_time);
3272 acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT);
3273 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3274 acx_log(LOG_DEBUG, L_INIT, "wakeup_cfg: 0x%02X\n",
3275 pm.acx111.wakeup_cfg);
3276 acx_s_mwait(40);
3277 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3278 acx_log(LOG_DEBUG, L_INIT, "wakeup_cfg: 0x%02X\n",
3279 pm.acx111.wakeup_cfg);
3280 acx_log(LOG_DEBUG, L_INIT, "power save mode change %s\n",
3281 (pm.acx111.wakeup_cfg & PS_CFG_PENDING) ?
3282 "FAILED" : "was successful");
3283 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3284 * that power save mode change was successful. */
3285 /* FIXME: we shouldn't trigger a scan immediately after
3286 * fiddling with power save mode (since the firmware is sending
3287 * a NULL frame then). */
3289 #endif
3292 /***********************************************************************
3293 ** acx_s_update_card_settings
3295 ** Applies accumulated changes in various adev->xxxx members
3296 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3297 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3299 void acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
3301 unsigned mask;
3303 unsigned int i;
3305 for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
3306 if (acx_reg_domain_ids[i] == adev->reg_dom_id)
3307 break;
3309 if (sizeof(acx_reg_domain_ids) == i) {
3310 acx_log(LOG_WARNING, L_INIT,
3311 "Invalid or unsupported regulatory domain"
3312 " 0x%02X specified, falling back to FCC (USA)!"
3313 " Please report if this sounds fishy!\n",
3314 adev->reg_dom_id);
3315 i = 0;
3316 adev->reg_dom_id = acx_reg_domain_ids[i];
3318 /* since there was a mismatch, we need to force updating */
3319 do_set = 1;
3322 if (do_set) {
3323 acx_ie_generic_t dom;
3324 dom.m.bytes[0] = adev->reg_dom_id;
3325 acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3328 adev->reg_dom_chanmask = reg_domain_channel_masks[i];
3330 mask = (1 << (adev->channel - 1));
3333 * Check our channels wrt the current regulatory domain
3335 if (adev->reg_dom_chanmask & mask)
3336 return;
3339 * Hmm nope, need to adjust channels!
3342 mask = 1;
3343 for (i = 1; i <= 14; i++) {
3344 if (!(adev->reg_dom_chanmask & mask)) {
3345 mask <<= 1;
3346 continue;
3348 acx_log(LOG_INFO, L_ANY, "%s: adjusting selected channel "
3349 "from %d to %d due to new regulatory domain\n",
3350 wiphy_name(adev->ieee->wiphy), adev->channel, i);
3351 adev->channel = i;
3352 break;
3356 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3358 u32 feature1, feature2;
3360 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3361 acx_log(LOG_WARNING, L_ANY,
3362 "%s: invalid sensitivity setting (1..3), "
3363 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3364 adev->sensitivity = 1;
3366 acx111_s_get_feature_config(adev, &feature1, &feature2);
3367 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3368 if (adev->sensitivity > 1)
3369 SET_BIT(feature1, FEATURE1_LOW_RX);
3370 if (adev->sensitivity > 2)
3371 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3372 acx111_s_feature_set(adev, feature1, feature2);
3376 void acx_s_update_card_settings(acx_device_t *adev)
3378 unsigned long flags;
3379 unsigned int start_scan = 0;
3380 int i;
3382 FN_ENTER;
3384 acx_log(LOG_DEBUG, L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3385 adev->get_mask, adev->set_mask);
3387 /* Track dependencies betweed various settings */
3389 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3390 acx_log(LOG_DEBUG, L_INIT,
3391 "important setting has been changed. "
3392 "Need to update packet templates, too\n");
3393 SET_BIT(adev->set_mask, SET_TEMPLATES);
3395 if (adev->set_mask & GETSET_CHANNEL) {
3396 /* This will actually tune RX/TX to the channel */
3397 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3398 switch (adev->mode) {
3399 case ACX_MODE_0_ADHOC:
3400 case ACX_MODE_3_AP:
3401 /* Beacons contain channel# - update them */
3402 SET_BIT(adev->set_mask, SET_TEMPLATES);
3405 switch (adev->mode) {
3406 case ACX_MODE_0_ADHOC:
3407 case ACX_MODE_2_STA:
3408 start_scan = 1;
3412 /* Apply settings */
3415 if (adev->get_mask & GETSET_STATION_ID) {
3416 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3417 const u8 *paddr;
3419 acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3420 paddr = &stationID[4];
3421 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3422 for (i = 0; i < ETH_ALEN; i++) {
3423 /* we copy the MAC address (reversed in
3424 * the card) to the netdevice's MAC
3425 * address, and on ifup it will be
3426 * copied into iwadev->dev_addr */
3427 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3429 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3430 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3433 if (adev->get_mask & GETSET_SENSITIVITY) {
3434 if ((RADIO_RFMD_11 == adev->radio_type)
3435 || (RADIO_MAXIM_0D == adev->radio_type)
3436 || (RADIO_RALINK_15 == adev->radio_type)) {
3437 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3438 } else {
3439 acx_log(LOG_WARNING, L_INIT,
3440 "don't know how to get sensitivity "
3441 "for radio type 0x%02X\n", adev->radio_type);
3442 adev->sensitivity = 0;
3444 acx_log(LOG_DEBUG, L_INIT, "got sensitivity value %u\n",
3445 adev->sensitivity);
3447 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3450 if (adev->get_mask & GETSET_ANTENNA) {
3451 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3453 memset(antenna, 0, sizeof(antenna));
3454 acx_s_interrogate(adev, antenna,
3455 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3456 adev->antenna = antenna[4];
3457 acx_log(LOG_INFO, L_INIT, "got antenna value 0x%02X\n",
3458 adev->antenna);
3459 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3462 if (adev->get_mask & GETSET_ED_THRESH) {
3463 if (IS_ACX100(adev)) {
3464 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3466 memset(ed_threshold, 0, sizeof(ed_threshold));
3467 acx_s_interrogate(adev, ed_threshold,
3468 ACX100_IE_DOT11_ED_THRESHOLD);
3469 adev->ed_threshold = ed_threshold[4];
3470 } else {
3471 acx_log(LOG_WARNING, L_INIT,
3472 "acx111 doesn't support ED\n");
3473 adev->ed_threshold = 0;
3475 acx_log(LOG_INFO, L_INIT,
3476 "got Energy Detect (ED) threshold %u\n",
3477 adev->ed_threshold);
3478 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3481 if (adev->get_mask & GETSET_CCA) {
3482 if (IS_ACX100(adev)) {
3483 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3485 memset(cca, 0, sizeof(adev->cca));
3486 acx_s_interrogate(adev, cca,
3487 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3488 adev->cca = cca[4];
3489 } else {
3490 acx_log(LOG_WARNING, L_INIT,
3491 "acx111 doesn't support CCA\n");
3492 adev->cca = 0;
3494 acx_log(LOG_INFO, L_INIT,
3495 "got Channel Clear Assessment (CCA) value %u\n",
3496 adev->cca);
3497 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3500 if (adev->get_mask & GETSET_REG_DOMAIN) {
3501 acx_ie_generic_t dom;
3503 acx_s_interrogate(adev, &dom,
3504 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3505 adev->reg_dom_id = dom.m.bytes[0];
3506 acx_s_set_sane_reg_domain(adev, 0);
3507 acx_log(LOG_INFO, L_INIT,
3508 "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3509 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3512 if (adev->set_mask & GETSET_STATION_ID) {
3513 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3514 u8 *paddr;
3516 paddr = &stationID[4];
3517 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3518 for (i = 0; i < ETH_ALEN; i++) {
3519 /* copy the MAC address we obtained when we noticed
3520 * that the ethernet iface's MAC changed
3521 * to the card (reversed in
3522 * the card!) */
3523 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3525 acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3526 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3529 if (adev->set_mask & SET_STA_LIST) {
3530 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3532 if (adev->set_mask & SET_RATE_FALLBACK) {
3533 u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
3535 /* configure to not do fallbacks when not in auto rate mode */
3536 rate[4] =
3537 (adev->
3538 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3539 acx_log(LOG_DEBUG, L_INIT,
3540 "updating Tx fallback to %u retries\n", rate[4]);
3541 acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK);
3542 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3544 if (adev->set_mask & GETSET_TXPOWER) {
3545 acx_log(LOG_DEBUG, L_INIT, "updating transmit power: %u dBm\n",
3546 adev->tx_level_dbm);
3547 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3548 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3551 if (adev->set_mask & GETSET_SENSITIVITY) {
3552 acx_log(LOG_DEBUG, L_INIT, "updating sensitivity value: %u\n",
3553 adev->sensitivity);
3554 switch (adev->radio_type) {
3555 case RADIO_RFMD_11:
3556 case RADIO_MAXIM_0D:
3557 case RADIO_RALINK_15:
3558 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3559 break;
3560 case RADIO_RADIA_16:
3561 case RADIO_UNKNOWN_17:
3562 acx111_s_sens_radio_16_17(adev);
3563 break;
3564 default:
3565 acx_log(LOG_WARNING, L_INIT,
3566 "don't know how to modify sensitivity "
3567 "for radio type 0x%02X\n", adev->radio_type);
3569 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3572 if (adev->set_mask & GETSET_ANTENNA) {
3573 /* antenna */
3574 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3576 memset(antenna, 0, sizeof(antenna));
3577 antenna[4] = adev->antenna;
3578 acx_log(LOG_DEBUG, L_INIT, "updating antenna value: 0x%02X\n",
3579 adev->antenna);
3580 acx_s_configure(adev, &antenna,
3581 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3582 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3585 if (adev->set_mask & GETSET_ED_THRESH) {
3586 /* ed_threshold */
3587 acx_log(LOG_INFO, L_INIT,
3588 "updating Energy Detect (ED) threshold: %u\n",
3589 adev->ed_threshold);
3590 if (IS_ACX100(adev)) {
3591 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3593 memset(ed_threshold, 0, sizeof(ed_threshold));
3594 ed_threshold[4] = adev->ed_threshold;
3595 acx_s_configure(adev, &ed_threshold,
3596 ACX100_IE_DOT11_ED_THRESHOLD);
3597 } else
3598 acx_log(LOG_WARNING, L_INIT,
3599 "acx111 doesn't support ED!\n");
3600 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3603 if (adev->set_mask & GETSET_CCA) {
3604 /* CCA value */
3605 acx_log(LOG_DEBUG, L_INIT,
3606 "updating Channel Clear Assessment (CCA) value: "
3607 "0x%02X\n", adev->cca);
3608 if (IS_ACX100(adev)) {
3609 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3611 memset(cca, 0, sizeof(cca));
3612 cca[4] = adev->cca;
3613 acx_s_configure(adev, &cca,
3614 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3615 } else
3616 acx_log(LOG_WARNING, L_INIT,
3617 "acx111 doesn't support CCA!\n");
3618 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3621 if (adev->set_mask & GETSET_LED_POWER) {
3622 /* Enable Tx */
3623 acx_log(LOG_INFO, L_INIT,
3624 "updating power LED status: %u\n", adev->led_power);
3626 acx_lock(adev, flags); /* acxpci_l_power_led expects that the lock is already taken! */
3627 if (IS_PCI(adev))
3628 acxpci_l_power_led(adev, adev->led_power);
3629 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3630 acx_unlock(adev, flags);
3633 if (adev->set_mask & GETSET_POWER_80211) {
3634 #if POWER_SAVE_80211
3635 acx_s_update_80211_powersave_mode(adev);
3636 #endif
3637 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3640 if (adev->set_mask & GETSET_CHANNEL) {
3641 /* channel */
3642 acx_log(LOG_INFO, L_INIT, "updating channel to: %u\n",
3643 adev->channel);
3644 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3647 if (adev->set_mask & GETSET_TX) {
3648 /* set Tx */
3649 acx_log(LOG_INFO, L_INIT, "updating: %s Tx\n",
3650 adev->tx_disabled ? "disable" : "enable");
3651 if (adev->tx_disabled)
3652 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3653 else {
3654 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3655 &adev->channel, 1);
3656 FIXME();
3657 /* This needs to be keyed on WEP? */
3658 /* acx111_s_feature_on(adev, 0,
3659 FEATURE2_NO_TXCRYPT |
3660 FEATURE2_SNIFFER); */
3661 acx_wake_queue(adev->ieee, NULL);
3663 CLEAR_BIT(adev->set_mask, GETSET_TX);
3666 if (adev->set_mask & GETSET_RX) {
3667 /* Enable Rx */
3668 acx_log(LOG_INFO, L_INIT,
3669 "updating: enable Rx on channel: %u\n", adev->channel);
3670 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3671 CLEAR_BIT(adev->set_mask, GETSET_RX);
3674 if (adev->set_mask & GETSET_RETRY) {
3675 u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
3676 u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
3678 acx_log(LOG_INFO, L_INIT,
3679 "updating short retry limit: %u, "
3680 "long retry limit: %u\n",
3681 adev->short_retry, adev->long_retry);
3682 short_retry[0x4] = adev->short_retry;
3683 long_retry[0x4] = adev->long_retry;
3684 acx_s_configure(adev, &short_retry,
3685 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
3686 acx_s_configure(adev, &long_retry,
3687 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
3688 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3691 if (adev->set_mask & SET_MSDU_LIFETIME) {
3692 u8 xmt_msdu_lifetime[4 +
3693 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3695 acx_log(LOG_DEBUG, L_INIT, "updating tx MSDU lifetime: %u\n",
3696 adev->msdu_lifetime);
3697 *(u32 *) & xmt_msdu_lifetime[4] =
3698 cpu_to_le32((u32) adev->msdu_lifetime);
3699 acx_s_configure(adev, &xmt_msdu_lifetime,
3700 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
3701 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3704 if (adev->set_mask & GETSET_REG_DOMAIN) {
3705 acx_log(LOG_INFO, L_INIT,
3706 "updating regulatory domain: 0x%02X\n",
3707 adev->reg_dom_id);
3708 acx_s_set_sane_reg_domain(adev, 1);
3709 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3711 if (adev->set_mask & GETSET_MODE ) {
3712 acx111_s_feature_on(adev, 0,
3713 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3714 switch (adev->mode) {
3715 case ACX_MODE_3_AP:
3716 adev->aid = 0;
3717 //acx111_s_feature_off(adev, 0,
3718 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3719 MAC_COPY(adev->bssid, adev->dev_addr);
3720 acx_s_cmd_join_bssid(adev, adev->dev_addr);
3721 break;
3722 case ACX_MODE_MONITOR:
3723 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3724 break;
3725 case ACX_MODE_0_ADHOC:
3726 case ACX_MODE_2_STA:
3727 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3728 break;
3729 default:
3730 break;
3732 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3734 if (adev->set_mask & SET_TEMPLATES) {
3735 switch (adev->mode)
3737 case ACX_MODE_3_AP:
3738 acx_s_set_tim_template(adev);
3739 break;
3740 default:
3741 break;
3743 if (adev->beacon_cache)
3745 acx_s_set_beacon_template(adev, adev->beacon_cache);
3746 dev_kfree_skb(adev->beacon_cache);
3747 adev->beacon_cache = NULL;
3749 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3752 if (adev->set_mask & SET_RXCONFIG) {
3753 acx_s_initialize_rx_config(adev);
3754 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3757 if (adev->set_mask & GETSET_RESCAN) {
3758 /* switch (adev->mode) {
3759 case ACX_MODE_0_ADHOC:
3760 case ACX_MODE_2_STA:
3761 start_scan = 1;
3762 break;
3764 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3767 if (adev->set_mask & GETSET_WEP) {
3768 /* encode */
3770 ie_dot11WEPDefaultKeyID_t dkey;
3771 #ifdef DEBUG_WEP
3772 struct {
3773 u16 type;
3774 u16 len;
3775 u8 val;
3776 } ACX_PACKED keyindic;
3777 #endif
3778 acx_log(LOG_DEBUG, L_INIT, "updating WEP key settings\n");
3780 acx_s_set_wepkey(adev);
3781 if (adev->wep_enabled) {
3782 dkey.KeyID = adev->wep_current_index;
3783 acx_log(LOG_DEBUG, L_INIT,
3784 "setting WEP key %u as default\n",
3785 dkey.KeyID);
3786 acx_s_configure(adev, &dkey,
3787 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
3788 #ifdef DEBUG_WEP
3789 keyindic.val = 3;
3790 acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
3791 #endif
3794 // start_scan = 1;
3795 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3798 if (adev->set_mask & SET_WEP_OPTIONS) {
3799 acx100_ie_wep_options_t options;
3801 if (IS_ACX111(adev)) {
3802 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
3803 "setting WEP Options for acx111 "
3804 "is not supported\n");
3805 } else {
3806 acx_log(LOG_DEBUG, L_INIT, "setting WEP Options\n");
3808 /* let's choose maximum setting: 4 default keys,
3809 * plus 10 other keys: */
3810 options.NumKeys =
3811 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3812 /* don't decrypt default key only,
3813 * don't override decryption: */
3814 options.WEPOption = 0;
3815 if (adev->mode == ACX_MODE_3_AP) {
3816 /* don't decrypt default key only,
3817 * override decryption mechanism: */
3818 options.WEPOption = 2;
3821 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3823 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3827 /* debug, rate, and nick don't need any handling */
3828 /* what about sniffing mode?? */
3830 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3831 adev->get_mask, adev->set_mask);
3833 /* end: */
3834 FN_EXIT0;
3837 #if 0
3838 /***********************************************************************
3839 ** acx_e_after_interrupt_task
3841 static int acx_s_recalib_radio(acx_device_t * adev)
3843 if (IS_ACX111(adev)) {
3844 acx111_cmd_radiocalib_t cal;
3846 /* automatic recalibration, choose all methods: */
3847 cal.methods = cpu_to_le32(0x8000000f);
3848 /* automatic recalibration every 60 seconds (value in TUs)
3849 * I wonder what the firmware default here is? */
3850 cal.interval = cpu_to_le32(58594);
3851 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3852 &cal, sizeof(cal),
3853 CMD_TIMEOUT_MS(100));
3854 } else {
3855 /* On ACX100, we need to recalibrate the radio
3856 * by issuing a GETSET_TX|GETSET_RX */
3857 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3858 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3859 (OK ==
3860 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3861 &adev->channel, 1))
3862 && (OK ==
3863 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3864 &adev->channel, 1)))
3865 return OK;
3866 return NOT_OK;
3869 #endif // if 0
3870 #if 0
3871 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3873 int res;
3875 /* this helps with ACX100 at least;
3876 * hopefully ACX111 also does a
3877 * recalibration here */
3879 /* clear flag beforehand, since we want to make sure
3880 * it's cleared; then only set it again on specific circumstances */
3881 CLEAR_BIT(adev->after_interrupt_jobs, ACX_TASKLET_CMD_RADIO_RECALIB);
3883 /* better wait a bit between recalibrations to
3884 * prevent overheating due to torturing the card
3885 * into working too long despite high temperature
3886 * (just a safety measure) */
3887 if (adev->recalib_time_last_success
3888 && time_before(jiffies, adev->recalib_time_last_success
3889 + RECALIB_PAUSE * 60 * HZ)) {
3890 if (adev->recalib_msg_ratelimit <= 4) {
3891 printk("%s: less than " STRING(RECALIB_PAUSE)
3892 " minutes since last radio recalibration, "
3893 "not recalibrating (maybe card is too hot?)\n",
3894 wiphy_name(adev->ieee->wiphy));
3895 adev->recalib_msg_ratelimit++;
3896 if (adev->recalib_msg_ratelimit == 5)
3897 printk("disabling above message until next recalib\n");
3899 return;
3902 adev->recalib_msg_ratelimit = 0;
3904 /* note that commands sometimes fail (card busy),
3905 * so only clear flag if we were fully successful */
3906 res = acx_s_recalib_radio(adev);
3907 if (res == OK) {
3908 printk("%s: successfully recalibrated radio\n",
3909 wiphy_name(adev->ieee->wiphy));
3910 adev->recalib_time_last_success = jiffies;
3911 adev->recalib_failure_count = 0;
3912 } else {
3913 /* failed: resubmit, but only limited
3914 * amount of times within some time range
3915 * to prevent endless loop */
3917 adev->recalib_time_last_success = 0; /* we failed */
3919 /* if some time passed between last
3920 * attempts, then reset failure retry counter
3921 * to be able to do next recalib attempt */
3922 if (time_after
3923 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3924 adev->recalib_failure_count = 0;
3926 if (adev->recalib_failure_count < 5) {
3927 /* increment inside only, for speedup of outside path */
3928 adev->recalib_failure_count++;
3929 adev->recalib_time_last_attempt = jiffies;
3930 acx_schedule_task(adev,
3931 ACX_TASKLET_CMD_RADIO_RECALIB);
3935 #endif // if 0
3937 void acx_e_after_interrupt_task(struct work_struct *work)
3939 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
3940 unsigned long flags;
3942 FN_ENTER;
3944 acx_lock(adev, flags);
3946 if (!adev->after_interrupt_jobs || !adev->initialized)
3947 goto end; /* no jobs to do */
3949 /* we see lotsa tx errors */
3950 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_RADIO_RECALIB) {
3951 acx_log_ratelimited(LOG_WARNING, L_ANY,
3952 "too many TX errors??\n");
3953 // acx_s_after_interrupt_recalib(adev);
3956 /* a poor interrupt code wanted to do update_card_settings() */
3957 if (adev->after_interrupt_jobs & ACX_TASKLET_UPDATE_CARD_CFG) {
3958 if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
3959 acx_unlock(adev, flags);
3960 acx_s_update_card_settings(adev);
3961 acx_lock(adev, flags);
3963 CLEAR_BIT(adev->after_interrupt_jobs,
3964 ACX_TASKLET_UPDATE_CARD_CFG);
3967 /* 1) we detected that no Scan_Complete IRQ came from fw, or
3968 ** 2) we found too many STAs */
3969 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_STOP_SCAN) {
3970 acx_log(LOG_DEBUG, L_IRQ, "sending a stop scan cmd...\n");
3971 acx_unlock(adev, flags);
3972 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
3973 acx_lock(adev, flags);
3974 /* HACK: set the IRQ bit, since we won't get a
3975 * scan complete IRQ any more on ACX111 (works on ACX100!),
3976 * since _we_, not a fw, have stopped the scan */
3977 SET_BIT(adev->irq_status, ACX_IRQ_SCAN_COMPLETE);
3978 CLEAR_BIT(adev->after_interrupt_jobs,
3979 ACX_TASKLET_CMD_STOP_SCAN);
3982 /* either fw sent Scan_Complete or we detected that
3983 ** no Scan_Complete IRQ came from fw. Finish scanning,
3984 ** pick join partner if any */
3985 if (adev->after_interrupt_jobs & ACX_TASKLET_COMPLETE_SCAN) {
3986 /* + scan kills current join status - restore it
3987 ** (do we need it for STA?) */
3988 /* + does it happen only with active scans?
3989 ** active and passive scans? ALL scans including
3990 ** background one? */
3991 /* + was not verified that everything is restored
3992 ** (but at least we start to emit beacons again) */
3993 CLEAR_BIT(adev->after_interrupt_jobs,
3994 ACX_TASKLET_COMPLETE_SCAN);
3997 /* STA auth or assoc timed out, start over again */
3999 if (adev->after_interrupt_jobs & ACX_TASKLET_RESTART_SCAN) {
4000 acx_log(LOG_DEBUG, L_IRQ, "sending a start_scan cmd...\n");
4001 CLEAR_BIT(adev->after_interrupt_jobs,
4002 ACX_TASKLET_RESTART_SCAN);
4005 /* whee, we got positive assoc response! 8) */
4006 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_ASSOCIATE) {
4007 CLEAR_BIT(adev->after_interrupt_jobs,
4008 ACX_TASKLET_CMD_ASSOCIATE);
4010 end:
4011 if(adev->after_interrupt_jobs)
4013 acx_log(LOG_DEBUG, L_ANY, "Jobs still to be run: %x\n",
4014 adev->after_interrupt_jobs);
4015 adev->after_interrupt_jobs = 0;
4017 acx_unlock(adev, flags);
4018 // acx_sem_unlock(adev);
4019 FN_EXIT0;
4023 /***********************************************************************
4024 ** acx_schedule_task
4026 ** Schedule the call of the after_interrupt method after leaving
4027 ** the interrupt context.
4029 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
4031 if (!adev->after_interrupt_jobs)
4033 SET_BIT(adev->after_interrupt_jobs, set_flag);
4034 schedule_work(&adev->after_interrupt_task);
4039 /***********************************************************************
4041 void acx_init_task_scheduler(acx_device_t * adev)
4043 /* configure task scheduler */
4044 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4048 /***********************************************************************
4049 ** acx_s_start
4051 void acx_s_start(acx_device_t * adev)
4053 FN_ENTER;
4056 * Ok, now we do everything that can possibly be done with ioctl
4057 * calls to make sure that when it was called before the card
4058 * was up we get the changes asked for
4061 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4062 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4063 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4064 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4066 acx_log(LOG_INFO, L_INIT,
4067 "updating initial settings on iface activation\n");
4068 acx_s_update_card_settings(adev);
4070 FN_EXIT0;
4074 /***********************************************************************
4075 ** acx_update_capabilities
4076 *//*
4077 void acx_update_capabilities(acx_device_t * adev)
4079 u16 cap = 0;
4081 switch (adev->mode) {
4082 case ACX_MODE_3_AP:
4083 SET_BIT(cap, WF_MGMT_CAP_ESS);
4084 break;
4085 case ACX_MODE_0_ADHOC:
4086 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4087 break;
4088 */ /* other types of stations do not emit beacons */
4089 /* }
4091 if (adev->wep_restricted) {
4092 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4094 if (adev->cfgopt_dot11ShortPreambleOption) {
4095 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4097 if (adev->cfgopt_dot11PBCCOption) {
4098 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4100 if (adev->cfgopt_dot11ChannelAgility) {
4101 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4103 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4104 adev->capabilities, cap);
4105 adev->capabilities = cap;
4109 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4112 static void acx_s_select_opmode(acx_device_t * adev)
4114 int changed = 0;
4115 FN_ENTER;
4117 if (adev->interface.operating) {
4118 switch (adev->interface.type) {
4119 case IEEE80211_IF_TYPE_AP:
4120 if (adev->mode != ACX_MODE_3_AP)
4122 adev->mode = ACX_MODE_3_AP;
4123 changed = 1;
4125 break;
4126 case IEEE80211_IF_TYPE_IBSS:
4127 if (adev->mode != ACX_MODE_0_ADHOC)
4129 adev->mode = ACX_MODE_0_ADHOC;
4130 changed = 1;
4132 break;
4133 case IEEE80211_IF_TYPE_STA:
4134 if (adev->mode != ACX_MODE_2_STA)
4136 adev->mode = ACX_MODE_2_STA;
4137 changed = 1;
4139 break;
4140 case IEEE80211_IF_TYPE_WDS:
4141 default:
4142 if (adev->mode != ACX_MODE_OFF)
4144 adev->mode = ACX_MODE_OFF;
4145 changed = 1;
4147 break;
4149 } else {
4150 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4152 if (adev->mode != ACX_MODE_MONITOR)
4154 adev->mode = ACX_MODE_MONITOR;
4155 changed = 1;
4158 else
4160 if (adev->mode != ACX_MODE_OFF)
4162 adev->mode = ACX_MODE_OFF;
4163 changed = 1;
4167 if (changed)
4169 SET_BIT(adev->set_mask, GETSET_MODE);
4170 acx_s_update_card_settings(adev);
4171 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4174 FN_EXIT0;
4178 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4182 int acx_add_interface(struct ieee80211_hw *ieee,
4183 struct ieee80211_if_init_conf *conf)
4185 acx_device_t *adev = ieee2adev(ieee);
4186 unsigned long flags;
4187 int err = -EOPNOTSUPP;
4189 DECLARE_MAC_BUF(mac);
4191 FN_ENTER;
4192 acx_lock(adev, flags);
4194 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4195 adev->interface.monitor++;
4196 } else {
4197 if (adev->interface.operating)
4198 goto out_unlock;
4199 adev->interface.operating = 1;
4200 adev->interface.mac_addr = conf->mac_addr;
4201 adev->interface.type = conf->type;
4203 // adev->mode = conf->type;
4205 acx_unlock(adev, flags);
4207 if (adev->initialized)
4208 acx_s_select_opmode(adev);
4210 acx_lock(adev, flags);
4212 err = 0;
4214 acx_log(LOG_INFO, L_ANY, "Virtual interface added "
4215 "(type: 0x%08X, ID: %d, MAC: %s)\n",
4216 conf->type,
4217 adev->interface.if_id,
4218 print_mac(mac, conf->mac_addr));
4220 out_unlock:
4221 acx_unlock(adev, flags);
4223 FN_EXIT0;
4224 return err;
4227 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4231 void acx_remove_interface(struct ieee80211_hw *hw,
4232 struct ieee80211_if_init_conf *conf)
4234 acx_device_t *adev = ieee2adev(hw);
4236 DECLARE_MAC_BUF(mac);
4238 FN_ENTER;
4240 acx_sem_lock(adev);
4241 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4242 adev->interface.monitor--;
4243 // assert(bcm->interface.monitor >= 0);
4244 } else {
4245 adev->interface.operating = 0;
4248 acx_log(LOG_INFO, L_ANY, "Removing interface: %d %d\n",
4249 adev->interface.operating, conf->type);
4250 acx_sem_unlock(adev);
4252 if (adev->initialized)
4253 acx_s_select_opmode(adev);
4254 flush_scheduled_work();
4256 acx_log(LOG_INFO, L_ANY, "Virtual interface removed "
4257 "(type: 0x%08X, ID: %d, MAC: %s)\n",
4258 conf->type, adev->interface.if_id,
4259 print_mac(mac, conf->mac_addr));
4261 FN_EXIT0;
4264 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4268 int acx_net_reset(struct ieee80211_hw *ieee)
4270 acx_device_t *adev = ieee2adev(ieee);
4271 FN_ENTER;
4272 if (IS_PCI(adev))
4273 acxpci_s_reset_dev(adev);
4274 else
4275 TODO();
4277 FN_EXIT0;
4278 return 0;
4282 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4285 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4287 int result;
4289 FN_ENTER;
4291 acx_sem_lock(adev);
4292 adev->rx_status.channel = channel;
4293 adev->rx_status.freq = freq;
4295 adev->channel = channel;
4296 /* hmm, the following code part is strange, but this is how
4297 * it was being done before... */
4298 acx_log(LOG_DEBUG, L_IOCTL, "Changing to channel %d\n", channel);
4299 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4300 result = -EINPROGRESS; /* need to call commit handler */
4302 acx_sem_unlock(adev);
4303 FN_EXIT1(result);
4304 return result;
4308 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4311 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4313 acx_device_t *adev = ieee2adev(hw);
4314 unsigned long flags;
4316 FN_ENTER;
4318 acx_lock(adev, flags);
4319 //FIXME();
4320 if (!adev->initialized) {
4321 acx_unlock(adev, flags);
4322 return 0;
4324 if (conf->beacon_int != adev->beacon_interval)
4325 adev->beacon_interval = conf->beacon_int;
4326 if (conf->channel != adev->channel) {
4327 acx_unlock(adev, flags);
4328 acx_selectchannel(adev, conf->channel,conf->freq);
4329 acx_lock(adev, flags);
4330 /* acx_schedule_task(adev,
4331 ACX_TASKLET_UPDATE_CARD_CFG
4332 */ /*+ ACX_TASKLET_RESTART_SCAN */ /*);*/
4335 if (conf->short_slot_time != adev->short_slot) {
4336 // assert(phy->type == BCM43xx_PHYTYPE_G);
4337 if (conf->short_slot_time)
4338 acx_short_slot_timing_enable(adev);
4339 else
4340 acx_short_slot_timing_disable(adev);
4341 acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4344 adev->tx_disabled = !conf->radio_enabled;
4345 /* if (conf->power_level != 0){
4346 adev->tx_level_dbm = conf->power_level;
4347 acx_s_set_tx_level(adev, adev->tx_level_dbm);
4348 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4349 //acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4352 //FIXME: This does not seem to wake up:
4353 #if 0
4354 if (conf->power_level == 0) {
4355 if (radio->enabled)
4356 bcm43xx_radio_turn_off(bcm);
4357 } else {
4358 if (!radio->enabled)
4359 bcm43xx_radio_turn_on(bcm);
4361 #endif
4363 //TODO: phymode
4364 //TODO: antennas
4365 if (adev->set_mask > 0) {
4366 acx_unlock(adev, flags);
4367 acx_s_update_card_settings(adev);
4368 acx_lock(adev, flags);
4370 acx_unlock(adev, flags);
4372 FN_EXIT0;
4373 return 0;
4377 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4381 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
4382 extern int acx_config_interface(struct ieee80211_hw* ieee,
4383 struct ieee80211_vif *vif,
4384 struct ieee80211_if_conf *conf)
4386 acx_device_t *adev = ieee2adev(ieee);
4387 unsigned long flags;
4388 int err = -ENODEV;
4389 FN_ENTER;
4390 if (!adev->interface.operating)
4391 goto err_out;
4393 if (adev->initialized)
4394 acx_s_select_opmode(adev);
4396 acx_lock(adev, flags);
4398 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4399 && (adev->vif == vif)) {
4400 if (conf->bssid)
4402 adev->interface.bssid = conf->bssid;
4403 MAC_COPY(adev->bssid,conf->bssid);
4406 if ((conf->type == IEEE80211_IF_TYPE_AP)
4407 && (adev->vif == vif)) {
4408 #else
4409 int acx_config_interface(struct ieee80211_hw* ieee, int if_id,
4410 struct ieee80211_if_conf *conf)
4412 acx_device_t *adev = ieee2adev(ieee);
4413 unsigned long flags;
4414 int err = -ENODEV;
4415 FN_ENTER;
4416 if (!adev->interface.operating)
4417 goto err_out;
4419 if (adev->initialized)
4420 acx_s_select_opmode(adev);
4422 acx_lock(adev, flags);
4424 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4425 && (adev->interface.if_id == if_id)) {
4426 if (conf->bssid)
4428 adev->interface.bssid = conf->bssid;
4429 MAC_COPY(adev->bssid,conf->bssid);
4432 if ((conf->type == IEEE80211_IF_TYPE_AP)
4433 && (adev->interface.if_id == if_id)) {
4434 #endif
4436 if ((conf->ssid_len > 0) && conf->ssid)
4438 adev->essid_len = conf->ssid_len;
4439 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4440 SET_BIT(adev->set_mask, SET_TEMPLATES);
4443 if (conf->beacon != 0)
4445 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4446 adev->beacon_cache = conf->beacon;
4447 SET_BIT(adev->set_mask, SET_TEMPLATES);
4450 acx_unlock(adev, flags);
4452 if (adev->set_mask != 0)
4453 acx_s_update_card_settings(adev);
4454 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4455 err = 0;
4456 err_out:
4457 FN_EXIT1(err);
4458 return err;
4462 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4466 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4467 struct ieee80211_tx_queue_stats *stats)
4469 // acx_device_t *adev = ndev2adev(net_dev);
4470 struct ieee80211_tx_queue_stats_data *data;
4471 int err = -ENODEV;
4473 FN_ENTER;
4475 // acx_lock(adev, flags);
4476 data = &(stats->data[0]);
4477 data->len = 0;
4478 data->limit = TX_CNT;
4479 data->count = 0;
4480 // acx_unlock(adev, flags);
4482 FN_EXIT0;
4483 return err;
4486 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4490 int acx_net_conf_tx(struct ieee80211_hw *hw,
4491 int queue, const struct ieee80211_tx_queue_params *params)
4493 FN_ENTER;
4494 // TODO();
4495 FN_EXIT0;
4496 return 0;
4499 static void keymac_write(acx_device_t * adev, u16 index, const u32 * addr)
4501 /* for keys 0-3 there is no associated mac address */
4502 if (index < 4)
4503 return;
4505 index -= 4;
4506 if (1) {
4507 TODO();
4509 bcm43xx_shm_write32(bcm,
4510 BCM43xx_SHM_HWMAC,
4511 index * 2,
4512 cpu_to_be32(*addr));
4513 bcm43xx_shm_write16(bcm,
4514 BCM43xx_SHM_HWMAC,
4515 (index * 2) + 1,
4516 cpu_to_be16(*((u16 *)(addr + 1))));
4518 } else {
4519 if (index < 8) {
4520 TODO(); /* Put them in the macaddress filter */
4521 } else {
4522 TODO();
4523 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4524 Keep in mind to update the count of keymacs in 0x003 */
4530 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4534 int acx_clear_keys(acx_device_t * adev)
4536 static const u32 zero_mac[2] = { 0 };
4537 unsigned int i, j, nr_keys = 54;
4538 u16 offset;
4540 /* FixMe:Check for Number of Keys available */
4542 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4544 for (i = 0; i < nr_keys; i++) {
4545 adev->key[i].enabled = 0;
4546 /* returns for i < 4 immediately */
4547 keymac_write(adev, i, zero_mac);
4549 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4550 0x100 + (i * 2), 0x0000);
4552 for (j = 0; j < 8; j++) {
4553 offset =
4554 adev->security_offset + (j * 4) +
4555 (i * ACX_SEC_KEYSIZE);
4557 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4558 offset, 0x0000);
4562 return 1;
4566 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4570 int acx_key_write(acx_device_t * adev,
4571 u16 index, u8 algorithm,
4572 const struct ieee80211_key_conf *key, const u8 * mac_addr)
4574 // struct iw_point *dwrq = &wrqu->encoding;
4575 int result;
4577 FN_ENTER;
4579 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4580 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4582 // acx_sem_lock(adev);
4584 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4585 if (key->keylen > 0) {
4586 /* if index is 0 or invalid, use default key */
4587 if (index > 3)
4588 index = (int)adev->wep_current_index;
4589 if ((algorithm == ACX_SEC_ALGO_WEP) ||
4590 (algorithm == ACX_SEC_ALGO_WEP104)) {
4591 switch(key->keylen) {
4592 case 40 / 8:
4593 /* WEP 40-bit =
4594 40-bit entered key + 24 bit IV = 64-bit */
4595 adev->wep_keys[index].size = 13;
4596 break;
4597 case 104 / 8:
4598 /* WEP 104-bit =
4599 104-bit entered key + 24-bit IV = 128-bit */
4600 adev->wep_keys[index].size = 29;
4601 break;
4602 case 128 / 8:
4603 /* WEP 128-bit =
4604 128-bit entered key + 24 bit IV = 152-bit */
4605 adev->wep_keys[index].size = 16;
4606 break;
4607 default:
4608 adev->wep_keys[index].size = 0;
4609 return -EINVAL; /* shouldn't happen */
4612 memset(adev->wep_keys[index].key, 0,
4613 sizeof(adev->wep_keys[index].key));
4614 memcpy(adev->wep_keys[index].key, key, key->keylen);
4615 } else {
4616 /* set transmit key */
4617 if (index <= 3)
4618 adev->wep_current_index = index;
4619 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4620 /* complain if we were not just setting
4621 * the key mode */
4622 // result = -EINVAL;
4623 // goto end_unlock;
4624 // }
4628 adev->wep_enabled = (algorithm == ALG_WEP);
4630 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4632 if (algorithm & IW_ENCODE_OPEN) {
4633 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4634 adev->wep_restricted = 0;
4636 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4637 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4638 adev->wep_restricted = 1;
4641 // adev->auth_alg = algorithm;
4642 /* set flag to make sure the card WEP settings get updated */
4643 if (adev->wep_enabled) {
4644 SET_BIT(adev->set_mask, GETSET_WEP);
4645 acx_s_update_card_settings(adev);
4646 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4649 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4650 dwrq->length, extra, dwrq->flags);
4651 for (index = 0; index <= 3; index++) {
4652 if (adev->wep_keys[index].size) {
4653 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4654 adev->wep_keys[index].index,
4655 (int) adev->wep_keys[index].size,
4656 adev->wep_keys[index].key);
4660 result = -EINPROGRESS;
4661 // acx_sem_unlock(adev);
4663 FN_EXIT1(result);
4664 return result;
4670 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4674 int acx_net_set_key(struct ieee80211_hw *ieee,
4675 enum set_key_cmd cmd, const u8 *local_addr,
4676 const u8 * addr, struct ieee80211_key_conf *key)
4678 // return 0;
4679 struct acx_device *adev = ieee2adev(ieee);
4680 unsigned long flags;
4681 u8 algorithm;
4682 u16 index;
4683 int err = -EINVAL;
4684 FN_ENTER;
4685 // TODO();
4686 switch (key->alg) {
4687 default:
4688 /* case ALG_NONE:
4689 case ALG_NULL:
4690 algorithm = ACX_SEC_ALGO_NONE;
4691 break;
4692 */ case ALG_WEP:
4693 if (key->keylen == 5)
4694 algorithm = ACX_SEC_ALGO_WEP;
4695 else
4696 algorithm = ACX_SEC_ALGO_WEP104;
4697 break;
4698 case ALG_TKIP:
4699 algorithm = ACX_SEC_ALGO_TKIP;
4700 break;
4701 case ALG_CCMP:
4702 algorithm = ACX_SEC_ALGO_AES;
4703 break;
4706 index = (u8) (key->keyidx);
4707 if (index >= ARRAY_SIZE(adev->key))
4708 goto out;
4709 acx_lock(adev, flags);
4710 switch (cmd) {
4711 case SET_KEY:
4712 err = acx_key_write(adev, index, algorithm, key, addr);
4713 if (err)
4714 goto out_unlock;
4715 key->hw_key_idx = index;
4716 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4717 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4718 adev->default_key_idx = index;*/
4719 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4720 adev->key[index].enabled = 1;
4721 break;
4722 case DISABLE_KEY:
4723 adev->key[index].enabled = 0;
4724 err = 0;
4725 break;
4726 /* case ENABLE_COMPRESSION:
4727 case DISABLE_COMPRESSION:
4728 err = 0;
4729 break; */
4731 out_unlock:
4732 acx_unlock(adev, flags);
4733 out:
4734 FN_EXIT0;
4735 return err;
4740 /***********************************************************************
4741 ** Common function to parse ALL configoption struct formats
4742 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4743 ** FIXME: logging should be removed here and added to a /proc file instead
4745 ** Look into bcm43xx
4747 void
4748 acx_s_parse_configoption(acx_device_t * adev,
4749 const acx111_ie_configoption_t * pcfg)
4751 const u8 *pEle;
4752 int i;
4753 int is_acx111 = IS_ACX111(adev);
4755 acx_log_dump(LOG_DEBUG, L_REALLYVERBOSE, pcfg, sizeof(*pcfg),
4756 "configoption struct content:\n");
4758 if ((is_acx111 && (adev->eeprom_version == 5))
4759 || (!is_acx111 && (adev->eeprom_version == 4))
4760 || (!is_acx111 && (adev->eeprom_version == 5))) {
4761 /* these versions are known to be supported */
4762 } else {
4763 acx_log(LOG_WARNING, L_ANY,
4764 "unknown chip and EEPROM version combination "
4765 "(%s, v%d), "
4766 "don't know how to parse config options yet. "
4767 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4768 adev->eeprom_version);
4769 return;
4772 /* first custom-parse the first part which has chip-specific layout */
4774 pEle = (const u8 *)pcfg;
4776 pEle += 4; /* skip (type,len) header */
4778 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4779 pEle += sizeof(adev->cfgopt_NVSv);
4781 if (is_acx111) {
4782 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4783 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4785 adev->cfgopt_probe_delay = 200; /* good default value? */
4786 pEle += 2; /* FIXME: unknown, value 0x0001 */
4787 } else {
4788 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4789 pEle += sizeof(adev->cfgopt_MAC);
4791 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4792 pEle += sizeof(adev->cfgopt_probe_delay);
4793 if ((adev->cfgopt_probe_delay < 100)
4794 || (adev->cfgopt_probe_delay > 500)) {
4795 acx_log(LOG_WARNING, L_ANY,
4796 "strange probe_delay value %d, "
4797 "tweaking to 200\n", adev->cfgopt_probe_delay);
4798 adev->cfgopt_probe_delay = 200;
4802 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4803 pEle += sizeof(adev->cfgopt_eof_memory);
4805 acx_log(LOG_INFO, L_ANY, "NVS_vendor_offs:%04X probe_delay:%d "
4806 "eof_memory:%d\n",
4807 adev->cfgopt_NVS_vendor_offs, adev->cfgopt_probe_delay,
4808 adev->cfgopt_eof_memory);
4810 adev->cfgopt_dot11CCAModes = *pEle++;
4811 adev->cfgopt_dot11Diversity = *pEle++;
4812 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4813 adev->cfgopt_dot11PBCCOption = *pEle++;
4814 adev->cfgopt_dot11ChannelAgility = *pEle++;
4815 adev->cfgopt_dot11PhyType = *pEle++;
4816 adev->cfgopt_dot11TempType = *pEle++;
4817 acx_log(LOG_INFO, L_ANY,
4818 "CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4819 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4820 adev->cfgopt_dot11CCAModes, adev->cfgopt_dot11Diversity,
4821 adev->cfgopt_dot11ShortPreambleOption,
4822 adev->cfgopt_dot11PBCCOption, adev->cfgopt_dot11ChannelAgility,
4823 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4825 /* then use common parsing for next part which has common layout */
4827 pEle++; /* skip table_count (6) */
4829 adev->cfgopt_antennas.type = pEle[0];
4830 adev->cfgopt_antennas.len = pEle[1];
4833 * FIXME: a candidate for acx_log_dump(), but the code is bizarre
4835 acx_log(LOG_INFO, L_ANY, "AntennaID:%02X Len:%02X Data:",
4836 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4837 for (i = 0; i < pEle[1]; i++) {
4838 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4839 printk("%02X ", pEle[i + 2]);
4841 printk("\n");
4843 pEle += pEle[1] + 2;
4844 adev->cfgopt_power_levels.type = pEle[0];
4845 adev->cfgopt_power_levels.len = pEle[1];
4848 * FIXME: see above
4850 acx_log(LOG_INFO, L_ANY, "PowerLevelID:%02X Len:%02X Data:",
4851 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4852 for (i = 0; i < pEle[1]; i++) {
4853 adev->cfgopt_power_levels.list[i] =
4854 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4855 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4857 printk("\n");
4859 pEle += pEle[1] * 2 + 2;
4860 adev->cfgopt_data_rates.type = pEle[0];
4861 adev->cfgopt_data_rates.len = pEle[1];
4864 * FIXME again
4866 acx_log(LOG_INFO, L_ANY, "DataRatesID:%02X Len:%02X Data:",
4867 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4868 for (i = 0; i < pEle[1]; i++) {
4869 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4870 printk("%02X ", pEle[i + 2]);
4872 printk("\n");
4874 pEle += pEle[1] + 2;
4875 adev->cfgopt_domains.type = pEle[0];
4876 adev->cfgopt_domains.len = pEle[1];
4879 * And again
4881 acx_log(LOG_INFO, L_ANY, "DomainID:%02X Len:%02X Data:",
4882 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4883 for (i = 0; i < pEle[1]; i++) {
4884 adev->cfgopt_domains.list[i] = pEle[i + 2];
4885 printk("%02X ", pEle[i + 2]);
4887 printk("\n");
4889 pEle += pEle[1] + 2;
4890 adev->cfgopt_product_id.type = pEle[0];
4891 adev->cfgopt_product_id.len = pEle[1];
4892 for (i = 0; i < pEle[1]; i++) {
4893 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4895 acx_log(LOG_INFO, L_ANY, "ProductID:%02X Len:%02X Data:%.*s\n",
4896 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4897 adev->cfgopt_product_id.len,
4898 (char *)adev->cfgopt_product_id.list);
4900 pEle += pEle[1] + 2;
4901 adev->cfgopt_manufacturer.type = pEle[0];
4902 adev->cfgopt_manufacturer.len = pEle[1];
4903 for (i = 0; i < pEle[1]; i++) {
4904 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4906 acx_log(LOG_INFO, L_ANY, "ManufacturerID:%02X Len:%02X Data:%.*s\n",
4907 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4908 adev->cfgopt_manufacturer.len,
4909 (char *)adev->cfgopt_manufacturer.list);
4911 printk("EEPROM part:\n");
4912 for (i=0; i<58; i++) {
4913 printk("%02X =======> 0x%02X\n",
4914 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4920 /***********************************************************************
4921 ** Linux Kernel Specific
4923 static int __init acx_e_init_module(void)
4925 int r1, r2;
4927 acx_struct_size_check();
4929 acx_log(LOG_INFO, L_ANY, "this driver is still EXPERIMENTAL\n");
4930 acx_log(LOG_INFO, L_ANY, "acx: reading README file and/or "
4931 "Craig's HOWTO is recommended, "
4932 "visit http://acx100.sourceforge.net/wiki in case "
4933 "of further questions/discussion\n");
4935 #if defined(CONFIG_ACX_MAC80211_PCI)
4936 r1 = acxpci_e_init_module();
4937 #else
4938 r1 = -EINVAL;
4939 #endif
4940 #if defined(CONFIG_ACX_MAC80211_USB)
4941 r2 = acxusb_e_init_module();
4942 #else
4943 r2 = -EINVAL;
4944 #endif
4945 if (r2 && r1) /* both failed! */
4946 return r2 ? r2 : r1;
4947 /* return success if at least one succeeded */
4948 return 0;
4951 static void __exit acx_e_cleanup_module(void)
4953 #if defined(CONFIG_ACX_MAC80211_PCI)
4954 acxpci_e_cleanup_module();
4955 #endif
4956 #if defined(CONFIG_ACX_MAC80211_USB)
4957 acxusb_e_cleanup_module();
4958 #endif
4961 module_init(acx_e_init_module)
4962 module_exit(acx_e_cleanup_module)