Cleanups, Changelog additions, new release numbering scheme
[acx-mac80211.git] / common.c
bloba9a3e8036c260199c7cb65b9192475bbef8a874b
1 /*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
3 * The ACX100 Open Source Project <acx100-devel@lists.sourceforge.net>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include <linux/version.h>
19 #include <linux/module.h>
20 #include <linux/kernel.h>
21 #include <linux/sched.h>
22 #include <linux/types.h>
23 #include <linux/slab.h>
24 #include <linux/delay.h>
25 #include <linux/proc_fs.h>
26 #include <linux/if_arp.h>
27 #include <linux/rtnetlink.h>
28 #include <linux/netdevice.h>
29 #include <linux/etherdevice.h>
30 #include <linux/wireless.h>
31 #include <linux/pm.h>
32 #include <linux/vmalloc.h>
33 #include <linux/firmware.h>
34 //#include <net/iw_handler.h>
35 #include <linux/ethtool.h>
36 //#include <linux/utsrelease.h>
38 #include "acx.h"
41 /***********************************************************************
44 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf);
48 /***********************************************************************
50 #if ACX_DEBUG
51 unsigned int acx_debug /* will add __read_mostly later */ = ACX_DEFAULT_MSG;
52 /* parameter is 'debug', corresponding var is acx_debug */
53 module_param_named(debug, acx_debug, uint, 0);
54 MODULE_PARM_DESC(debug, "Debug level mask (see L_xxx constants)");
55 #endif
57 #ifdef MODULE_LICENSE
58 MODULE_LICENSE("Dual MPL/GPL");
59 #endif
60 /* USB had this: MODULE_AUTHOR("Martin Wawro <martin.wawro AT uni-dortmund.de>"); */
61 MODULE_AUTHOR("ACX100 Open Source Driver development team");
62 MODULE_DESCRIPTION
63 ("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)");
65 MODULE_VERSION(ACX_RELEASE);
67 /***********************************************************************
69 /* Probably a number of acx's intermediate buffers for USB transfers,
70 ** not to be confused with number of descriptors in tx/rx rings
71 ** (which are not directly accessible to host in USB devices) */
72 #define USB_RX_CNT 10
73 #define USB_TX_CNT 10
76 /***********************************************************************
79 /* minutes to wait until next radio recalibration: */
80 #define RECALIB_PAUSE 5
82 /* Please keep acx_reg_domain_ids_len in sync... */
83 const u8 acx_reg_domain_ids[acx_reg_domain_ids_len] =
84 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 };
85 static const u16 reg_domain_channel_masks[acx_reg_domain_ids_len] =
86 { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc };
87 const char *const
88 acx_reg_domain_strings[] = {
89 /* 0 */ " 1-11 FCC (USA)",
90 /* 1 */ " 1-11 DOC/IC (Canada)",
91 /* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */
92 /* 2 */ " 1-13 ETSI (Europe)",
93 /* 3 */ "10-11 Spain",
94 /* 4 */ "10-13 France",
95 /* 5 */ " 14 MKK (Japan)",
96 /* 6 */ " 1-14 MKK1",
97 /* 7 */ " 3-9 Israel (not all firmware versions)",
98 NULL /* needs to remain as last entry */
103 /***********************************************************************
104 ** Debugging support
106 #ifdef PARANOID_LOCKING
107 static unsigned max_lock_time;
108 static unsigned max_sem_time;
110 /* Obvious or linux kernel specific derived code follows: */
112 void acx_lock_unhold()
114 max_lock_time = 0;
117 void acx_sem_unhold()
119 max_sem_time = 0;
122 static inline const char *sanitize_str(const char *s)
124 const char *t = strrchr(s, '/');
125 if (t)
126 return t + 1;
127 return s;
130 void acx_lock_debug(acx_device_t * adev, const char *where)
132 unsigned int count = 100 * 1000 * 1000;
133 where = sanitize_str(where);
134 while (--count) {
135 if (!spin_is_locked(&adev->spinlock))
136 break;
137 cpu_relax();
139 if (!count) {
140 printk(KERN_EMERG "acx: LOCKUP: already taken at %s!\n",
141 adev->last_lock);
142 BUG();
144 adev->last_lock = where;
145 rdtscl(adev->lock_time);
148 void acx_unlock_debug(acx_device_t * adev, const char *where)
150 #ifdef SMP
151 if (!spin_is_locked(&adev->spinlock)) {
152 where = sanitize_str(where);
153 printk(KERN_EMERG "acx: STRAY UNLOCK at %s!\n", where);
154 BUG();
156 #endif
157 if (acx_debug & L_LOCK) {
158 unsigned long diff;
159 rdtscl(diff);
160 diff -= adev->lock_time;
161 if (diff > max_lock_time) {
162 where = sanitize_str(where);
163 printk("acx: max lock hold time %ld CPU ticks from %s "
164 "to %s\n", diff, adev->last_lock, where);
165 max_lock_time = diff;
169 #endif /* PARANOID_LOCKING */
172 /***********************************************************************
174 #if ACX_DEBUG > 1
176 static int acx_debug_func_indent;
177 #define DEBUG_TSC 0
178 #define FUNC_INDENT_INCREMENT 2
180 #if DEBUG_TSC
181 #define TIMESTAMP(d) unsigned long d; rdtscl(d)
182 #else
183 #define TIMESTAMP(d) unsigned long d = jiffies
184 #endif
186 static const char spaces[] = " " " "; /* Nx10 spaces */
188 void log_fn_enter(const char *funcname)
190 int indent;
191 TIMESTAMP(d);
193 indent = acx_debug_func_indent;
194 if (indent >= sizeof(spaces))
195 indent = sizeof(spaces) - 1;
197 printk("%08ld %s==> %s\n",
198 d % 100000000, spaces + (sizeof(spaces) - 1) - indent, funcname);
200 acx_debug_func_indent += FUNC_INDENT_INCREMENT;
202 void log_fn_exit(const char *funcname)
204 int indent;
205 TIMESTAMP(d);
207 acx_debug_func_indent -= FUNC_INDENT_INCREMENT;
209 indent = acx_debug_func_indent;
210 if (indent >= sizeof(spaces))
211 indent = sizeof(spaces) - 1;
213 printk("%08ld %s<== %s\n",
214 d % 100000000, spaces + (sizeof(spaces) - 1) - indent, funcname);
216 void log_fn_exit_v(const char *funcname, int v)
218 int indent;
219 TIMESTAMP(d);
221 acx_debug_func_indent -= FUNC_INDENT_INCREMENT;
223 indent = acx_debug_func_indent;
224 if (indent >= sizeof(spaces))
225 indent = sizeof(spaces) - 1;
227 printk("%08ld %s<== %s: %08X\n",
228 d % 100000000,
229 spaces + (sizeof(spaces) - 1) - indent, funcname, v);
231 #endif /* ACX_DEBUG > 1 */
234 /***********************************************************************
235 ** Basically a mdelay/msleep with logging
237 void acx_s_mwait(int ms)
239 FN_ENTER;
240 msleep(ms);
241 FN_EXIT0;
244 /***********************************************************************
245 ** Not inlined: it's larger than it seems
247 void acx_print_mac(const char *head, const u8 * mac, const char *tail)
249 printk("acx: %s" MACSTR "%s", head, MAC(mac), tail);
252 /***********************************************************************
253 ** acx_cmd_status_str
255 const char *acx_cmd_status_str(unsigned int state)
257 static const char *const cmd_error_strings[] = {
258 "Idle",
259 "Success",
260 "Unknown Command",
261 "Invalid Information Element",
262 "Channel rejected",
263 "Channel invalid in current regulatory domain",
264 "MAC invalid",
265 "Command rejected (read-only information element)",
266 "Command rejected",
267 "Already asleep",
268 "TX in progress",
269 "Already awake",
270 "Write only",
271 "RX in progress",
272 "Invalid parameter",
273 "Scan in progress",
274 "Failed"
276 return state < ARRAY_SIZE(cmd_error_strings) ?
277 cmd_error_strings[state] : "?";
280 /***********************************************************************
282 #if ACX_DEBUG
283 void acx_dump_bytes(const void *data, int num)
285 const u8 *ptr = (const u8 *)data;
287 FN_ENTER;
289 if (num <= 0) {
290 printk("\n");
291 return;
294 while (num >= 16) {
295 printk("%02X %02X %02X %02X %02X %02X %02X %02X "
296 "%02X %02X %02X %02X %02X %02X %02X %02X\n",
297 ptr[0], ptr[1], ptr[2], ptr[3],
298 ptr[4], ptr[5], ptr[6], ptr[7],
299 ptr[8], ptr[9], ptr[10], ptr[11],
300 ptr[12], ptr[13], ptr[14], ptr[15]);
301 num -= 16;
302 ptr += 16;
304 if (num > 0) {
305 while (--num > 0)
306 printk("%02X ", *ptr++);
307 printk("%02X\n", *ptr);
310 FN_EXIT0;
313 #endif
316 /***********************************************************************
317 ** acx_s_get_firmware_version
319 ** Obvious
321 void acx_s_get_firmware_version(acx_device_t * adev)
323 fw_ver_t fw;
324 u8 hexarr[4] = { 0, 0, 0, 0 };
325 int hexidx = 0, val = 0;
326 const char *num;
327 char c;
329 FN_ENTER;
331 memset(fw.fw_id, 'E', FW_ID_SIZE);
332 acx_s_interrogate(adev, &fw, ACX1xx_IE_FWREV);
333 memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE);
334 adev->firmware_version[FW_ID_SIZE] = '\0';
336 log(L_DEBUG, "acx: fw_ver: fw_id='%s' hw_id=%08X\n",
337 adev->firmware_version, fw.hw_id);
339 if (strncmp(fw.fw_id, "Rev ", 4) != 0) {
340 printk("acx: strange firmware version string "
341 "'%s', please report\n", adev->firmware_version);
342 adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */
343 } else {
344 num = &fw.fw_id[4];
345 while (1) {
346 c = *num++;
347 if ((c == '.') || (c == '\0')) {
348 hexarr[hexidx++] = val;
349 if ((hexidx > 3) || (c == '\0')) /* end? */
350 break;
351 val = 0;
352 continue;
354 if ((c >= '0') && (c <= '9'))
355 c -= '0';
356 else
357 c = c - 'a' + (char)10;
358 val = val * 16 + c;
361 adev->firmware_numver = (u32) ((hexarr[0] << 24) |
362 (hexarr[1] << 16)
363 | (hexarr[2] << 8) | hexarr[3]);
364 log(L_DEBUG, "acx: firmware_numver 0x%08X\n", adev->firmware_numver);
366 if (IS_ACX111(adev)) {
367 if (adev->firmware_numver == 0x00010011) {
368 /* This one does not survive floodpinging */
369 printk("acx: firmware '%s' is known to be buggy, "
370 "please upgrade\n", adev->firmware_version);
374 adev->firmware_id = le32_to_cpu(fw.hw_id);
376 /* we're able to find out more detailed chip names now */
377 switch (adev->firmware_id & 0xffff0000) {
378 case 0x01010000:
379 case 0x01020000:
380 adev->chip_name = "TNETW1100A";
381 break;
382 case 0x01030000:
383 adev->chip_name = "TNETW1100B";
384 break;
385 case 0x03000000:
386 case 0x03010000:
387 adev->chip_name = "TNETW1130";
388 break;
389 case 0x04030000: /* 0x04030101 is TNETW1450 */
390 adev->chip_name = "TNETW1450";
391 break;
392 default:
393 printk("acx: unknown chip ID 0x%08X, "
394 "please report\n", adev->firmware_id);
395 break;
398 FN_EXIT0;
402 /***********************************************************************
403 ** acx_display_hardware_details
405 ** Displays hw/fw version, radio type etc...
407 ** Obvious
409 void acx_display_hardware_details(acx_device_t * adev)
411 const char *radio_str, *form_str;
413 FN_ENTER;
415 switch (adev->radio_type) {
416 case RADIO_MAXIM_0D:
417 radio_str = "Maxim";
418 break;
419 case RADIO_RFMD_11:
420 radio_str = "RFMD";
421 break;
422 case RADIO_RALINK_15:
423 radio_str = "Ralink";
424 break;
425 case RADIO_RADIA_16:
426 radio_str = "Radia";
427 break;
428 case RADIO_UNKNOWN_17:
429 /* TI seems to have a radio which is
430 * additionally 802.11a capable, too */
431 radio_str = "802.11a/b/g radio?! Please report";
432 break;
433 case RADIO_UNKNOWN_19:
434 radio_str = "A radio used by Safecom cards?! Please report";
435 break;
436 case RADIO_UNKNOWN_1B:
437 radio_str = "An unknown radio used by TNETW1450 USB adapters";
438 break;
439 default:
440 radio_str = "UNKNOWN, please report radio type name!";
441 break;
444 switch (adev->form_factor) {
445 case 0x00:
446 form_str = "unspecified";
447 break;
448 case 0x01:
449 form_str = "(mini-)PCI / CardBus";
450 break;
451 case 0x02:
452 form_str = "USB";
453 break;
454 case 0x03:
455 form_str = "Compact Flash";
456 break;
457 default:
458 form_str = "UNKNOWN, please report";
459 break;
462 printk("acx: chipset %s, radio type 0x%02X (%s), "
463 "form factor 0x%02X (%s), EEPROM version 0x%02X, "
464 "uploaded firmware '%s'\n",
465 adev->chip_name, adev->radio_type, radio_str,
466 adev->form_factor, form_str, adev->eeprom_version,
467 adev->firmware_version);
469 FN_EXIT0;
473 /***********************************************************************
474 ** acx_e_get_stats, acx_e_get_wireless_stats
477 acx_e_get_stats(struct ieee80211_hw *hw,
478 struct ieee80211_low_level_stats *stats)
480 acx_device_t *adev = ieee2adev(hw);
481 unsigned long flags;
482 acx_lock(adev, flags);
483 memcpy(stats, &adev->ieee_stats, sizeof(*stats));
484 acx_unlock(adev, flags);
485 return 0;
489 /***********************************************************************
490 ** maps acx111 tx descr rate field to acx100 one
492 const u8 acx_bitpos2rate100[] = {
493 RATE100_1, /* 0 */
494 RATE100_2, /* 1 */
495 RATE100_5, /* 2 */
496 RATE100_2, /* 3, should not happen */
497 RATE100_2, /* 4, should not happen */
498 RATE100_11, /* 5 */
499 RATE100_2, /* 6, should not happen */
500 RATE100_2, /* 7, should not happen */
501 RATE100_22, /* 8 */
502 RATE100_2, /* 9, should not happen */
503 RATE100_2, /* 10, should not happen */
504 RATE100_2, /* 11, should not happen */
505 RATE100_2, /* 12, should not happen */
506 RATE100_2, /* 13, should not happen */
507 RATE100_2, /* 14, should not happen */
508 RATE100_2, /* 15, should not happen */
511 u8 acx_rate111to100(u16 r)
513 return acx_bitpos2rate100[highest_bit(r)];
517 /***********************************************************************
518 ** Calculate level like the feb 2003 windows driver seems to do
520 * Note: the FreeBSD and DragonFlyBSD drivers seems to use different
521 * so-called correction constants depending on the chip. They will be
522 * defined for now, but as it is still unknown whether they are correct
523 * or not, only the original value will be used. Something else to take
524 * into account is that the OpenBSD driver uses another approach and
525 * defines the maximum RSSI value depending on the chip, rather than
526 * using a value of 100 for all of them, as it is currently done here.
528 #define ACX100_RSSI_CORR 8
529 #define ACX111_RSSI_CORR 5
530 static u8 acx_signal_to_winlevel(u8 rawlevel)
532 /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
533 u8 winlevel = (((ACX100_RSSI_CORR / 2) + (rawlevel * 5)) /
534 ACX100_RSSI_CORR);
536 if (winlevel > 100)
537 winlevel = 100;
538 return winlevel;
541 u8 acx_signal_determine_quality(u8 signal, u8 noise)
543 int qual;
545 qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2;
547 if (qual > 100)
548 return 100;
549 if (qual < 0)
550 return 0;
551 return qual;
555 /***********************************************************************
556 ** Interrogate/configure commands
559 /* FIXME: the lengths given here probably aren't always correct.
560 * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4",
561 * unless the firmware actually expects a different length than the struct length */
562 static const u16 acx100_ie_len[] = {
564 ACX100_IE_ACX_TIMER_LEN,
565 sizeof(acx100_ie_powersave_t) - 4, /* is that 6 or 8??? */
566 ACX1xx_IE_QUEUE_CONFIG_LEN,
567 ACX100_IE_BLOCK_SIZE_LEN,
568 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
569 ACX1xx_IE_RATE_FALLBACK_LEN,
570 ACX100_IE_WEP_OPTIONS_LEN,
571 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
573 ACX1xx_IE_ASSOC_ID_LEN,
575 ACX111_IE_CONFIG_OPTIONS_LEN,
576 ACX1xx_IE_FWREV_LEN,
577 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
578 ACX1xx_IE_MEDIUM_USAGE_LEN,
579 ACX1xx_IE_RXCONFIG_LEN,
582 sizeof(fw_stats_t) - 4,
584 ACX1xx_IE_FEATURE_CONFIG_LEN,
585 ACX111_IE_KEY_CHOOSE_LEN,
586 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
587 ACX1FF_IE_WONE_CONFIG_LEN,
589 ACX1FF_IE_TID_CONFIG_LEN,
593 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
594 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
595 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
596 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
598 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
599 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
600 ACX1FF_IE_CCA_THRESHOLD_LEN,
601 ACX1FF_IE_EVENT_MASK_LEN,
602 ACX1FF_IE_DTIM_PERIOD_LEN,
604 ACX1FF_IE_ACI_CONFIG_SET_LEN,
611 ACX1FF_IE_EEPROM_VER_LEN,
614 static const u16 acx100_ie_len_dot11[] = {
616 ACX1xx_IE_DOT11_STATION_ID_LEN,
618 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
619 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
620 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
621 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
622 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
623 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
625 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
626 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
628 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
629 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
630 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
631 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
637 static const u16 acx111_ie_len[] = {
639 ACX100_IE_ACX_TIMER_LEN,
640 sizeof(acx111_ie_powersave_t) - 4,
641 ACX1xx_IE_QUEUE_CONFIG_LEN,
642 ACX100_IE_BLOCK_SIZE_LEN,
643 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
644 ACX1xx_IE_RATE_FALLBACK_LEN,
645 ACX100_IE_WEP_OPTIONS_LEN,
646 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
648 ACX1xx_IE_ASSOC_ID_LEN,
650 ACX111_IE_CONFIG_OPTIONS_LEN,
651 ACX1xx_IE_FWREV_LEN,
652 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
653 ACX1xx_IE_MEDIUM_USAGE_LEN,
654 ACX1xx_IE_RXCONFIG_LEN,
657 sizeof(fw_stats_t) - 4,
659 ACX1xx_IE_FEATURE_CONFIG_LEN,
660 ACX111_IE_KEY_CHOOSE_LEN,
661 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
662 ACX1FF_IE_WONE_CONFIG_LEN,
664 ACX1FF_IE_TID_CONFIG_LEN,
668 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
669 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
670 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
671 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
673 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
674 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
675 ACX1FF_IE_CCA_THRESHOLD_LEN,
676 ACX1FF_IE_EVENT_MASK_LEN,
677 ACX1FF_IE_DTIM_PERIOD_LEN,
679 ACX1FF_IE_ACI_CONFIG_SET_LEN,
686 ACX1FF_IE_EEPROM_VER_LEN,
689 static const u16 acx111_ie_len_dot11[] = {
691 ACX1xx_IE_DOT11_STATION_ID_LEN,
693 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
694 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
695 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
696 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
697 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
698 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
700 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
701 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
703 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
704 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
705 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
706 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
713 #undef FUNC
714 #define FUNC "configure"
715 #if !ACX_DEBUG
716 int acx_s_configure(acx_device_t * adev, void *pdr, int type)
718 #else
720 acx_s_configure_debug(acx_device_t * adev, void *pdr, int type,
721 const char *typestr)
723 #endif
724 u16 len;
725 int res;
727 if (type < 0x1000)
728 len = adev->ie_len[type];
729 else
730 len = adev->ie_len_dot11[type - 0x1000];
732 log(L_CTL, "acx: " FUNC "(type:%s,len:%u)\n", typestr, len);
733 if (unlikely(!len)) {
734 log(L_DEBUG, "acx: zero-length type %s?!\n", typestr);
737 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
738 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
739 res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4);
740 if (unlikely(OK != res)) {
741 #if ACX_DEBUG
742 printk("acx: %s: " FUNC "(type:%s) FAILED\n", wiphy_name(adev->ieee->wiphy),
743 typestr);
744 #else
745 printk("acx: %s: " FUNC "(type:0x%X) FAILED\n", wiphy_name(adev->ieee->wiphy),
746 type);
747 #endif
748 /* dump_stack() is already done in issue_cmd() */
750 return res;
753 #undef FUNC
754 #define FUNC "interrogate"
755 #if !ACX_DEBUG
756 int acx_s_interrogate(acx_device_t * adev, void *pdr, int type)
758 #else
760 acx_s_interrogate_debug(acx_device_t * adev, void *pdr, int type,
761 const char *typestr)
763 #endif
764 u16 len;
765 int res;
767 FN_ENTER;
769 /* FIXME: no check whether this exceeds the array yet.
770 * We should probably remember the number of entries... */
771 if (type < 0x1000)
772 len = adev->ie_len[type];
773 else
774 len = adev->ie_len_dot11[type - 0x1000];
776 log(L_CTL, "acx: " FUNC "(type:%s,len:%u)\n", typestr, len);
778 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
779 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
780 res = acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, pdr, len + 4);
781 if (unlikely(OK != res)) {
782 #if ACX_DEBUG
783 printk("acx: %s: " FUNC "(type:%s) FAILED\n", wiphy_name(adev->ieee->wiphy),
784 typestr);
785 #else
786 printk("acx: %s: " FUNC "(type:0x%X) FAILED\n", wiphy_name(adev->ieee->wiphy),
787 type);
788 #endif
789 /* dump_stack() is already done in issue_cmd() */
792 FN_EXIT1(res);
793 return res;
796 #if CMD_DISCOVERY
797 void great_inquisitor(acx_device_t * adev)
799 static struct {
800 u16 type;
801 u16 len;
802 /* 0x200 was too large here: */
803 u8 data[0x100 - 4];
804 } ACX_PACKED ie;
805 u16 type;
807 FN_ENTER;
809 /* 0..0x20, 0x1000..0x1020 */
810 for (type = 0; type <= 0x1020; type++) {
811 if (type == 0x21)
812 type = 0x1000;
813 ie.type = cpu_to_le16(type);
814 ie.len = cpu_to_le16(sizeof(ie) - 4);
815 acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie));
817 FN_EXIT0;
819 #endif
822 #ifdef CONFIG_PROC_FS
823 /***********************************************************************
824 ** /proc files
826 /***********************************************************************
827 ** acx_l_proc_output
828 ** Generate content for our /proc entry
830 ** Arguments:
831 ** buf is a pointer to write output to
832 ** adev is the usual pointer to our private struct acx_device
833 ** Returns:
834 ** number of bytes actually written to buf
835 ** Side effects:
836 ** none
838 static int acx_l_proc_output(char *buf, acx_device_t * adev)
840 char *p = buf;
842 FN_ENTER;
844 p += sprintf(p,
845 "acx driver version:\t\t" ACX_RELEASE "\n"
846 "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n"
847 "chip name:\t\t\t%s (0x%08X)\n"
848 "radio type:\t\t\t0x%02X\n"
849 "form factor:\t\t\t0x%02X\n"
850 "EEPROM version:\t\t\t0x%02X\n"
851 "firmware version:\t\t%s (0x%08X)\n",
852 adev->chip_name, adev->firmware_id,
853 adev->radio_type,
854 adev->form_factor,
855 adev->eeprom_version,
856 adev->firmware_version, adev->firmware_numver);
858 FN_EXIT1(p - buf);
859 return p - buf;
863 /***********************************************************************
865 static int acx_s_proc_diag_output(char *buf, acx_device_t * adev)
867 char *p = buf;
868 unsigned long flags;
869 ssize_t len = 0, partlen;
870 u32 temp1, temp2;
871 u8 *st, *st_end;
872 #ifdef __BIG_ENDIAN
873 u8 *st2;
874 #endif
875 fw_stats_t *fw_stats;
876 char *part_str = NULL;
877 fw_stats_tx_t *tx = NULL;
878 fw_stats_rx_t *rx = NULL;
879 fw_stats_dma_t *dma = NULL;
880 fw_stats_irq_t *irq = NULL;
881 fw_stats_wep_t *wep = NULL;
882 fw_stats_pwr_t *pwr = NULL;
883 fw_stats_mic_t *mic = NULL;
884 fw_stats_aes_t *aes = NULL;
885 fw_stats_event_t *evt = NULL;
887 FN_ENTER;
889 acx_lock(adev, flags);
891 if (IS_PCI(adev))
892 p = acxpci_s_proc_diag_output(p, adev);
894 p += sprintf(p,
895 "\n"
896 "** network status **\n"
897 "dev_state_mask 0x%04X\n"
898 "mode %u, channel %u, "
899 "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
900 adev->dev_state_mask,
901 adev->mode, adev->channel,
902 adev->reg_dom_id, adev->reg_dom_chanmask);
903 p += sprintf(p,
904 "ESSID \"%s\", essid_active %d, essid_len %d, "
905 "essid_for_assoc \"%s\", nick \"%s\"\n"
906 "WEP ena %d, restricted %d, idx %d\n",
907 adev->essid, adev->essid_active, (int)adev->essid_len,
908 adev->essid_for_assoc, adev->nick,
909 adev->wep_enabled, adev->wep_restricted,
910 adev->wep_current_index);
911 p += sprintf(p, "dev_addr " MACSTR "\n", MAC(adev->dev_addr));
912 p += sprintf(p, "bssid " MACSTR "\n", MAC(adev->bssid));
913 p += sprintf(p, "ap_filter " MACSTR "\n", MAC(adev->ap));
915 p += sprintf(p, "\n" "** PHY status **\n"
916 "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
917 "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
918 "rate_basic 0x%04X, rate_oper 0x%04X\n"
919 "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
920 "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
921 adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */
922 adev->sensitivity, adev->antenna, adev->ed_threshold,
923 adev->cca, adev->preamble_mode, adev->rate_basic, adev->rate_oper, adev->rts_threshold,
924 adev->frag_threshold, adev->short_retry, adev->long_retry,
925 adev->msdu_lifetime, adev->listen_interval,
926 adev->beacon_interval);
928 acx_unlock(adev, flags);
930 p += sprintf(p,
931 "\n"
932 "** Firmware **\n"
933 "NOTE: version dependent statistics layout, "
934 "please report if you suspect wrong parsing!\n"
935 "\n" "version \"%s\"\n", adev->firmware_version);
937 /* TODO: may replace kmalloc/memset with kzalloc once
938 * Linux 2.6.14 is widespread */
939 fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL);
940 if (!fw_stats) {
941 FN_EXIT1(0);
942 return 0;
944 memset(fw_stats, 0, sizeof(*fw_stats));
946 st = (u8 *) fw_stats;
948 part_str = "statistics query command";
950 if (OK != acx_s_interrogate(adev, st, ACX1xx_IE_FIRMWARE_STATISTICS))
951 goto fw_stats_end;
953 st += sizeof(u16);
954 len = *(u16 *) st;
956 if (len > sizeof(*fw_stats)) {
957 p += sprintf(p,
958 "firmware version with bigger fw_stats struct detected\n"
959 "(%zu vs. %zu), please report\n", len, sizeof(fw_stats_t));
960 if (len > sizeof(*fw_stats)) {
961 p += sprintf(p, "struct size exceeded allocation!\n");
962 len = sizeof(*fw_stats);
965 st += sizeof(u16);
966 st_end = st - 2 * sizeof(u16) + len;
968 #ifdef __BIG_ENDIAN
969 /* let's make one bold assumption here:
970 * (hopefully!) *all* statistics fields are u32 only,
971 * thus if we need to make endianness corrections
972 * we can simply do them in one go, in advance */
973 st2 = (u8 *) fw_stats;
974 for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4)
975 *(u32 *) st2 = le32_to_cpu(*(u32 *) st2);
976 #endif
978 part_str = "Rx/Tx";
980 /* directly at end of a struct part? --> no error! */
981 if (st == st_end)
982 goto fw_stats_end;
984 tx = (fw_stats_tx_t *) st;
985 st += sizeof(fw_stats_tx_t);
986 rx = (fw_stats_rx_t *) st;
987 st += sizeof(fw_stats_rx_t);
988 partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t);
990 if (IS_ACX100(adev)) {
991 /* at least ACX100 PCI F/W 1.9.8.b
992 * and ACX100 USB F/W 1.0.7-USB
993 * don't have those two fields... */
994 st -= 2 * sizeof(u32);
996 /* our parsing doesn't quite match this firmware yet,
997 * log failure */
998 if (st > st_end)
999 goto fw_stats_fail;
1000 temp1 = temp2 = 999999999;
1001 } else {
1002 if (st > st_end)
1003 goto fw_stats_fail;
1004 temp1 = rx->rx_aci_events;
1005 temp2 = rx->rx_aci_resets;
1008 p += sprintf(p,
1009 "%s:\n"
1010 " tx_desc_overfl %u\n"
1011 " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
1012 " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n"
1013 " rx_aci_events %u, rx_aci_resets %u\n",
1014 part_str,
1015 tx->tx_desc_of,
1016 rx->rx_oom,
1017 rx->rx_hdr_of,
1018 rx->rx_hw_stuck,
1019 rx->rx_dropped_frame,
1020 rx->rx_frame_ptr_err, rx->rx_xfr_hint_trig, temp1, temp2);
1022 part_str = "DMA";
1024 if (st == st_end)
1025 goto fw_stats_end;
1027 dma = (fw_stats_dma_t *) st;
1028 partlen = sizeof(fw_stats_dma_t);
1029 st += partlen;
1031 if (st > st_end)
1032 goto fw_stats_fail;
1034 p += sprintf(p,
1035 "%s:\n"
1036 " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n",
1037 part_str,
1038 dma->rx_dma_req,
1039 dma->rx_dma_err, dma->tx_dma_req, dma->tx_dma_err);
1041 part_str = "IRQ";
1043 if (st == st_end)
1044 goto fw_stats_end;
1046 irq = (fw_stats_irq_t *) st;
1047 partlen = sizeof(fw_stats_irq_t);
1048 st += partlen;
1050 if (st > st_end)
1051 goto fw_stats_fail;
1053 p += sprintf(p,
1054 "%s:\n"
1055 " cmd_cplt %u, fiq %u\n"
1056 " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
1057 " irqs %u, tx_procs %u, decrypt_done %u\n"
1058 " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
1059 " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
1060 " host_acks %u, pci_pm %u, acm_wakeups %u\n",
1061 part_str,
1062 irq->cmd_cplt,
1063 irq->fiq,
1064 irq->rx_hdrs,
1065 irq->rx_cmplt,
1066 irq->rx_mem_of,
1067 irq->rx_rdys,
1068 irq->irqs,
1069 irq->tx_procs,
1070 irq->decrypt_done,
1071 irq->dma_0_done,
1072 irq->dma_1_done,
1073 irq->tx_exch_complet,
1074 irq->commands,
1075 irq->rx_procs,
1076 irq->hw_pm_mode_changes,
1077 irq->host_acks, irq->pci_pm, irq->acm_wakeups);
1079 part_str = "WEP";
1081 if (st == st_end)
1082 goto fw_stats_end;
1084 wep = (fw_stats_wep_t *) st;
1085 partlen = sizeof(fw_stats_wep_t);
1086 st += partlen;
1088 if (IS_ACX100(adev)) {
1089 /* at least ACX100 PCI F/W 1.9.8.b
1090 * and ACX100 USB F/W 1.0.7-USB
1091 * don't have those two fields... */
1092 st -= 2 * sizeof(u32);
1093 if (st > st_end)
1094 goto fw_stats_fail;
1095 temp1 = temp2 = 999999999;
1096 } else {
1097 if (st > st_end)
1098 goto fw_stats_fail;
1099 temp1 = wep->wep_pkt_decrypt;
1100 temp2 = wep->wep_decrypt_irqs;
1103 p += sprintf(p,
1104 "%s:\n"
1105 " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
1106 " wep_key_not_found %u, wep_decrypt_fail %u\n"
1107 " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
1108 part_str,
1109 wep->wep_key_count,
1110 wep->wep_default_key_count,
1111 wep->dot11_def_key_mib,
1112 wep->wep_key_not_found,
1113 wep->wep_decrypt_fail, temp1, temp2);
1115 part_str = "power";
1117 if (st == st_end)
1118 goto fw_stats_end;
1120 pwr = (fw_stats_pwr_t *) st;
1121 partlen = sizeof(fw_stats_pwr_t);
1122 st += partlen;
1124 if (st > st_end)
1125 goto fw_stats_fail;
1127 p += sprintf(p,
1128 "%s:\n"
1129 " tx_start_ctr %u, no_ps_tx_too_short %u\n"
1130 " rx_start_ctr %u, no_ps_rx_too_short %u\n"
1131 " lppd_started %u\n"
1132 " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n",
1133 part_str,
1134 pwr->tx_start_ctr,
1135 pwr->no_ps_tx_too_short,
1136 pwr->rx_start_ctr,
1137 pwr->no_ps_rx_too_short,
1138 pwr->lppd_started,
1139 pwr->no_lppd_too_noisy,
1140 pwr->no_lppd_too_short, pwr->no_lppd_matching_frame);
1142 part_str = "MIC";
1144 if (st == st_end)
1145 goto fw_stats_end;
1147 mic = (fw_stats_mic_t *) st;
1148 partlen = sizeof(fw_stats_mic_t);
1149 st += partlen;
1151 if (st > st_end)
1152 goto fw_stats_fail;
1154 p += sprintf(p,
1155 "%s:\n"
1156 " mic_rx_pkts %u, mic_calc_fail %u\n",
1157 part_str, mic->mic_rx_pkts, mic->mic_calc_fail);
1159 part_str = "AES";
1161 if (st == st_end)
1162 goto fw_stats_end;
1164 aes = (fw_stats_aes_t *) st;
1165 partlen = sizeof(fw_stats_aes_t);
1166 st += partlen;
1168 if (st > st_end)
1169 goto fw_stats_fail;
1171 p += sprintf(p,
1172 "%s:\n"
1173 " aes_enc_fail %u, aes_dec_fail %u\n"
1174 " aes_enc_pkts %u, aes_dec_pkts %u\n"
1175 " aes_enc_irq %u, aes_dec_irq %u\n",
1176 part_str,
1177 aes->aes_enc_fail,
1178 aes->aes_dec_fail,
1179 aes->aes_enc_pkts,
1180 aes->aes_dec_pkts, aes->aes_enc_irq, aes->aes_dec_irq);
1182 part_str = "event";
1184 if (st == st_end)
1185 goto fw_stats_end;
1187 evt = (fw_stats_event_t *) st;
1188 partlen = sizeof(fw_stats_event_t);
1189 st += partlen;
1191 if (st > st_end)
1192 goto fw_stats_fail;
1194 p += sprintf(p,
1195 "%s:\n"
1196 " heartbeat %u, calibration %u\n"
1197 " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
1198 " oom_late %u\n"
1199 " phy_tx_err %u, tx_stuck %u\n",
1200 part_str,
1201 evt->heartbeat,
1202 evt->calibration,
1203 evt->rx_mismatch,
1204 evt->rx_mem_empty,
1205 evt->rx_pool,
1206 evt->oom_late, evt->phy_tx_err, evt->tx_stuck);
1208 if (st < st_end)
1209 goto fw_stats_bigger;
1211 goto fw_stats_end;
1213 fw_stats_fail:
1214 st -= partlen;
1215 p += sprintf(p,
1216 "failed at %s part (size %zu), offset %zu (struct size %zu), "
1217 "please report\n", part_str, partlen,
1218 ((void *)st - (void *)fw_stats), len);
1220 fw_stats_bigger:
1221 for (; st < st_end; st += 4)
1222 p += sprintf(p,
1223 "UNKN%3d: %u\n",
1224 (int)((void *)st - (void *)fw_stats), *(u32 *) st);
1226 fw_stats_end:
1227 kfree(fw_stats);
1229 FN_EXIT1(p - buf);
1230 return p - buf;
1234 /***********************************************************************
1236 static int acx_s_proc_phy_output(char *buf, acx_device_t * adev)
1238 char *p = buf;
1239 int i;
1241 FN_ENTER;
1244 if (RADIO_RFMD_11 != adev->radio_type) {
1245 printk("acx: sorry, not yet adapted for radio types "
1246 "other than RFMD, please verify "
1247 "PHY size etc. first!\n");
1248 goto end;
1252 /* The PHY area is only 0x80 bytes long; further pages after that
1253 * only have some page number registers with altered value,
1254 * all other registers remain the same. */
1255 for (i = 0; i < 0x80; i++) {
1256 acx_s_read_phy_reg(adev, i, p++);
1259 FN_EXIT1(p - buf);
1260 return p - buf;
1264 /***********************************************************************
1265 ** acx_e_read_proc_XXXX
1266 ** Handle our /proc entry
1268 ** Arguments:
1269 ** standard kernel read_proc interface
1270 ** Returns:
1271 ** number of bytes written to buf
1272 ** Side effects:
1273 ** none
1275 static int
1276 acx_e_read_proc(char *buf, char **start, off_t offset, int count,
1277 int *eof, void *data)
1279 acx_device_t *adev = (acx_device_t *) data;
1280 unsigned long flags;
1281 int length;
1283 FN_ENTER;
1285 acx_sem_lock(adev);
1286 acx_lock(adev, flags);
1287 /* fill buf */
1288 length = acx_l_proc_output(buf, adev);
1289 acx_unlock(adev, flags);
1290 acx_sem_unlock(adev);
1292 /* housekeeping */
1293 if (length <= offset + count)
1294 *eof = 1;
1295 *start = buf + offset;
1296 length -= offset;
1297 if (length > count)
1298 length = count;
1299 if (length < 0)
1300 length = 0;
1301 FN_EXIT1(length);
1302 return length;
1305 static int
1306 acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count,
1307 int *eof, void *data)
1309 acx_device_t *adev = (acx_device_t *) data;
1310 int length;
1312 FN_ENTER;
1314 acx_sem_lock(adev);
1315 /* fill buf */
1316 length = acx_s_proc_diag_output(buf, adev);
1317 acx_sem_unlock(adev);
1319 /* housekeeping */
1320 if (length <= offset + count)
1321 *eof = 1;
1322 *start = buf + offset;
1323 length -= offset;
1324 if (length > count)
1325 length = count;
1326 if (length < 0)
1327 length = 0;
1328 FN_EXIT1(length);
1329 return length;
1332 static int
1333 acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count,
1334 int *eof, void *data)
1336 acx_device_t *adev = (acx_device_t *) data;
1337 int length;
1339 FN_ENTER;
1341 /* fill buf */
1342 length = 0;
1343 if (IS_PCI(adev)) {
1344 acx_sem_lock(adev);
1345 length = acxpci_proc_eeprom_output(buf, adev);
1346 acx_sem_unlock(adev);
1349 /* housekeeping */
1350 if (length <= offset + count)
1351 *eof = 1;
1352 *start = buf + offset;
1353 length -= offset;
1354 if (length > count)
1355 length = count;
1356 if (length < 0)
1357 length = 0;
1358 FN_EXIT1(length);
1359 return length;
1362 static int
1363 acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count,
1364 int *eof, void *data)
1366 acx_device_t *adev = (acx_device_t *) data;
1367 int length;
1369 FN_ENTER;
1371 acx_sem_lock(adev);
1372 /* fill buf */
1373 length = acx_s_proc_phy_output(buf, adev);
1374 acx_sem_unlock(adev);
1376 /* housekeeping */
1377 if (length <= offset + count)
1378 *eof = 1;
1379 *start = buf + offset;
1380 length -= offset;
1381 if (length > count)
1382 length = count;
1383 if (length < 0)
1384 length = 0;
1385 FN_EXIT1(length);
1386 return length;
1390 /***********************************************************************
1391 ** /proc files registration
1393 static const char *const
1394 proc_files[] = { "", "_diag", "_eeprom", "_phy" };
1396 static read_proc_t *const
1397 proc_funcs[] = {
1398 acx_e_read_proc,
1399 acx_e_read_proc_diag,
1400 acx_e_read_proc_eeprom,
1401 acx_e_read_proc_phy
1404 static int manage_proc_entries(struct ieee80211_hw *hw, int remove)
1406 acx_device_t *adev = ieee2adev(hw);
1407 char procbuf[80];
1408 int i;
1410 FN_ENTER;
1412 for (i = 0; i < ARRAY_SIZE(proc_files); i++) {
1413 snprintf(procbuf, sizeof(procbuf),
1414 "driver/acx%s", proc_files[i]);
1415 log(L_INIT, "acx: %sing /proc entry %s\n",
1416 remove ? "remov" : "creat", procbuf);
1417 if (!remove) {
1418 if (!create_proc_read_entry
1419 (procbuf, 0, NULL, proc_funcs[i], adev)) {
1420 printk("acx: cannot register /proc entry %s\n",
1421 procbuf);
1422 FN_EXIT1(NOT_OK);
1423 return NOT_OK;
1425 } else {
1426 remove_proc_entry(procbuf, NULL);
1429 FN_EXIT0;
1430 return OK;
1433 int acx_proc_register_entries(struct ieee80211_hw *ieee)
1435 return manage_proc_entries(ieee, 0);
1438 int acx_proc_unregister_entries(struct ieee80211_hw *ieee)
1440 return manage_proc_entries(ieee, 1);
1442 #endif /* CONFIG_PROC_FS */
1444 /****
1445 ** Gathered From rt2x00 and bcm43xx_mac80211 projects
1447 void acx_free_modes(acx_device_t * adev)
1450 // kfree(adev->modes);
1451 // adev->modes = NULL;
1455 #define RATETAB_ENT(_rate, _rateid, _flags) \
1457 .rate = (_rate), \
1458 .val = (_rateid), \
1459 .val2 = (_rateid), \
1460 .flags = (_flags), \
1464 static struct ieee80211_rate __acx_rates[] = {
1465 { .rate = 10,
1466 .val = RATE111_1,
1467 .flags = IEEE80211_RATE_CCK },
1468 { .rate = 20,
1469 .val = RATE111_2,
1470 .flags = IEEE80211_RATE_CCK },
1471 { .rate = 55,
1472 .val = RATE111_5,
1473 .flags = IEEE80211_RATE_CCK },
1474 { .rate = 110,
1475 .val = RATE111_11,
1476 .flags = IEEE80211_RATE_CCK },
1477 { .rate = 60,
1478 .val = RATE111_6,
1479 .flags = IEEE80211_RATE_OFDM },
1480 { .rate = 90,
1481 .val = RATE111_9,
1482 .flags = IEEE80211_RATE_OFDM },
1483 { .rate = 120,
1484 .val = RATE111_12,
1485 .flags = IEEE80211_RATE_OFDM },
1486 { .rate = 180,
1487 .val = RATE111_18,
1488 .flags = IEEE80211_RATE_OFDM },
1489 { .rate = 240,
1490 .val = RATE111_24,
1491 .flags = IEEE80211_RATE_OFDM },
1492 { .rate = 360,
1493 .val = RATE111_36,
1494 .flags = IEEE80211_RATE_OFDM },
1495 { .rate = 480,
1496 .val = RATE111_48,
1497 .flags = IEEE80211_RATE_OFDM },
1498 { .rate = 540,
1499 .val = RATE111_54,
1500 .flags = IEEE80211_RATE_OFDM },
1503 static struct ieee80211_channel channels[] = {
1504 { .chan = 1,
1505 .freq = 2412},
1506 { .chan = 2,
1507 .freq = 2417},
1508 { .chan = 3,
1509 .freq = 2422},
1510 { .chan = 4,
1511 .freq = 2427},
1512 { .chan = 5,
1513 .freq = 2432},
1514 { .chan = 6,
1515 .freq = 2437},
1516 { .chan = 7,
1517 .freq = 2442},
1518 { .chan = 8,
1519 .freq = 2447},
1520 { .chan = 9,
1521 .freq = 2452},
1522 { .chan = 10,
1523 .freq = 2457},
1524 { .chan = 11,
1525 .freq = 2462},
1526 { .chan = 12,
1527 .freq = 2467},
1528 { .chan = 13,
1529 .freq = 2472},
1532 int acx_setup_modes(acx_device_t * adev)
1534 struct ieee80211_hw *hw = adev->ieee;
1535 struct ieee80211_hw_mode *mode;
1536 int err = -ENOMEM;
1538 FN_ENTER;
1540 if (IS_ACX111(adev)) {
1542 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);
1543 err = acx_setup_modes_gphy(adev);
1545 mode = &adev->modes[0];
1547 /* from the zd1211rw driver: - do we need to do the same? */
1549 memcpy(mode->channels, channels, sizeof(channels));
1550 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1553 mode->mode = MODE_IEEE80211G;
1554 mode->num_channels = ARRAY_SIZE(channels);
1555 mode->num_rates = 12;
1556 mode->rates = __acx_rates;
1557 } else {
1559 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1560 err = acx_setup_modes_bphy(adev);
1562 mode = &adev->modes[1];
1564 /* from the zd1211rw driver: - do we need to do the same? */
1566 memcpy(mode->channels, channels, sizeof(channels));
1567 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1570 mode->mode = MODE_IEEE80211B;
1571 mode->num_channels = ARRAY_SIZE(channels);
1572 mode->num_rates = 4;
1573 mode->rates = __acx_rates;
1576 /* if (err && adev->modes)
1577 kfree(adev->modes);*/
1579 mode->channels = channels;
1580 err = ieee80211_register_hwmode(hw, mode);
1582 FN_EXIT1(err);
1583 return err;
1587 /***********************************************************************
1588 ** acx_fill_beacon_or_proberesp_template
1590 ** Origin: derived from rt2x00 project
1592 static int
1593 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1594 struct acx_template_beacon *templ,
1595 struct sk_buff* skb /* in host order! */)
1597 FN_ENTER;
1599 memcpy(templ,skb->data, skb->len);
1600 FN_EXIT1(skb->len);
1601 return skb->len;
1604 /***********************************************************************
1605 ** acx_s_set_beacon_template
1609 static int
1610 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1612 struct acx_template_beacon bcn;
1613 int len, result;
1615 FN_ENTER;
1616 printk("acx: Size of template: %08zX, Size of beacon: %08X\n", sizeof(struct acx_template_beacon),skb->len);
1617 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1618 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1620 FN_EXIT1(result);
1621 return result;
1624 /***********************************************************************
1625 ** acx_cmd_join_bssid
1627 ** Common code for both acx100 and acx111.
1629 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1630 static const u8 bitpos2genframe_txrate[] = {
1631 10, /* 0. 1 Mbit/s */
1632 20, /* 1. 2 Mbit/s */
1633 55, /* 2. 5.5 Mbit/s */
1634 0x0B, /* 3. 6 Mbit/s */
1635 0x0F, /* 4. 9 Mbit/s */
1636 110, /* 5. 11 Mbit/s */
1637 0x0A, /* 6. 12 Mbit/s */
1638 0x0E, /* 7. 18 Mbit/s */
1639 220, /* 8. 22 Mbit/s */
1640 0x09, /* 9. 24 Mbit/s */
1641 0x0D, /* 10. 36 Mbit/s */
1642 0x08, /* 11. 48 Mbit/s */
1643 0x0C, /* 12. 54 Mbit/s */
1644 10, /* 13. 1 Mbit/s, should never happen */
1645 10, /* 14. 1 Mbit/s, should never happen */
1646 10, /* 15. 1 Mbit/s, should never happen */
1649 /* Looks scary, eh?
1650 ** Actually, each one compiled into one AND and one SHIFT,
1651 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1652 static inline unsigned int rate111to5bits(unsigned int rate)
1654 return (rate & 0x7)
1655 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1656 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1660 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1662 acx_joinbss_t tmp;
1663 int dtim_interval;
1664 int i;
1666 if (mac_is_zero(bssid))
1667 return;
1669 FN_ENTER;
1671 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1672 1 : adev->dtim_interval;
1674 memset(&tmp, 0, sizeof(tmp));
1676 for (i = 0; i < ETH_ALEN; i++) {
1677 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1680 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1682 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1683 ** are sent with one of these rates */
1684 if (IS_ACX111(adev)) {
1685 /* It was experimentally determined that rates_basic
1686 ** can take 11g rates as well, not only rates
1687 ** defined with JOINBSS_RATES_BASIC111_nnn.
1688 ** Just use RATE111_nnn constants... */
1689 tmp.u.acx111.dtim_interval = dtim_interval;
1690 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1691 log(L_ASSOC, "acx: rates_basic:%04X, rates_supported:%04X\n",
1692 adev->rate_basic, adev->rate_oper);
1693 } else {
1694 tmp.u.acx100.dtim_interval = dtim_interval;
1695 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1696 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1697 log(L_ASSOC, "acx: rates_basic:%04X->%02X, "
1698 "rates_supported:%04X->%02X\n",
1699 adev->rate_basic, tmp.u.acx100.rates_basic,
1700 adev->rate_oper, tmp.u.acx100.rates_supported);
1703 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1704 ** will be sent (rate/modulation/preamble) */
1705 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1706 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1707 /* we can use short pre *if* all peers can understand it */
1708 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1710 /* we switch fw to STA mode in MONITOR mode, it seems to be
1711 ** the only mode where fw does not emit beacons by itself
1712 ** but allows us to send anything (we really want to retain
1713 ** ability to tx arbitrary frames in MONITOR mode)
1715 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1716 tmp.channel = adev->channel;
1717 tmp.essid_len = adev->essid_len;
1719 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1720 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1722 log(L_ASSOC|L_DEBUG, "acx: BSS_Type = %u\n", tmp.macmode);
1723 acxlog_mac(L_ASSOC|L_DEBUG, "acx: JoinBSSID MAC:", adev->bssid, "\n");
1725 /* acx_update_capabilities(adev); */
1726 FN_EXIT0;
1729 /***********************************************************************
1730 ** acxpci_i_set_multicast_list
1731 ** FIXME: most likely needs refinement
1734 void acx_i_set_multicast_list(struct ieee80211_hw *hw,
1735 unsigned int changed_flags,
1736 unsigned int *total_flags,
1737 int mc_count, struct dev_addr_list *mc_list)
1739 acx_device_t *adev = ieee2adev(hw);
1740 unsigned long flags;
1742 FN_ENTER;
1744 acx_lock(adev, flags);
1746 changed_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1747 FIF_CONTROL | FIF_OTHER_BSS);
1748 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1749 FIF_CONTROL | FIF_OTHER_BSS);
1750 /* if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1751 return; */
1753 if (*total_flags) {
1754 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1755 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1756 SET_BIT(adev->set_mask, SET_RXCONFIG);
1757 /* let kernel know in case *we* needed to set promiscuous */
1758 } else {
1759 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1760 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1761 SET_BIT(adev->set_mask, SET_RXCONFIG);
1764 /* cannot update card settings directly here, atomic context */
1765 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
1767 acx_unlock(adev, flags);
1769 FN_EXIT0;
1772 /***********************************************************************
1773 ** acx111 feature config
1775 ** Obvious
1777 static int
1778 acx111_s_get_feature_config(acx_device_t * adev,
1779 u32 * feature_options, u32 * data_flow_options)
1781 struct acx111_ie_feature_config feat;
1783 FN_ENTER;
1785 if (!IS_ACX111(adev)) {
1786 return NOT_OK;
1789 memset(&feat, 0, sizeof(feat));
1791 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1792 FN_EXIT1(NOT_OK);
1793 return NOT_OK;
1795 log(L_DEBUG,
1796 "acx: got Feature option:0x%X, DataFlow option: 0x%X\n",
1797 feat.feature_options, feat.data_flow_options);
1799 if (feature_options)
1800 *feature_options = le32_to_cpu(feat.feature_options);
1801 if (data_flow_options)
1802 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1804 FN_EXIT0;
1805 return OK;
1809 static int
1810 acx111_s_set_feature_config(acx_device_t * adev,
1811 u32 feature_options, u32 data_flow_options,
1812 unsigned int mode
1813 /* 0 == remove, 1 == add, 2 == set */ )
1815 struct acx111_ie_feature_config feat;
1817 FN_ENTER;
1819 if (!IS_ACX111(adev)) {
1820 FN_EXIT1(NOT_OK);
1821 return NOT_OK;
1824 if ((mode < 0) || (mode > 2)) {
1825 FN_EXIT1(NOT_OK);
1826 return NOT_OK;
1829 if (mode != 2)
1830 /* need to modify old data */
1831 acx111_s_get_feature_config(adev, &feat.feature_options,
1832 &feat.data_flow_options);
1833 else {
1834 /* need to set a completely new value */
1835 feat.feature_options = 0;
1836 feat.data_flow_options = 0;
1839 if (mode == 0) { /* remove */
1840 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1841 CLEAR_BIT(feat.data_flow_options,
1842 cpu_to_le32(data_flow_options));
1843 } else { /* add or set */
1844 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1845 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1848 log(L_DEBUG,
1849 "acx: old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1850 "acx: new: feature 0x%08X dataflow 0x%08X\n",
1851 feature_options, data_flow_options, mode,
1852 le32_to_cpu(feat.feature_options),
1853 le32_to_cpu(feat.data_flow_options));
1855 if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1856 FN_EXIT1(NOT_OK);
1857 return NOT_OK;
1860 FN_EXIT0;
1861 return OK;
1864 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1866 return acx111_s_set_feature_config(adev, f, d, 0);
1868 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1870 return acx111_s_set_feature_config(adev, f, d, 1);
1872 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1874 return acx111_s_set_feature_config(adev, f, d, 2);
1878 /***********************************************************************
1879 ** acx100_s_init_memory_pools
1881 static int
1882 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1884 acx100_ie_memblocksize_t MemoryBlockSize;
1885 acx100_ie_memconfigoption_t MemoryConfigOption;
1886 int TotalMemoryBlocks;
1887 int RxBlockNum;
1888 int TotalRxBlockSize;
1889 int TxBlockNum;
1890 int TotalTxBlockSize;
1892 FN_ENTER;
1894 /* Let's see if we can follow this:
1895 first we select our memory block size (which I think is
1896 completely arbitrary) */
1897 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1899 /* Then we alert the card to our decision of block size */
1900 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
1901 goto bad;
1904 /* We figure out how many total blocks we can create, using
1905 the block size we chose, and the beginning and ending
1906 memory pointers, i.e.: end-start/size */
1907 TotalMemoryBlocks =
1908 (le32_to_cpu(mmt->PoolEnd) -
1909 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1911 log(L_DEBUG, "acx: TotalMemoryBlocks=%u (%u bytes)\n",
1912 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1914 /* MemoryConfigOption.DMA_config bitmask:
1915 access to ACX memory is to be done:
1916 0x00080000 using PCI conf space?!
1917 0x00040000 using IO instructions?
1918 0x00000000 using memory access instructions
1919 0x00020000 using local memory block linked list (else what?)
1920 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1922 if (IS_PCI(adev)) {
1923 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1924 /* Declare start of the Rx host pool */
1925 MemoryConfigOption.pRxHostDesc =
1926 cpu2acx(adev->rxhostdesc_startphy);
1927 log(L_DEBUG, "acx: pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
1928 acx2cpu(MemoryConfigOption.pRxHostDesc),
1929 (long)adev->rxhostdesc_startphy);
1930 } else {
1931 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1934 /* 50% of the allotment of memory blocks go to tx descriptors */
1935 TxBlockNum = TotalMemoryBlocks / 2;
1936 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1938 /* and 50% go to the rx descriptors */
1939 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1940 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1942 /* size of the tx and rx descriptor queues */
1943 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1944 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1945 log(L_DEBUG, "acx: TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u "
1946 "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum,
1947 TotalTxBlockSize, TotalRxBlockSize);
1950 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1951 MemoryConfigOption.rx_mem =
1952 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1954 /* align the rx descriptor queue to units of 0x20
1955 * and offset it by the tx descriptor queue */
1956 MemoryConfigOption.tx_mem =
1957 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
1958 0x1f) & ~0x1f);
1959 log(L_DEBUG, "acx: rx_mem %08X rx_mem %08X\n", MemoryConfigOption.tx_mem,
1960 MemoryConfigOption.rx_mem);
1962 /* alert the device to our decision */
1963 if (OK !=
1964 acx_s_configure(adev, &MemoryConfigOption,
1965 ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
1966 goto bad;
1969 /* and tell the device to kick it into gear */
1970 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
1971 goto bad;
1973 FN_EXIT1(OK);
1974 return OK;
1975 bad:
1976 FN_EXIT1(NOT_OK);
1977 return NOT_OK;
1981 /***********************************************************************
1982 ** acx100_s_create_dma_regions
1984 ** Note that this fn messes up heavily with hardware, but we cannot
1985 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1987 /* OLD CODE? - let's rewrite it! */
1988 static int acx100_s_create_dma_regions(acx_device_t * adev)
1990 acx100_ie_queueconfig_t queueconf;
1991 acx_ie_memmap_t memmap;
1992 int res = NOT_OK;
1993 u32 tx_queue_start, rx_queue_start;
1995 FN_ENTER;
1997 /* read out the acx100 physical start address for the queues */
1998 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1999 goto fail;
2002 tx_queue_start = le32_to_cpu(memmap.QueueStart);
2003 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
2005 log(L_DEBUG, "acx: initializing Queue Indicator\n");
2007 memset(&queueconf, 0, sizeof(queueconf));
2009 /* Not needed for PCI, so we can avoid setting them altogether */
2010 if (IS_USB(adev)) {
2011 queueconf.NumTxDesc = USB_TX_CNT;
2012 queueconf.NumRxDesc = USB_RX_CNT;
2015 /* calculate size of queues */
2016 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
2017 RX_CNT * sizeof(rxdesc_t) + 8);
2018 queueconf.NumTxQueues = 1; /* number of tx queues */
2019 /* sets the beginning of the tx descriptor queue */
2020 queueconf.TxQueueStart = memmap.QueueStart;
2021 /* done by memset: queueconf.TxQueuePri = 0; */
2022 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
2023 queueconf.QueueOptions = 1; /* auto reset descriptor */
2024 /* sets the end of the rx descriptor queue */
2025 queueconf.QueueEnd =
2026 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
2028 /* sets the beginning of the next queue */
2029 queueconf.HostQueueEnd =
2030 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
2031 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
2032 goto fail;
2035 if (IS_PCI(adev)) {
2036 /* sets the beginning of the rx descriptor queue, after the tx descrs */
2037 if (OK != acxpci_s_create_hostdesc_queues(adev))
2038 goto fail;
2039 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2042 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2043 goto fail;
2046 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
2047 0x1f) & ~0x1f);
2049 if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2050 goto fail;
2053 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
2054 goto fail;
2057 res = OK;
2058 goto end;
2060 fail:
2061 acx_s_mwait(1000); /* ? */
2062 if (IS_PCI(adev))
2063 acxpci_free_desc_queues(adev);
2064 end:
2065 FN_EXIT1(res);
2066 return res;
2070 /***********************************************************************
2071 ** acx111_s_create_dma_regions
2073 ** Note that this fn messes heavily with hardware, but we cannot
2074 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2076 #define ACX111_PERCENT(percent) ((percent)/5)
2078 static int acx111_s_create_dma_regions(acx_device_t * adev)
2080 struct acx111_ie_memoryconfig memconf;
2081 struct acx111_ie_queueconfig queueconf;
2082 u32 tx_queue_start, rx_queue_start;
2084 FN_ENTER;
2086 /* Calculate memory positions and queue sizes */
2088 /* Set up our host descriptor pool + data pool */
2089 if (IS_PCI(adev)) {
2090 if (OK != acxpci_s_create_hostdesc_queues(adev))
2091 goto fail;
2094 memset(&memconf, 0, sizeof(memconf));
2095 /* the number of STAs (STA contexts) to support
2096 ** NB: was set to 1 and everything seemed to work nevertheless... */
2097 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
2098 /* specify the memory block size. Default is 256 */
2099 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
2100 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
2101 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
2102 /* set the count of our queues
2103 ** NB: struct acx111_ie_memoryconfig shall be modified
2104 ** if we ever will switch to more than one rx and/or tx queue */
2105 memconf.count_rx_queues = 1;
2106 memconf.count_tx_queues = 1;
2107 /* 0 == Busmaster Indirect Memory Organization, which is what we want
2108 * (using linked host descs with their allocated mem).
2109 * 2 == Generic Bus Slave */
2110 /* done by memset: memconf.options = 0; */
2111 /* let's use 25% for fragmentations and 75% for frame transfers
2112 * (specified in units of 5%) */
2113 memconf.fragmentation = ACX111_PERCENT(75);
2114 /* Rx descriptor queue config */
2115 memconf.rx_queue1_count_descs = RX_CNT;
2116 memconf.rx_queue1_type = 7; /* must be set to 7 */
2117 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2118 if (IS_PCI(adev)) {
2119 memconf.rx_queue1_host_rx_start =
2120 cpu2acx(adev->rxhostdesc_startphy);
2122 /* Tx descriptor queue config */
2123 memconf.tx_queue1_count_descs = TX_CNT;
2124 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2126 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
2127 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2128 ** But it is actually correct wrt IE numbers.
2129 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
2130 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2131 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2132 if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
2133 goto fail;
2136 acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
2138 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2139 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2141 log(L_INIT, "acx: dump queue head (from card):\n"
2142 "acx: len: %u\n"
2143 "acx: tx_memory_block_address: %X\n"
2144 "acx: rx_memory_block_address: %X\n"
2145 "acx: tx1_queue address: %X\n"
2146 "acx: rx1_queue address: %X\n",
2147 le16_to_cpu(queueconf.len),
2148 le32_to_cpu(queueconf.tx_memory_block_address),
2149 le32_to_cpu(queueconf.rx_memory_block_address),
2150 tx_queue_start, rx_queue_start);
2152 if (IS_PCI(adev))
2153 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2155 FN_EXIT1(OK);
2156 return OK;
2157 fail:
2158 if (IS_PCI(adev))
2159 acxpci_free_desc_queues(adev);
2161 FN_EXIT1(NOT_OK);
2162 return NOT_OK;
2166 /***********************************************************************
2168 static void acx_s_initialize_rx_config(acx_device_t * adev)
2170 struct {
2171 u16 id;
2172 u16 len;
2173 u16 rx_cfg1;
2174 u16 rx_cfg2;
2175 } ACX_PACKED cfg;
2176 switch (adev->mode) {
2177 case ACX_MODE_MONITOR:
2178 adev->rx_config_1 = (u16) (0
2179 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2180 /* | RX_CFG1_FILTER_SSID */
2181 /* | RX_CFG1_FILTER_BCAST */
2182 /* | RX_CFG1_RCV_MC_ADDR1 */
2183 /* | RX_CFG1_RCV_MC_ADDR0 */
2184 /* | RX_CFG1_FILTER_ALL_MULTI */
2185 /* | RX_CFG1_FILTER_BSSID */
2186 /* | RX_CFG1_FILTER_MAC */
2187 | RX_CFG1_RCV_PROMISCUOUS
2188 | RX_CFG1_INCLUDE_FCS
2189 /* | RX_CFG1_INCLUDE_PHY_HDR */
2191 adev->rx_config_2 = (u16) (0
2192 | RX_CFG2_RCV_ASSOC_REQ
2193 | RX_CFG2_RCV_AUTH_FRAMES
2194 | RX_CFG2_RCV_BEACON_FRAMES
2195 | RX_CFG2_RCV_CONTENTION_FREE
2196 | RX_CFG2_RCV_CTRL_FRAMES
2197 | RX_CFG2_RCV_DATA_FRAMES
2198 | RX_CFG2_RCV_BROKEN_FRAMES
2199 | RX_CFG2_RCV_MGMT_FRAMES
2200 | RX_CFG2_RCV_PROBE_REQ
2201 | RX_CFG2_RCV_PROBE_RESP
2202 | RX_CFG2_RCV_ACK_FRAMES
2203 | RX_CFG2_RCV_OTHER);
2204 break;
2205 default:
2206 adev->rx_config_1 = (u16) (0
2207 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2208 /* | RX_CFG1_FILTER_SSID */
2209 /* | RX_CFG1_FILTER_BCAST */
2210 /* | RX_CFG1_RCV_MC_ADDR1 */
2211 /* | RX_CFG1_RCV_MC_ADDR0 */
2212 /* | RX_CFG1_FILTER_ALL_MULTI */
2213 /* | RX_CFG1_FILTER_BSSID */
2214 /* | RX_CFG1_FILTER_MAC */
2215 | RX_CFG1_RCV_PROMISCUOUS
2216 /* | RX_CFG1_INCLUDE_FCS */
2217 /* | RX_CFG1_INCLUDE_PHY_HDR */
2219 adev->rx_config_2 = (u16) (0
2220 | RX_CFG2_RCV_ASSOC_REQ
2221 | RX_CFG2_RCV_AUTH_FRAMES
2222 | RX_CFG2_RCV_BEACON_FRAMES
2223 | RX_CFG2_RCV_CONTENTION_FREE
2224 | RX_CFG2_RCV_CTRL_FRAMES
2225 | RX_CFG2_RCV_DATA_FRAMES
2226 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2227 | RX_CFG2_RCV_MGMT_FRAMES
2228 | RX_CFG2_RCV_PROBE_REQ
2229 | RX_CFG2_RCV_PROBE_RESP
2230 | RX_CFG2_RCV_ACK_FRAMES
2231 | RX_CFG2_RCV_OTHER);
2232 break;
2234 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2236 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2237 || (adev->firmware_numver >= 0x02000000))
2238 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2239 else
2240 adev->phy_header_len = 0;
2242 log(L_INIT, "acx: setting RXconfig to %04X:%04X\n",
2243 adev->rx_config_1, adev->rx_config_2);
2244 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2245 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2246 acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
2250 /***********************************************************************
2251 ** FIXME: this should be solved in a general way for all radio types
2252 ** by decoding the radio firmware module,
2253 ** since it probably has some standard structure describing how to
2254 ** set the power level of the radio module which it controls.
2255 ** Or maybe not, since the radio module probably has a function interface
2256 ** instead which then manages Tx level programming :-\
2258 ** Obvious
2260 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2262 struct acx111_ie_tx_level tx_level;
2264 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2265 * 1 (30mW) [15dBm]
2266 * 2 (10mW) [10dBm]
2267 * For now, just assume all other acx111 cards have the same.
2268 * FIXME: Ideally we would query it here, but we first need a
2269 * standard way to query individual configoptions easily.
2270 * Well, now we have proper cfgopt txpower variables, but this still
2271 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2272 if (level_dbm <= 12) {
2273 tx_level.level = 2; /* 10 dBm */
2274 adev->tx_level_dbm = 10;
2275 } else {
2276 tx_level.level = 1; /* 15 dBm */
2277 adev->tx_level_dbm = 15;
2279 if (level_dbm != adev->tx_level_dbm)
2280 log(L_INIT, "acx: only predefined transmission "
2281 "power levels are supported at this time: "
2282 "adjusted %d dBm to %d dBm\n", level_dbm,
2283 adev->tx_level_dbm);
2285 return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
2288 static int acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
2290 if (IS_ACX111(adev)) {
2291 return acx111_s_set_tx_level(adev, level_dbm);
2293 if (IS_PCI(adev)) {
2294 return acx100pci_s_set_tx_level(adev, level_dbm);
2297 return OK;
2301 /***********************************************************************
2302 ** acx_s_set_defaults
2304 void acx_s_set_defaults(acx_device_t * adev)
2306 struct ieee80211_conf *conf = &adev->ieee->conf;
2307 unsigned long flags;
2309 FN_ENTER;
2311 acx_lock(adev, flags);
2312 /* do it before getting settings, prevent bogus channel 0 warning */
2313 adev->channel = 1;
2315 /* query some settings from the card.
2316 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2317 * query is REQUIRED, otherwise the card won't work correctly! */
2318 adev->get_mask =
2319 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2320 GETSET_REG_DOMAIN;
2321 /* Only ACX100 supports ED and CCA */
2322 if (IS_ACX100(adev))
2323 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2325 acx_unlock(adev, flags);
2327 acx_s_update_card_settings(adev);
2329 acx_lock(adev, flags);
2331 /* set our global interrupt mask */
2332 if (IS_PCI(adev))
2333 acxpci_set_interrupt_mask(adev);
2335 adev->led_power = 1; /* LED is active on startup */
2336 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2337 adev->brange_time_last_state_change = jiffies;
2339 /* copy the MAC address we just got from the card
2340 * into our MAC address used during current 802.11 session */
2341 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
2342 MAC_BCAST(adev->ap);
2344 adev->essid_len =
2345 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2346 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2347 adev->essid_active = 1;
2349 /* we have a nick field to waste, so why not abuse it
2350 * to announce the driver version? ;-) */
2351 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2353 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2354 /* first regulatory domain entry in EEPROM == default reg. domain */
2355 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2358 /* 0xffff would be better, but then we won't get a "scan complete"
2359 * interrupt, so our current infrastructure will fail: */
2360 adev->scan_count = 1;
2361 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2362 adev->scan_duration = 100;
2363 adev->scan_probe_delay = 200;
2364 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2365 adev->scan_rate = ACX_SCAN_RATE_1;
2368 adev->mode = ACX_MODE_2_STA;
2369 adev->listen_interval = 100;
2370 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2371 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2373 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2375 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2376 adev->frag_threshold = 2346;
2378 /* use standard default values for retry limits */
2379 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2380 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2382 adev->preamble_mode = 2; /* auto */
2383 adev->fallback_threshold = 3;
2384 adev->stepup_threshold = 10;
2385 adev->rate_bcast = RATE111_1;
2386 adev->rate_bcast100 = RATE100_1;
2387 adev->rate_basic = RATE111_1 | RATE111_2;
2388 adev->rate_auto = 1;
2389 if (IS_ACX111(adev)) {
2390 adev->rate_oper = RATE111_ALL;
2391 } else {
2392 adev->rate_oper = RATE111_ACX100_COMPAT;
2395 /* Supported Rates element - the rates here are given in units of
2396 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2397 acx_l_update_ratevector(adev);
2399 /* set some more defaults */
2400 if (IS_ACX111(adev)) {
2401 /* 30mW (15dBm) is default, at least in my acx111 card: */
2402 adev->tx_level_dbm = 15;
2403 conf->power_level = adev->tx_level_dbm;
2404 acx_unlock(adev, flags);
2405 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2406 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2407 acx_lock(adev, flags);
2408 } else {
2409 /* don't use max. level, since it might be dangerous
2410 * (e.g. WRT54G people experience
2411 * excessive Tx power damage!) */
2412 adev->tx_level_dbm = 18;
2413 conf->power_level = adev->tx_level_dbm;
2414 acx_unlock(adev, flags);
2415 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2416 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2417 acx_lock(adev, flags);
2420 /* adev->tx_level_auto = 1; */
2421 if (IS_ACX111(adev)) {
2422 /* start with sensitivity level 1 out of 3: */
2423 adev->sensitivity = 1;
2426 /* #define ENABLE_POWER_SAVE */
2427 #ifdef ENABLE_POWER_SAVE
2428 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2429 adev->ps_listen_interval = 1;
2430 adev->ps_options =
2431 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2432 adev->ps_hangover_period = 30;
2433 adev->ps_enhanced_transition_time = 0;
2434 #else
2435 adev->ps_wakeup_cfg = 0;
2436 adev->ps_listen_interval = 0;
2437 adev->ps_options = 0;
2438 adev->ps_hangover_period = 0;
2439 adev->ps_enhanced_transition_time = 0;
2440 #endif
2442 /* These settings will be set in fw on ifup */
2443 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2444 /* configure card to do rate fallback when in auto rate mode */
2445 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2446 /* better re-init the antenna value we got above */
2447 | GETSET_ANTENNA
2448 #if POWER_SAVE_80211
2449 | GETSET_POWER_80211
2450 #endif
2453 acx_unlock(adev, flags);
2454 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2456 acx_s_initialize_rx_config(adev);
2458 FN_EXIT0;
2462 /***********************************************************************
2463 ** acx_l_process_rxbuf
2465 ** NB: used by USB code also
2467 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2469 struct ieee80211_hdr *hdr;
2470 u16 fc, buf_len;
2472 FN_ENTER;
2474 hdr = acx_get_wlan_hdr(adev, rxbuf);
2475 fc = le16_to_cpu(hdr->frame_control);
2476 /* length of frame from control field to first byte of FCS */
2477 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2479 if (unlikely(acx_debug & L_DATA)) {
2480 printk("acx: rx: 802.11 buf[%u]: \n", buf_len);
2481 acx_dump_bytes(hdr, buf_len);
2485 acx_l_rx(adev, rxbuf);
2486 /* Now check Rx quality level, AFTER processing packet.
2487 * I tried to figure out how to map these levels to dBm
2488 * values, but for the life of me I really didn't
2489 * manage to get it. Either these values are not meant to
2490 * be expressed in dBm, or it's some pretty complicated
2491 * calculation. */
2493 /* TODO: only the RSSI seems to be reported */
2494 adev->rx_status.ssi = acx_signal_to_winlevel(rxbuf->phy_level);
2496 FN_EXIT0;
2500 /***********************************************************************
2501 ** acx_l_handle_txrate_auto
2503 ** Theory of operation:
2504 ** client->rate_cap is a bitmask of rates client is capable of.
2505 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2506 ** It is set as a result of iwconfig rate N [auto]
2507 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2508 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2509 ** auto (0x00ff == 18Mbit or any lower value),
2510 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2512 ** client->rate_cur is a value for rate111 field in tx descriptor.
2513 ** It is always set to txrate_cfg sans zero or more most significant
2514 ** bits. This routine handles selection of new rate_cur value depending on
2515 ** outcome of last tx event.
2517 ** client->rate_100 is a precalculated rate value for acx100
2518 ** (we can do without it, but will need to calculate it on each tx).
2520 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2521 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2522 ** In theory you can implement it, but so far it is considered not worth doing.
2524 ** 22Mbit, of course, is PBCC always. */
2526 /* maps acx100 tx descr rate field to acx111 one */
2528 static u16 rate100to111(u8 r)
2530 switch (r) {
2531 case RATE100_1:
2532 return RATE111_1;
2533 case RATE100_2:
2534 return RATE111_2;
2535 case RATE100_5:
2536 case (RATE100_5 | RATE100_PBCC511):
2537 return RATE111_5;
2538 case RATE100_11:
2539 case (RATE100_11 | RATE100_PBCC511):
2540 return RATE111_11;
2541 case RATE100_22:
2542 return RATE111_22;
2543 default:
2544 printk("acx: unexpected acx100 txrate: %u! "
2545 "Please report\n", r);
2546 return RATE111_1;
2553 acx_i_start_xmit(struct ieee80211_hw *hw,
2554 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2556 acx_device_t *adev = ieee2adev(hw);
2557 tx_t *tx;
2558 void *txbuf;
2559 unsigned long flags;
2561 int txresult = NOT_OK;
2563 FN_ENTER;
2565 if (unlikely(!skb)) {
2566 /* indicate success */
2567 txresult = OK;
2568 goto out;
2571 if (unlikely(!adev)) {
2572 goto out;
2575 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2576 goto out;
2578 if (unlikely(!adev->initialized)) {
2579 goto out;
2582 acx_lock(adev, flags);
2584 tx = acx_l_alloc_tx(adev);
2586 if (unlikely(!tx)) {
2587 printk_ratelimited("acx: %s: start_xmit: txdesc ring is full, "
2588 "dropping tx\n", wiphy_name(adev->ieee->wiphy));
2589 txresult = NOT_OK;
2590 goto out_unlock;
2593 txbuf = acx_l_get_txbuf(adev, tx);
2595 if (unlikely(!txbuf)) {
2596 /* Card was removed */
2597 txresult = NOT_OK;
2598 acx_l_dealloc_tx(adev, tx);
2599 goto out_unlock;
2601 memcpy(txbuf, skb->data, skb->len);
2603 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2605 txresult = OK;
2606 adev->stats.tx_packets++;
2607 adev->stats.tx_bytes += skb->len;
2609 out_unlock:
2610 acx_unlock(adev, flags);
2612 out:
2613 FN_EXIT1(txresult);
2614 return txresult;
2616 /***********************************************************************
2617 ** acx_l_update_ratevector
2619 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2621 const u8 acx_bitpos2ratebyte[] = {
2622 DOT11RATEBYTE_1,
2623 DOT11RATEBYTE_2,
2624 DOT11RATEBYTE_5_5,
2625 DOT11RATEBYTE_6_G,
2626 DOT11RATEBYTE_9_G,
2627 DOT11RATEBYTE_11,
2628 DOT11RATEBYTE_12_G,
2629 DOT11RATEBYTE_18_G,
2630 DOT11RATEBYTE_22,
2631 DOT11RATEBYTE_24_G,
2632 DOT11RATEBYTE_36_G,
2633 DOT11RATEBYTE_48_G,
2634 DOT11RATEBYTE_54_G,
2637 void acx_l_update_ratevector(acx_device_t * adev)
2639 u16 bcfg = adev->rate_basic;
2640 u16 ocfg = adev->rate_oper;
2641 u8 *supp = adev->rate_supported;
2642 const u8 *dot11 = acx_bitpos2ratebyte;
2644 FN_ENTER;
2646 while (ocfg) {
2647 if (ocfg & 1) {
2648 *supp = *dot11;
2649 if (bcfg & 1) {
2650 *supp |= 0x80;
2652 supp++;
2654 dot11++;
2655 ocfg >>= 1;
2656 bcfg >>= 1;
2658 adev->rate_supported_len = supp - adev->rate_supported;
2659 if (acx_debug & L_ASSOC) {
2660 printk("acx: new ratevector: ");
2661 acx_dump_bytes(adev->rate_supported, adev->rate_supported_len);
2663 FN_EXIT0;
2666 /***********************************************************************
2667 ** acx_i_timer
2669 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2671 ** Obvious
2673 void acx_i_timer(unsigned long address)
2675 unsigned long flags;
2676 acx_device_t *adev = (acx_device_t *) address;
2678 FN_ENTER;
2680 acx_lock(adev, flags);
2682 FIXME();
2683 /* We need calibration and stats gather tasks to perform here */
2685 acx_unlock(adev, flags);
2687 FN_EXIT0;
2691 /***********************************************************************
2692 ** acx_set_timer
2694 ** Sets the 802.11 state management timer's timeout.
2696 ** Linux derived
2698 void acx_set_timer(acx_device_t * adev, int timeout_us)
2700 FN_ENTER;
2702 log(L_DEBUG | L_IRQ, "acx: %s(%u ms)\n", __func__, timeout_us / 1000);
2703 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2704 printk("acx: attempt to set the timer "
2705 "when the card interface is not up!\n");
2706 goto end;
2709 /* first check if the timer was already initialized, THEN modify it */
2710 if (adev->mgmt_timer.function) {
2711 mod_timer(&adev->mgmt_timer,
2712 jiffies + (timeout_us * HZ / 1000000));
2714 end:
2715 FN_EXIT0;
2718 /** acx_plcp_get_bitrate_cck
2720 ** Obvious
2722 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2724 switch (plcp) {
2725 case 0x0A:
2726 return ACX_CCK_RATE_1MB;
2727 case 0x14:
2728 return ACX_CCK_RATE_2MB;
2729 case 0x37:
2730 return ACX_CCK_RATE_5MB;
2731 case 0x6E:
2732 return ACX_CCK_RATE_11MB;
2734 return 0;
2737 /* Extract the bitrate out of an OFDM PLCP header. */
2738 /** Obvious **/
2739 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2741 switch (plcp & 0xF) {
2742 case 0xB:
2743 return ACX_OFDM_RATE_6MB;
2744 case 0xF:
2745 return ACX_OFDM_RATE_9MB;
2746 case 0xA:
2747 return ACX_OFDM_RATE_12MB;
2748 case 0xE:
2749 return ACX_OFDM_RATE_18MB;
2750 case 0x9:
2751 return ACX_OFDM_RATE_24MB;
2752 case 0xD:
2753 return ACX_OFDM_RATE_36MB;
2754 case 0x8:
2755 return ACX_OFDM_RATE_48MB;
2756 case 0xC:
2757 return ACX_OFDM_RATE_54MB;
2759 return 0;
2763 /***********************************************************************
2764 ** acx_l_rx
2766 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2767 ** buffer and feeds it to the network stack via netif_rx().
2769 ** Look to bcm43xx or p54
2771 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2774 struct ieee80211_rx_status* status = &adev->rx_status;
2775 struct ieee80211_hdr *w_hdr;
2776 struct sk_buff *skb;
2777 int buflen;
2778 FN_ENTER;
2780 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2781 printk("acx: asked to receive a packet but the interface is down??\n");
2782 goto out;
2785 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2786 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2788 * Allocate our skb
2790 skb = dev_alloc_skb(buflen + 2);
2792 if (!skb) {
2793 printk("acx: skb allocation FAILED\n");
2794 goto out;
2797 skb_reserve(skb, 2);
2798 skb_put(skb, buflen);
2799 memcpy(skb->data, w_hdr, buflen);
2801 // memset(&status, 0, sizeof(status));
2803 status->mactime = rxbuf->time;
2804 status->ssi = acx_signal_to_winlevel(rxbuf->phy_level);
2805 /* TODO: they do not seem to be reported, at least on the acx111
2806 * (and TNETW1450?), therefore commenting them out
2807 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2808 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr); */
2809 status->flag = 0;
2810 status->rate = rxbuf->phy_plcp_signal;
2811 status->antenna = 1;
2812 if (rxbuf->phy_stat_baseband & (1 << 3)) { /* Uses OFDM */
2813 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2814 } else {
2815 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2819 * FIXME: should it really be done here??
2821 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2822 adev->stats.rx_packets++;
2823 adev->stats.rx_bytes += skb->len;
2824 out:
2825 FN_EXIT0;
2830 /***********************************************************************
2831 ** acx_s_read_fw
2833 ** Loads a firmware image
2835 ** Returns:
2836 ** 0 unable to load file
2837 ** pointer to firmware success
2839 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2840 u32 * size)
2842 firmware_image_t *res;
2843 const struct firmware *fw_entry;
2845 res = NULL;
2846 log(L_INIT, "acx: requesting firmware image '%s'\n", file);
2847 if (!request_firmware(&fw_entry, file, dev)) {
2848 *size = 8;
2849 if (fw_entry->size >= 8)
2850 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2851 if (fw_entry->size != *size) {
2852 printk("acx: firmware size does not match "
2853 "firmware header: %d != %d, "
2854 "aborting fw upload\n",
2855 (int)fw_entry->size, (int)*size);
2856 goto release_ret;
2858 res = vmalloc(*size);
2859 if (!res) {
2860 printk("acx: no memory for firmware "
2861 "(%u bytes)\n", *size);
2862 goto release_ret;
2864 memcpy(res, fw_entry->data, fw_entry->size);
2865 release_ret:
2866 release_firmware(fw_entry);
2867 return res;
2869 printk("acx: firmware image '%s' was not provided. "
2870 "Check your hotplug scripts\n", file);
2872 /* checksum will be verified in write_fw, so don't bother here */
2873 return res;
2877 /***********************************************************************
2878 ** acx_s_set_wepkey
2880 static void acx100_s_set_wepkey(acx_device_t * adev)
2882 ie_dot11WEPDefaultKey_t dk;
2883 int i;
2885 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2886 if (adev->wep_keys[i].size != 0) {
2887 log(L_INIT, "acx: setting WEP key: %d with "
2888 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2889 dk.action = 1;
2890 dk.keySize = adev->wep_keys[i].size;
2891 dk.defaultKeyNum = i;
2892 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2893 acx_s_configure(adev, &dk,
2894 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
2899 static void acx111_s_set_wepkey(acx_device_t * adev)
2901 acx111WEPDefaultKey_t dk;
2902 int i;
2904 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2905 if (adev->wep_keys[i].size != 0) {
2906 log(L_INIT, "acx: setting WEP key: %d with "
2907 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2908 memset(&dk, 0, sizeof(dk));
2909 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2910 dk.keySize = adev->wep_keys[i].size;
2912 /* are these two lines necessary? */
2913 dk.type = 0; /* default WEP key */
2914 dk.index = 0; /* ignored when setting default key */
2916 dk.defaultKeyNum = i;
2917 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2918 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2919 sizeof(dk));
2923 /* Obvious */
2924 static void acx_s_set_wepkey(acx_device_t * adev)
2926 if (IS_ACX111(adev))
2927 acx111_s_set_wepkey(adev);
2928 else
2929 acx100_s_set_wepkey(adev);
2933 /***********************************************************************
2934 ** acx100_s_init_wep
2936 ** FIXME: this should probably be moved into the new card settings
2937 ** management, but since we're also modifying the memory map layout here
2938 ** due to the WEP key space we want, we should take care...
2940 static int acx100_s_init_wep(acx_device_t * adev)
2942 acx100_ie_wep_options_t options;
2943 ie_dot11WEPDefaultKeyID_t dk;
2944 acx_ie_memmap_t pt;
2945 int res = NOT_OK;
2947 FN_ENTER;
2949 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2950 goto fail;
2953 log(L_DEBUG, "acx: CodeEnd:%X\n", pt.CodeEnd);
2955 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2956 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2958 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2959 goto fail;
2962 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2963 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2964 options.WEPOption = 0x00;
2966 log(L_ASSOC, "acx: writing WEP options\n");
2967 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
2969 acx100_s_set_wepkey(adev);
2971 if (adev->wep_keys[adev->wep_current_index].size != 0) {
2972 log(L_ASSOC, "acx: setting active default WEP key number: %d\n",
2973 adev->wep_current_index);
2974 dk.KeyID = adev->wep_current_index;
2975 acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
2977 /* FIXME!!! wep_key_struct is filled nowhere! But adev
2978 * is initialized to 0, and we don't REALLY need those keys either */
2979 /* for (i = 0; i < 10; i++) {
2980 if (adev->wep_key_struct[i].len != 0) {
2981 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
2982 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
2983 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
2984 wep_mgmt.Action = cpu_to_le16(1);
2985 log(L_ASSOC, "acx: writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
2986 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
2987 adev->wep_key_struct[i].index = i;
2993 /* now retrieve the updated WEPCacheEnd pointer... */
2994 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2995 printk("acx: %s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
2996 wiphy_name(adev->ieee->wiphy));
2997 goto fail;
2999 /* ...and tell it to start allocating templates at that location */
3000 /* (no endianness conversion needed) */
3001 pt.PacketTemplateStart = pt.WEPCacheEnd;
3003 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
3004 printk("acx: %s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
3005 wiphy_name(adev->ieee->wiphy));
3006 goto fail;
3008 res = OK;
3010 fail:
3011 FN_EXIT1(res);
3012 return res;
3016 static int
3017 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
3018 unsigned int cmd)
3020 int res;
3021 union {
3022 acx_template_nullframe_t null;
3023 acx_template_beacon_t b;
3024 acx_template_tim_t tim;
3025 acx_template_probereq_t preq;
3026 acx_template_proberesp_t presp;
3027 } templ;
3029 memset(&templ, 0, len);
3030 templ.null.size = cpu_to_le16(len - 2);
3031 res = acx_s_issue_cmd(adev, cmd, &templ, len);
3032 return res;
3035 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
3037 return acx_s_init_max_template_generic(adev,
3038 sizeof(acx_template_nullframe_t),
3039 ACX1xx_CMD_CONFIG_NULL_DATA);
3042 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
3044 return acx_s_init_max_template_generic(adev,
3045 sizeof(acx_template_beacon_t),
3046 ACX1xx_CMD_CONFIG_BEACON);
3049 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
3051 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
3052 ACX1xx_CMD_CONFIG_TIM);
3055 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
3057 return acx_s_init_max_template_generic(adev,
3058 sizeof(acx_template_proberesp_t),
3059 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
3062 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
3064 return acx_s_init_max_template_generic(adev,
3065 sizeof(acx_template_probereq_t),
3066 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
3069 /***********************************************************************
3070 ** acx_s_set_tim_template
3072 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
3073 ** by calling this function
3074 ** (it can be done by irq handler on each DTIM irq or by timer...)
3076 [802.11 7.3.2.6] TIM information element:
3077 - 1 EID
3078 - 1 Length
3079 1 1 DTIM Count
3080 indicates how many beacons (including this) appear before next DTIM
3081 (0=this one is a DTIM)
3082 2 1 DTIM Period
3083 number of beacons between successive DTIMs
3084 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
3085 3 1 Bitmap Control
3086 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
3087 set to 1 in TIM elements with a value of 0 in the DTIM Count field
3088 when one or more broadcast or multicast frames are buffered at the AP.
3089 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
3090 4 n Partial Virtual Bitmap
3091 Visible part of traffic-indication bitmap.
3092 Full bitmap consists of 2008 bits (251 octets) such that bit number N
3093 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
3094 in octet number N/8 where the low-order bit of each octet is bit0,
3095 and the high order bit is bit7.
3096 Each set bit in virtual bitmap corresponds to traffic buffered by AP
3097 for a specific station (with corresponding AID?).
3098 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
3099 Bitmap Offset is a number of skipped zero octets (see above).
3100 'Missing' octets at the tail are also assumed to be zero.
3101 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
3102 This means that traffic-indication bitmap is:
3103 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
3104 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
3106 static int acx_s_set_tim_template(acx_device_t * adev)
3108 /* For now, configure smallish test bitmap, all zero ("no pending data") */
3109 enum { bitmap_size = 5 };
3111 acx_template_tim_t t;
3112 int result;
3114 FN_ENTER;
3116 memset(&t, 0, sizeof(t));
3117 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3118 t.tim_eid = WLAN_EID_TIM;
3119 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3120 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3121 FN_EXIT1(result);
3122 return result;
3128 #if POWER_SAVE_80211
3129 /***********************************************************************
3130 ** acx_s_set_null_data_template
3132 static int acx_s_set_null_data_template(acx_device_t * adev)
3134 struct acx_template_nullframe b;
3135 int result;
3137 FN_ENTER;
3139 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3141 b.size = cpu_to_le16(sizeof(b) - 2);
3142 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3143 b.hdr.dur = 0;
3144 MAC_BCAST(b.hdr.a1);
3145 MAC_COPY(b.hdr.a2, adev->dev_addr);
3146 MAC_COPY(b.hdr.a3, adev->bssid);
3147 b.hdr.seq = 0;
3149 result =
3150 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3152 FN_EXIT1(result);
3153 return result;
3155 #endif
3162 /***********************************************************************
3163 ** acx_s_init_packet_templates()
3165 ** NOTE: order is very important here, to have a correct memory layout!
3166 ** init templates: max Probe Request (station mode), max NULL data,
3167 ** max Beacon, max TIM, max Probe Response.
3169 static int acx_s_init_packet_templates(acx_device_t * adev)
3171 acx_ie_memmap_t mm; /* ACX100 only */
3172 int result = NOT_OK;
3174 FN_ENTER;
3176 log(L_DEBUG | L_INIT, "acx: initializing max packet templates\n");
3178 if (OK != acx_s_init_max_probe_request_template(adev))
3179 goto failed;
3181 if (OK != acx_s_init_max_null_data_template(adev))
3182 goto failed;
3184 if (OK != acx_s_init_max_beacon_template(adev))
3185 goto failed;
3187 if (OK != acx_s_init_max_tim_template(adev))
3188 goto failed;
3190 if (OK != acx_s_init_max_probe_response_template(adev))
3191 goto failed;
3193 if (IS_ACX111(adev)) {
3194 /* ACX111 doesn't need the memory map magic below,
3195 * and the other templates will be set later (acx_start) */
3196 result = OK;
3197 goto success;
3200 /* ACX100 will have its TIM template set,
3201 * and we also need to update the memory map */
3203 if (OK != acx_s_set_tim_template(adev))
3204 goto failed_acx100;
3206 log(L_DEBUG, "acx: sizeof(memmap) = %d bytes\n", (int)sizeof(mm));
3208 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3209 goto failed_acx100;
3211 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3212 if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3213 goto failed_acx100;
3215 result = OK;
3216 goto success;
3218 failed_acx100:
3219 log(L_DEBUG | L_INIT,
3220 /* "cb=0x%X\n" */
3221 "acx: ACXMemoryMap:\n"
3222 "acx: .CodeStart=0x%X\n"
3223 "acx: .CodeEnd=0x%X\n"
3224 "acx: .WEPCacheStart=0x%X\n"
3225 "acx: .WEPCacheEnd=0x%X\n"
3226 "acx: .PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3227 /* len, */
3228 le32_to_cpu(mm.CodeStart),
3229 le32_to_cpu(mm.CodeEnd),
3230 le32_to_cpu(mm.WEPCacheStart),
3231 le32_to_cpu(mm.WEPCacheEnd),
3232 le32_to_cpu(mm.PacketTemplateStart),
3233 le32_to_cpu(mm.PacketTemplateEnd));
3235 failed:
3236 printk("acx: %s: %s() FAILED\n", wiphy_name(adev->ieee->wiphy), __func__);
3238 success:
3239 FN_EXIT1(result);
3240 return result;
3245 /***********************************************************************
3246 ** acx_s_init_mac
3248 int acx_s_init_mac(acx_device_t * adev)
3250 int result = NOT_OK;
3252 FN_ENTER;
3254 if (IS_ACX111(adev)) {
3255 adev->ie_len = acx111_ie_len;
3256 adev->ie_len_dot11 = acx111_ie_len_dot11;
3257 } else {
3258 adev->ie_len = acx100_ie_len;
3259 adev->ie_len_dot11 = acx100_ie_len_dot11;
3262 if (IS_PCI(adev)) {
3263 adev->memblocksize = 256; /* 256 is default */
3264 /* try to load radio for both ACX100 and ACX111, since both
3265 * chips have at least some firmware versions making use of an
3266 * external radio module */
3267 acxpci_s_upload_radio(adev);
3268 } else {
3269 adev->memblocksize = 128;
3272 if (IS_ACX111(adev)) {
3273 /* for ACX111, the order is different from ACX100
3274 1. init packet templates
3275 2. create station context and create dma regions
3276 3. init wep default keys
3278 if (OK != acx_s_init_packet_templates(adev))
3279 goto fail;
3280 if (OK != acx111_s_create_dma_regions(adev)) {
3281 printk("acx: %s: acx111_create_dma_regions FAILED\n",
3282 wiphy_name(adev->ieee->wiphy));
3283 goto fail;
3285 } else {
3286 if (OK != acx100_s_init_wep(adev))
3287 goto fail;
3288 if (OK != acx_s_init_packet_templates(adev))
3289 goto fail;
3290 if (OK != acx100_s_create_dma_regions(adev)) {
3291 printk("acx: %s: acx100_create_dma_regions FAILED\n",
3292 wiphy_name(adev->ieee->wiphy));
3293 goto fail;
3297 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3298 result = OK;
3300 fail:
3301 if (result)
3302 printk("acx: init_mac() FAILED\n");
3303 FN_EXIT1(result);
3304 return result;
3309 #if POWER_SAVE_80211
3310 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3312 /* merge both structs in a union to be able to have common code */
3313 union {
3314 acx111_ie_powersave_t acx111;
3315 acx100_ie_powersave_t acx100;
3316 } pm;
3318 /* change 802.11 power save mode settings */
3319 log(L_INIT, "acx: updating 802.11 power save mode settings: "
3320 "wakeup_cfg 0x%02X, listen interval %u, "
3321 "options 0x%02X, hangover period %u, "
3322 "enhanced_ps_transition_time %u\n",
3323 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3324 adev->ps_options, adev->ps_hangover_period,
3325 adev->ps_enhanced_transition_time);
3326 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3327 log(L_INIT, "acx: Previous PS mode settings: wakeup_cfg 0x%02X, "
3328 "listen interval %u, options 0x%02X, "
3329 "hangover period %u, "
3330 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3331 pm.acx111.wakeup_cfg,
3332 pm.acx111.listen_interval,
3333 pm.acx111.options,
3334 pm.acx111.hangover_period,
3335 IS_ACX111(adev) ?
3336 pm.acx111.enhanced_ps_transition_time
3337 : pm.acx100.enhanced_ps_transition_time,
3338 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3339 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3340 pm.acx111.listen_interval = adev->ps_listen_interval;
3341 pm.acx111.options = adev->ps_options;
3342 pm.acx111.hangover_period = adev->ps_hangover_period;
3343 if (IS_ACX111(adev)) {
3344 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3345 pm.acx111.enhanced_ps_transition_time =
3346 cpu_to_le32(adev->ps_enhanced_transition_time);
3347 } else {
3348 pm.acx100.enhanced_ps_transition_time =
3349 cpu_to_le16(adev->ps_enhanced_transition_time);
3351 acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT);
3352 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3353 log(L_INIT, "acx: wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3354 acx_s_mwait(40);
3355 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3356 log(L_INIT, "acx: wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3357 log(L_INIT, "acx: power save mode change %s\n",
3358 (pm.acx111.
3359 wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful");
3360 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3361 * that power save mode change was successful. */
3362 /* FIXME: we shouldn't trigger a scan immediately after
3363 * fiddling with power save mode (since the firmware is sending
3364 * a NULL frame then). */
3366 #endif
3369 /***********************************************************************
3370 ** acx_s_update_card_settings
3372 ** Applies accumulated changes in various adev->xxxx members
3373 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3374 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3376 void acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
3378 unsigned mask;
3380 unsigned int i;
3382 for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
3383 if (acx_reg_domain_ids[i] == adev->reg_dom_id)
3384 break;
3386 if (sizeof(acx_reg_domain_ids) == i) {
3387 log(L_INIT, "acx: Invalid or unsupported regulatory domain"
3388 " 0x%02X specified, falling back to FCC (USA)!"
3389 " Please report if this sounds fishy!\n",
3390 adev->reg_dom_id);
3391 i = 0;
3392 adev->reg_dom_id = acx_reg_domain_ids[i];
3394 /* since there was a mismatch, we need to force updating */
3395 do_set = 1;
3398 if (do_set) {
3399 acx_ie_generic_t dom;
3400 dom.m.bytes[0] = adev->reg_dom_id;
3401 acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3404 adev->reg_dom_chanmask = reg_domain_channel_masks[i];
3406 mask = (1 << (adev->channel - 1));
3407 if (!(adev->reg_dom_chanmask & mask)) {
3408 /* hmm, need to adjust our channel to reside within domain */
3409 mask = 1;
3410 for (i = 1; i <= 14; i++) {
3411 if (adev->reg_dom_chanmask & mask) {
3412 printk("acx: %s: adjusting the selected channel from %d "
3413 "to %d due to the new regulatory domain\n",
3414 wiphy_name(adev->ieee->wiphy), adev->channel, i);
3415 adev->channel = i;
3416 break;
3418 mask <<= 1;
3423 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3425 u32 feature1, feature2;
3427 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3428 printk("acx: %s: invalid sensitivity setting (1..3), "
3429 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3430 adev->sensitivity = 1;
3432 acx111_s_get_feature_config(adev, &feature1, &feature2);
3433 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3434 if (adev->sensitivity > 1)
3435 SET_BIT(feature1, FEATURE1_LOW_RX);
3436 if (adev->sensitivity > 2)
3437 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3438 acx111_s_feature_set(adev, feature1, feature2);
3442 void acx_s_update_card_settings(acx_device_t *adev)
3444 unsigned long flags;
3445 unsigned int start_scan = 0;
3446 int i;
3448 FN_ENTER;
3450 log(L_INIT, "acx: get_mask 0x%08X, set_mask 0x%08X\n",
3451 adev->get_mask, adev->set_mask);
3453 /* Track dependencies betweed various settings */
3455 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3456 log(L_INIT, "acx: an important setting has been changed. "
3457 "The packet templates must also be updated\n");
3458 SET_BIT(adev->set_mask, SET_TEMPLATES);
3460 if (adev->set_mask & GETSET_CHANNEL) {
3461 /* This will actually tune RX/TX to the channel */
3462 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3463 switch (adev->mode) {
3464 case ACX_MODE_0_ADHOC:
3465 case ACX_MODE_3_AP:
3466 /* Beacons contain channel# - update them */
3467 SET_BIT(adev->set_mask, SET_TEMPLATES);
3470 switch (adev->mode) {
3471 case ACX_MODE_0_ADHOC:
3472 case ACX_MODE_2_STA:
3473 start_scan = 1;
3477 /* Apply settings */
3480 if (adev->get_mask & GETSET_STATION_ID) {
3481 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3482 const u8 *paddr;
3484 acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3485 paddr = &stationID[4];
3486 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3487 for (i = 0; i < ETH_ALEN; i++) {
3488 /* we copy the MAC address (reversed in
3489 * the card) to the netdevice's MAC
3490 * address, and on ifup it will be
3491 * copied into iwadev->dev_addr */
3492 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3494 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3495 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3498 if (adev->get_mask & GETSET_SENSITIVITY) {
3499 if ((RADIO_RFMD_11 == adev->radio_type)
3500 || (RADIO_MAXIM_0D == adev->radio_type)
3501 || (RADIO_RALINK_15 == adev->radio_type)) {
3502 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3503 } else {
3504 log(L_INIT, "acx: don't know how to get sensitivity "
3505 "for radio type 0x%02X\n", adev->radio_type);
3506 adev->sensitivity = 0;
3508 log(L_INIT, "acx: got sensitivity value %u\n", adev->sensitivity);
3510 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3513 if (adev->get_mask & GETSET_ANTENNA) {
3514 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3516 memset(antenna, 0, sizeof(antenna));
3517 acx_s_interrogate(adev, antenna,
3518 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3519 adev->antenna = antenna[4];
3520 log(L_INIT, "acx: got antenna value 0x%02X\n", adev->antenna);
3521 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3524 if (adev->get_mask & GETSET_ED_THRESH) {
3525 if (IS_ACX100(adev)) {
3526 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3528 memset(ed_threshold, 0, sizeof(ed_threshold));
3529 acx_s_interrogate(adev, ed_threshold,
3530 ACX100_IE_DOT11_ED_THRESHOLD);
3531 adev->ed_threshold = ed_threshold[4];
3532 } else {
3533 log(L_INIT, "acx: acx111 doesn't support ED\n");
3534 adev->ed_threshold = 0;
3536 log(L_INIT, "acx: got Energy Detect (ED) threshold %u\n",
3537 adev->ed_threshold);
3538 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3541 if (adev->get_mask & GETSET_CCA) {
3542 if (IS_ACX100(adev)) {
3543 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3545 memset(cca, 0, sizeof(adev->cca));
3546 acx_s_interrogate(adev, cca,
3547 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3548 adev->cca = cca[4];
3549 } else {
3550 log(L_INIT, "acx: acx111 doesn't support CCA\n");
3551 adev->cca = 0;
3553 log(L_INIT, "acx: got Channel Clear Assessment (CCA) value %u\n",
3554 adev->cca);
3555 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3558 if (adev->get_mask & GETSET_REG_DOMAIN) {
3559 acx_ie_generic_t dom;
3561 acx_s_interrogate(adev, &dom,
3562 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3563 adev->reg_dom_id = dom.m.bytes[0];
3564 acx_s_set_sane_reg_domain(adev, 0);
3565 log(L_INIT, "acx: got regulatory domain 0x%02X\n", adev->reg_dom_id);
3566 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3569 if (adev->set_mask & GETSET_STATION_ID) {
3570 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3571 u8 *paddr;
3573 paddr = &stationID[4];
3574 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3575 for (i = 0; i < ETH_ALEN; i++) {
3576 /* copy the MAC address we obtained when we noticed
3577 * that the ethernet iface's MAC changed
3578 * to the card (reversed in
3579 * the card!) */
3580 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3582 acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3583 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3586 if (adev->set_mask & SET_STA_LIST) {
3587 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3589 if (adev->set_mask & SET_RATE_FALLBACK) {
3590 u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
3592 /* configure to not do fallbacks when not in auto rate mode */
3593 rate[4] =
3594 (adev->
3595 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3596 log(L_INIT, "acx: updating Tx fallback to %u retries\n", rate[4]);
3597 acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK);
3598 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3600 if (adev->set_mask & GETSET_TXPOWER) {
3601 log(L_INIT, "acx: updating the transmit power: %u dBm\n",
3602 adev->tx_level_dbm);
3603 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3604 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3607 if (adev->set_mask & GETSET_SENSITIVITY) {
3608 log(L_INIT, "acx: updating sensitivity value: %u\n",
3609 adev->sensitivity);
3610 switch (adev->radio_type) {
3611 case RADIO_RFMD_11:
3612 case RADIO_MAXIM_0D:
3613 case RADIO_RALINK_15:
3614 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3615 break;
3616 case RADIO_RADIA_16:
3617 case RADIO_UNKNOWN_17:
3618 acx111_s_sens_radio_16_17(adev);
3619 break;
3620 default:
3621 log(L_INIT, "acx: don't know how to modify the sensitivity "
3622 "for radio type 0x%02X\n", adev->radio_type);
3624 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3627 if (adev->set_mask & GETSET_ANTENNA) {
3628 /* antenna */
3629 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3631 memset(antenna, 0, sizeof(antenna));
3632 antenna[4] = adev->antenna;
3633 log(L_INIT, "acx: updating antenna value: 0x%02X\n", adev->antenna);
3634 acx_s_configure(adev, &antenna,
3635 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3636 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3639 if (adev->set_mask & GETSET_ED_THRESH) {
3640 /* ed_threshold */
3641 log(L_INIT, "acx: pdating the Energy Detect (ED) threshold: %u\n",
3642 adev->ed_threshold);
3643 if (IS_ACX100(adev)) {
3644 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3646 memset(ed_threshold, 0, sizeof(ed_threshold));
3647 ed_threshold[4] = adev->ed_threshold;
3648 acx_s_configure(adev, &ed_threshold,
3649 ACX100_IE_DOT11_ED_THRESHOLD);
3650 } else
3651 log(L_INIT, "acx: acx111 doesn't support ED\n");
3652 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3655 if (adev->set_mask & GETSET_CCA) {
3656 /* CCA value */
3657 log(L_INIT, "acx: updating the Channel Clear Assessment "
3658 "(CCA) value: 0x%02X\n", adev->cca);
3659 if (IS_ACX100(adev)) {
3660 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3662 memset(cca, 0, sizeof(cca));
3663 cca[4] = adev->cca;
3664 acx_s_configure(adev, &cca,
3665 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3666 } else
3667 log(L_INIT, "acx: acx111 doesn't support CCA\n");
3668 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3671 if (adev->set_mask & GETSET_LED_POWER) {
3672 /* Enable Tx */
3673 log(L_INIT, "acx: updating the power LED status: %u\n", adev->led_power);
3675 acx_lock(adev, flags); /* acxpci_l_power_led expects that the lock is already taken! */
3676 if (IS_PCI(adev))
3677 acxpci_l_power_led(adev, adev->led_power);
3678 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3679 acx_unlock(adev, flags);
3682 if (adev->set_mask & GETSET_POWER_80211) {
3683 #if POWER_SAVE_80211
3684 acx_s_update_80211_powersave_mode(adev);
3685 #endif
3686 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3689 if (adev->set_mask & GETSET_CHANNEL) {
3690 /* channel */
3691 log(L_INIT, "acx: updating channel to: %u\n", adev->channel);
3692 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3695 if (adev->set_mask & GETSET_TX) {
3696 /* set Tx */
3697 log(L_INIT, "acx: updating: %s Tx\n",
3698 adev->tx_disabled ? "disable" : "enable");
3699 if (adev->tx_disabled)
3700 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3701 else {
3702 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3703 &adev->channel, 1);
3704 FIXME();
3705 /* This needs to be keyed on WEP? */
3706 /* acx111_s_feature_on(adev, 0,
3707 FEATURE2_NO_TXCRYPT |
3708 FEATURE2_SNIFFER); */
3709 acx_wake_queue(adev->ieee, NULL);
3711 CLEAR_BIT(adev->set_mask, GETSET_TX);
3714 if (adev->set_mask & GETSET_RX) {
3715 /* Enable Rx */
3716 log(L_INIT, "acx: updating: enable Rx on channel: %u\n",
3717 adev->channel);
3718 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3719 CLEAR_BIT(adev->set_mask, GETSET_RX);
3722 if (adev->set_mask & GETSET_RETRY) {
3723 u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
3724 u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
3726 log(L_INIT,
3727 "acx: updating the short retry limit: %u, long retry limit: %u\n",
3728 adev->short_retry, adev->long_retry);
3729 short_retry[0x4] = adev->short_retry;
3730 long_retry[0x4] = adev->long_retry;
3731 acx_s_configure(adev, &short_retry,
3732 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
3733 acx_s_configure(adev, &long_retry,
3734 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
3735 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3738 if (adev->set_mask & SET_MSDU_LIFETIME) {
3739 u8 xmt_msdu_lifetime[4 +
3740 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3742 log(L_INIT, "acx: updating the tx MSDU lifetime: %u\n",
3743 adev->msdu_lifetime);
3744 *(u32 *) & xmt_msdu_lifetime[4] =
3745 cpu_to_le32((u32) adev->msdu_lifetime);
3746 acx_s_configure(adev, &xmt_msdu_lifetime,
3747 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
3748 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3751 if (adev->set_mask & GETSET_REG_DOMAIN) {
3752 log(L_INIT, "acx: updating the regulatory domain: 0x%02X\n",
3753 adev->reg_dom_id);
3754 acx_s_set_sane_reg_domain(adev, 1);
3755 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3757 if (adev->set_mask & GETSET_MODE ) {
3758 acx111_s_feature_on(adev, 0,
3759 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3760 switch (adev->mode) {
3761 case ACX_MODE_3_AP:
3762 adev->aid = 0;
3763 //acx111_s_feature_off(adev, 0,
3764 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3765 MAC_COPY(adev->bssid, adev->dev_addr);
3766 acx_s_cmd_join_bssid(adev, adev->dev_addr);
3767 break;
3768 case ACX_MODE_MONITOR:
3769 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3770 break;
3771 case ACX_MODE_0_ADHOC:
3772 case ACX_MODE_2_STA:
3773 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3774 break;
3775 default:
3776 break;
3778 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3780 if (adev->set_mask & SET_TEMPLATES) {
3781 switch (adev->mode)
3783 case ACX_MODE_3_AP:
3784 acx_s_set_tim_template(adev);
3785 break;
3786 default:
3787 break;
3789 if (adev->beacon_cache)
3791 acx_s_set_beacon_template(adev, adev->beacon_cache);
3792 dev_kfree_skb(adev->beacon_cache);
3793 adev->beacon_cache = NULL;
3795 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3798 if (adev->set_mask & SET_RXCONFIG) {
3799 acx_s_initialize_rx_config(adev);
3800 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3803 if (adev->set_mask & GETSET_RESCAN) {
3804 /* switch (adev->mode) {
3805 case ACX_MODE_0_ADHOC:
3806 case ACX_MODE_2_STA:
3807 start_scan = 1;
3808 break;
3810 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3813 if (adev->set_mask & GETSET_WEP) {
3814 /* encode */
3816 ie_dot11WEPDefaultKeyID_t dkey;
3817 #ifdef DEBUG_WEP
3818 struct {
3819 u16 type;
3820 u16 len;
3821 u8 val;
3822 } ACX_PACKED keyindic;
3823 #endif
3824 log(L_INIT, "acx: updating WEP key settings\n");
3826 acx_s_set_wepkey(adev);
3827 if (adev->wep_enabled) {
3828 dkey.KeyID = adev->wep_current_index;
3829 log(L_INIT, "acx: setting WEP key %u as default\n",
3830 dkey.KeyID);
3831 acx_s_configure(adev, &dkey,
3832 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
3833 #ifdef DEBUG_WEP
3834 keyindic.val = 3;
3835 acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
3836 #endif
3839 // start_scan = 1;
3840 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3843 if (adev->set_mask & SET_WEP_OPTIONS) {
3844 acx100_ie_wep_options_t options;
3846 if (IS_ACX111(adev)) {
3847 log(L_DEBUG,
3848 "acx: setting WEP Options for acx111 is not supported\n");
3849 } else {
3850 log(L_INIT, "acx: setting WEP Options\n");
3852 /* let's choose maximum setting: 4 default keys,
3853 * plus 10 other keys: */
3854 options.NumKeys =
3855 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3856 /* don't decrypt default key only,
3857 * don't override decryption: */
3858 options.WEPOption = 0;
3859 if (adev->mode == ACX_MODE_3_AP) {
3860 /* don't decrypt default key only,
3861 * override decryption mechanism: */
3862 options.WEPOption = 2;
3865 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3867 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3871 /* debug, rate, and nick don't need any handling */
3872 /* what about sniffing mode?? */
3874 /* log(L_INIT, "acx: get_mask 0x%08X, set_mask 0x%08X - after update\n",
3875 adev->get_mask, adev->set_mask);
3877 /* end: */
3878 FN_EXIT0;
3881 #if 0
3882 /***********************************************************************
3883 ** acx_e_after_interrupt_task
3885 static int acx_s_recalib_radio(acx_device_t * adev)
3887 if (IS_ACX111(adev)) {
3888 acx111_cmd_radiocalib_t cal;
3890 /* automatic recalibration, choose all methods: */
3891 cal.methods = cpu_to_le32(0x8000000f);
3892 /* automatic recalibration every 60 seconds (value in TUs)
3893 * I wonder what the firmware default here is? */
3894 cal.interval = cpu_to_le32(58594);
3895 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3896 &cal, sizeof(cal),
3897 CMD_TIMEOUT_MS(100));
3898 } else {
3899 /* On ACX100, we need to recalibrate the radio
3900 * by issuing a GETSET_TX|GETSET_RX */
3901 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3902 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3903 (OK ==
3904 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3905 &adev->channel, 1))
3906 && (OK ==
3907 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3908 &adev->channel, 1)))
3909 return OK;
3910 return NOT_OK;
3913 #endif // if 0
3914 #if 0
3915 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3917 int res;
3919 /* this helps with ACX100 at least;
3920 * hopefully ACX111 also does a
3921 * recalibration here */
3923 /* clear flag beforehand, since we want to make sure
3924 * it's cleared; then only set it again on specific circumstances */
3925 CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3927 /* better wait a bit between recalibrations to
3928 * prevent overheating due to torturing the card
3929 * into working too long despite high temperature
3930 * (just a safety measure) */
3931 if (adev->recalib_time_last_success
3932 && time_before(jiffies, adev->recalib_time_last_success
3933 + RECALIB_PAUSE * 60 * HZ)) {
3934 if (adev->recalib_msg_ratelimit <= 4) {
3935 printk("acx: %s: less than " STRING(RECALIB_PAUSE)
3936 " minutes since last radio recalibration, "
3937 "not recalibrating (maybe the card is too hot?)\n",
3938 wiphy_name(adev->ieee->wiphy));
3939 adev->recalib_msg_ratelimit++;
3940 if (adev->recalib_msg_ratelimit == 5)
3941 printk("acx: disabling the above message until next recalib\n");
3943 return;
3946 adev->recalib_msg_ratelimit = 0;
3948 /* note that commands sometimes fail (card busy),
3949 * so only clear flag if we were fully successful */
3950 res = acx_s_recalib_radio(adev);
3951 if (res == OK) {
3952 printk("acx: %s: successfully recalibrated radio\n",
3953 wiphy_name(adev->ieee->wiphy));
3954 adev->recalib_time_last_success = jiffies;
3955 adev->recalib_failure_count = 0;
3956 } else {
3957 /* failed: resubmit, but only limited
3958 * amount of times within some time range
3959 * to prevent endless loop */
3961 adev->recalib_time_last_success = 0; /* we failed */
3963 /* if some time passed between last
3964 * attempts, then reset failure retry counter
3965 * to be able to do next recalib attempt */
3966 if (time_after
3967 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3968 adev->recalib_failure_count = 0;
3970 if (adev->recalib_failure_count < 5) {
3971 /* increment inside only, for speedup of outside path */
3972 adev->recalib_failure_count++;
3973 adev->recalib_time_last_attempt = jiffies;
3974 acx_schedule_task(adev,
3975 ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3979 #endif // if 0
3981 void acx_e_after_interrupt_task(struct work_struct *work)
3983 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
3984 unsigned long flags;
3986 FN_ENTER;
3988 acx_lock(adev, flags);
3990 if (!adev->after_interrupt_jobs || !adev->initialized)
3991 goto end; /* no jobs to do */
3993 /* we see lotsa tx errors */
3994 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) {
3995 printk("acx: too many TX errors??\n");
3996 // acx_s_after_interrupt_recalib(adev);
3999 /* a poor interrupt code wanted to do update_card_settings() */
4000 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) {
4001 if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
4002 acx_unlock(adev, flags);
4003 acx_s_update_card_settings(adev);
4004 acx_lock(adev, flags);
4006 CLEAR_BIT(adev->after_interrupt_jobs,
4007 ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4010 /* 1) we detected that no Scan_Complete IRQ came from fw, or
4011 ** 2) we found too many STAs */
4012 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) {
4013 log(L_IRQ, "acx: sending a stop scan cmd...\n");
4014 acx_unlock(adev, flags);
4015 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
4016 acx_lock(adev, flags);
4017 /* HACK: set the IRQ bit, since we won't get a
4018 * scan complete IRQ any more on ACX111 (works on ACX100!),
4019 * since _we_, not a fw, have stopped the scan */
4020 SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
4021 CLEAR_BIT(adev->after_interrupt_jobs,
4022 ACX_AFTER_IRQ_CMD_STOP_SCAN);
4025 /* either fw sent Scan_Complete or we detected that
4026 ** no Scan_Complete IRQ came from fw. Finish scanning,
4027 ** pick join partner if any */
4028 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) {
4029 /* + scan kills current join status - restore it
4030 ** (do we need it for STA?) */
4031 /* + does it happen only with active scans?
4032 ** active and passive scans? ALL scans including
4033 ** background one? */
4034 /* + was not verified that everything is restored
4035 ** (but at least we start to emit beacons again) */
4036 CLEAR_BIT(adev->after_interrupt_jobs,
4037 ACX_AFTER_IRQ_COMPLETE_SCAN);
4040 /* STA auth or assoc timed out, start over again */
4042 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) {
4043 log(L_IRQ, "acx: sending a start_scan cmd...\n");
4044 CLEAR_BIT(adev->after_interrupt_jobs,
4045 ACX_AFTER_IRQ_RESTART_SCAN);
4048 /* whee, we got positive assoc response! 8) */
4049 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) {
4050 CLEAR_BIT(adev->after_interrupt_jobs,
4051 ACX_AFTER_IRQ_CMD_ASSOCIATE);
4053 end:
4054 if(adev->after_interrupt_jobs)
4056 printk("acx: Jobs still to be run: %x\n",adev->after_interrupt_jobs);
4057 adev->after_interrupt_jobs = 0;
4059 acx_unlock(adev, flags);
4060 // acx_sem_unlock(adev);
4061 FN_EXIT0;
4065 /***********************************************************************
4066 ** acx_schedule_task
4068 ** Schedule the call of the after_interrupt method after leaving
4069 ** the interrupt context.
4071 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
4073 if (!adev->after_interrupt_jobs)
4075 SET_BIT(adev->after_interrupt_jobs, set_flag);
4076 schedule_work(&adev->after_interrupt_task);
4081 /***********************************************************************
4083 void acx_init_task_scheduler(acx_device_t * adev)
4085 /* configure task scheduler */
4086 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4090 /***********************************************************************
4091 ** acx_s_start
4093 void acx_s_start(acx_device_t * adev)
4095 FN_ENTER;
4098 * Ok, now we do everything that can possibly be done with ioctl
4099 * calls to make sure that when it was called before the card
4100 * was up we get the changes asked for
4103 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4104 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4105 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4106 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4108 log(L_INIT, "acx: updating initial settings on iface activation\n");
4109 acx_s_update_card_settings(adev);
4111 FN_EXIT0;
4115 /***********************************************************************
4116 ** acx_update_capabilities
4117 *//*
4118 void acx_update_capabilities(acx_device_t * adev)
4120 u16 cap = 0;
4122 switch (adev->mode) {
4123 case ACX_MODE_3_AP:
4124 SET_BIT(cap, WF_MGMT_CAP_ESS);
4125 break;
4126 case ACX_MODE_0_ADHOC:
4127 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4128 break;
4129 */ /* other types of stations do not emit beacons */
4130 /* }
4132 if (adev->wep_restricted) {
4133 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4135 if (adev->cfgopt_dot11ShortPreambleOption) {
4136 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4138 if (adev->cfgopt_dot11PBCCOption) {
4139 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4141 if (adev->cfgopt_dot11ChannelAgility) {
4142 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4144 log(L_DEBUG, "acx: caps updated from 0x%04X to 0x%04X\n",
4145 adev->capabilities, cap);
4146 adev->capabilities = cap;
4150 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4153 static void acx_s_select_opmode(acx_device_t * adev)
4155 int changed = 0;
4156 FN_ENTER;
4158 if (adev->interface.operating) {
4159 switch (adev->interface.type) {
4160 case IEEE80211_IF_TYPE_AP:
4161 if (adev->mode != ACX_MODE_3_AP)
4163 adev->mode = ACX_MODE_3_AP;
4164 changed = 1;
4166 break;
4167 case IEEE80211_IF_TYPE_IBSS:
4168 if (adev->mode != ACX_MODE_0_ADHOC)
4170 adev->mode = ACX_MODE_0_ADHOC;
4171 changed = 1;
4173 break;
4174 case IEEE80211_IF_TYPE_STA:
4175 if (adev->mode != ACX_MODE_2_STA)
4177 adev->mode = ACX_MODE_2_STA;
4178 changed = 1;
4180 break;
4181 case IEEE80211_IF_TYPE_WDS:
4182 default:
4183 if (adev->mode != ACX_MODE_OFF)
4185 adev->mode = ACX_MODE_OFF;
4186 changed = 1;
4188 break;
4190 } else {
4191 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4193 if (adev->mode != ACX_MODE_MONITOR)
4195 adev->mode = ACX_MODE_MONITOR;
4196 changed = 1;
4199 else
4201 if (adev->mode != ACX_MODE_OFF)
4203 adev->mode = ACX_MODE_OFF;
4204 changed = 1;
4208 if (changed)
4210 SET_BIT(adev->set_mask, GETSET_MODE);
4211 acx_s_update_card_settings(adev);
4212 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4215 FN_EXIT0;
4219 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4223 int acx_add_interface(struct ieee80211_hw *ieee,
4224 struct ieee80211_if_init_conf *conf)
4226 acx_device_t *adev = ieee2adev(ieee);
4227 unsigned long flags;
4228 int err = -EOPNOTSUPP;
4230 DECLARE_MAC_BUF(mac);
4232 FN_ENTER;
4233 acx_lock(adev, flags);
4235 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4236 adev->interface.monitor++;
4237 } else {
4238 if (adev->interface.operating)
4239 goto out_unlock;
4240 adev->interface.operating = 1;
4241 adev->interface.mac_addr = conf->mac_addr;
4242 adev->interface.type = conf->type;
4244 // adev->mode = conf->type;
4246 acx_unlock(adev, flags);
4248 if (adev->initialized)
4249 acx_s_select_opmode(adev);
4251 acx_lock(adev, flags);
4253 err = 0;
4255 printk(KERN_INFO "acx: Virtual interface added "
4256 "(type: 0x%08X, MAC: %s)\n",
4257 conf->type,
4258 print_mac(mac, conf->mac_addr));
4260 out_unlock:
4261 acx_unlock(adev, flags);
4263 FN_EXIT0;
4264 return err;
4267 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4271 void acx_remove_interface(struct ieee80211_hw *hw,
4272 struct ieee80211_if_init_conf *conf)
4274 acx_device_t *adev = ieee2adev(hw);
4276 DECLARE_MAC_BUF(mac);
4278 FN_ENTER;
4280 acx_sem_lock(adev);
4281 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4282 adev->interface.monitor--;
4283 // assert(bcm->interface.monitor >= 0);
4284 } else {
4285 adev->interface.operating = 0;
4288 printk("acx: Removing interface: %d %d\n", adev->interface.operating, conf->type);
4289 acx_sem_unlock(adev);
4291 if (adev->initialized)
4292 acx_s_select_opmode(adev);
4293 flush_scheduled_work();
4295 printk(KERN_INFO "acx: Virtual interface removed "
4296 "(type: 0x%08X, MAC: %s)\n",
4297 conf->type, print_mac(mac, conf->mac_addr));
4299 FN_EXIT0;
4302 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4306 int acx_net_reset(struct ieee80211_hw *ieee)
4308 acx_device_t *adev = ieee2adev(ieee);
4309 FN_ENTER;
4310 if (IS_PCI(adev))
4311 acxpci_s_reset_dev(adev);
4312 else
4313 TODO();
4315 FN_EXIT0;
4316 return 0;
4320 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4323 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4325 int result;
4327 FN_ENTER;
4329 acx_sem_lock(adev);
4330 adev->rx_status.channel = channel;
4331 adev->rx_status.freq = freq;
4333 adev->channel = channel;
4334 /* hmm, the following code part is strange, but this is how
4335 * it was being done before... */
4336 log(L_IOCTL, "acx: Changing to channel %d\n", channel);
4337 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4338 result = -EINPROGRESS; /* need to call commit handler */
4340 acx_sem_unlock(adev);
4341 FN_EXIT1(result);
4342 return result;
4346 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4349 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4351 acx_device_t *adev = ieee2adev(hw);
4352 unsigned long flags;
4354 FN_ENTER;
4356 acx_lock(adev, flags);
4357 //FIXME();
4358 if (!adev->initialized) {
4359 acx_unlock(adev, flags);
4360 return 0;
4362 if (conf->beacon_int != adev->beacon_interval)
4363 adev->beacon_interval = conf->beacon_int;
4364 if (conf->channel != adev->channel) {
4365 acx_unlock(adev, flags);
4366 acx_selectchannel(adev, conf->channel,conf->freq);
4367 acx_lock(adev, flags);
4368 /* acx_schedule_task(adev,
4369 ACX_AFTER_IRQ_UPDATE_CARD_CFG
4370 */ /*+ ACX_AFTER_IRQ_RESTART_SCAN */ /*);*/
4373 if (conf->short_slot_time != adev->short_slot) {
4374 // assert(phy->type == BCM43xx_PHYTYPE_G);
4375 if (conf->short_slot_time)
4376 acx_short_slot_timing_enable(adev);
4377 else
4378 acx_short_slot_timing_disable(adev);
4379 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4382 adev->tx_disabled = !conf->radio_enabled;
4383 /* if (conf->power_level != 0){
4384 adev->tx_level_dbm = conf->power_level;
4385 acx_s_set_tx_level(adev, adev->tx_level_dbm);
4386 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4387 //acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4390 //FIXME: This does not seem to wake up:
4391 #if 0
4392 if (conf->power_level == 0) {
4393 if (radio->enabled)
4394 bcm43xx_radio_turn_off(bcm);
4395 } else {
4396 if (!radio->enabled)
4397 bcm43xx_radio_turn_on(bcm);
4399 #endif
4401 //TODO: phymode
4402 //TODO: antennas
4403 if (adev->set_mask > 0) {
4404 acx_unlock(adev, flags);
4405 acx_s_update_card_settings(adev);
4406 acx_lock(adev, flags);
4408 acx_unlock(adev, flags);
4410 FN_EXIT0;
4411 return 0;
4415 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4419 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
4420 extern int acx_config_interface(struct ieee80211_hw* ieee,
4421 struct ieee80211_vif *vif,
4422 struct ieee80211_if_conf *conf)
4424 acx_device_t *adev = ieee2adev(ieee);
4425 unsigned long flags;
4426 int err = -ENODEV;
4427 FN_ENTER;
4428 if (!adev->interface.operating)
4429 goto err_out;
4431 if (adev->initialized)
4432 acx_s_select_opmode(adev);
4434 acx_lock(adev, flags);
4436 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4437 && (adev->vif == vif)) {
4438 if (conf->bssid)
4440 adev->interface.bssid = conf->bssid;
4441 MAC_COPY(adev->bssid,conf->bssid);
4444 if ((conf->type == IEEE80211_IF_TYPE_AP)
4445 && (adev->vif == vif)) {
4446 #else
4447 int acx_config_interface(struct ieee80211_hw* ieee, int if_id,
4448 struct ieee80211_if_conf *conf)
4450 acx_device_t *adev = ieee2adev(ieee);
4451 unsigned long flags;
4452 int err = -ENODEV;
4453 FN_ENTER;
4454 if (!adev->interface.operating)
4455 goto err_out;
4457 if (adev->initialized)
4458 acx_s_select_opmode(adev);
4460 acx_lock(adev, flags);
4462 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4463 && (adev->interface.if_id == if_id)) {
4464 if (conf->bssid)
4466 adev->interface.bssid = conf->bssid;
4467 MAC_COPY(adev->bssid,conf->bssid);
4470 if ((conf->type == IEEE80211_IF_TYPE_AP)
4471 && (adev->interface.if_id == if_id)) {
4472 #endif
4474 if ((conf->ssid_len > 0) && conf->ssid)
4476 adev->essid_len = conf->ssid_len;
4477 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4478 SET_BIT(adev->set_mask, SET_TEMPLATES);
4481 if (conf->beacon != 0)
4483 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4484 adev->beacon_cache = conf->beacon;
4485 SET_BIT(adev->set_mask, SET_TEMPLATES);
4488 acx_unlock(adev, flags);
4490 if (adev->set_mask != 0)
4491 acx_s_update_card_settings(adev);
4492 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4493 err = 0;
4494 err_out:
4495 FN_EXIT1(err);
4496 return err;
4500 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4504 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4505 struct ieee80211_tx_queue_stats *stats)
4507 // acx_device_t *adev = ndev2adev(net_dev);
4508 struct ieee80211_tx_queue_stats_data *data;
4509 int err = -ENODEV;
4511 FN_ENTER;
4513 // acx_lock(adev, flags);
4514 data = &(stats->data[0]);
4515 data->len = 0;
4516 data->limit = TX_CNT;
4517 data->count = 0;
4518 // acx_unlock(adev, flags);
4520 FN_EXIT0;
4521 return err;
4524 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4528 int acx_net_conf_tx(struct ieee80211_hw *hw,
4529 int queue, const struct ieee80211_tx_queue_params *params)
4531 FN_ENTER;
4532 // TODO();
4533 FN_EXIT0;
4534 return 0;
4537 static void keymac_write(acx_device_t * adev, u16 index, const u32 * addr)
4539 /* for keys 0-3 there is no associated mac address */
4540 if (index < 4)
4541 return;
4543 index -= 4;
4544 if (1) {
4545 TODO();
4547 bcm43xx_shm_write32(bcm,
4548 BCM43xx_SHM_HWMAC,
4549 index * 2,
4550 cpu_to_be32(*addr));
4551 bcm43xx_shm_write16(bcm,
4552 BCM43xx_SHM_HWMAC,
4553 (index * 2) + 1,
4554 cpu_to_be16(*((u16 *)(addr + 1))));
4556 } else {
4557 if (index < 8) {
4558 TODO(); /* Put them in the macaddress filter */
4559 } else {
4560 TODO();
4561 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4562 Keep in mind to update the count of keymacs in 0x003 */
4568 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4572 int acx_clear_keys(acx_device_t * adev)
4574 static const u32 zero_mac[2] = { 0 };
4575 unsigned int i, j, nr_keys = 54;
4576 u16 offset;
4578 /* FixMe:Check for Number of Keys available */
4580 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4582 for (i = 0; i < nr_keys; i++) {
4583 adev->key[i].enabled = 0;
4584 /* returns for i < 4 immediately */
4585 keymac_write(adev, i, zero_mac);
4587 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4588 0x100 + (i * 2), 0x0000);
4590 for (j = 0; j < 8; j++) {
4591 offset =
4592 adev->security_offset + (j * 4) +
4593 (i * ACX_SEC_KEYSIZE);
4595 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4596 offset, 0x0000);
4600 return 1;
4604 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4608 int acx_key_write(acx_device_t * adev,
4609 u16 index, u8 algorithm,
4610 const struct ieee80211_key_conf *key, const u8 * mac_addr)
4612 // struct iw_point *dwrq = &wrqu->encoding;
4613 int result;
4615 FN_ENTER;
4617 log(L_IOCTL, "acx: set encoding flags=0x%04X, size=%d, key: %s\n",
4618 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4620 // acx_sem_lock(adev);
4622 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4623 if (key->keylen > 0) {
4624 /* if index is 0 or invalid, use default key */
4625 if (index > 3)
4626 index = (int)adev->wep_current_index;
4627 if ((algorithm == ACX_SEC_ALGO_WEP) ||
4628 (algorithm == ACX_SEC_ALGO_WEP104)) {
4629 switch(key->keylen) {
4630 case 40 / 8:
4631 /* WEP 40-bit =
4632 40-bit entered key + 24 bit IV = 64-bit */
4633 adev->wep_keys[index].size = 13;
4634 break;
4635 case 104 / 8:
4636 /* WEP 104-bit =
4637 104-bit entered key + 24-bit IV = 128-bit */
4638 adev->wep_keys[index].size = 29;
4639 break;
4640 case 128 / 8:
4641 /* WEP 128-bit =
4642 128-bit entered key + 24 bit IV = 152-bit */
4643 adev->wep_keys[index].size = 16;
4644 break;
4645 default:
4646 adev->wep_keys[index].size = 0;
4647 return -EINVAL; /* shouldn't happen */
4650 memset(adev->wep_keys[index].key, 0,
4651 sizeof(adev->wep_keys[index].key));
4652 memcpy(adev->wep_keys[index].key, key, key->keylen);
4653 } else {
4654 /* set transmit key */
4655 if (index <= 3)
4656 adev->wep_current_index = index;
4657 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4658 /* complain if we were not just setting
4659 * the key mode */
4660 // result = -EINVAL;
4661 // goto end_unlock;
4662 // }
4666 adev->wep_enabled = (algorithm == ALG_WEP);
4668 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4670 if (algorithm & IW_ENCODE_OPEN) {
4671 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4672 adev->wep_restricted = 0;
4674 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4675 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4676 adev->wep_restricted = 1;
4679 // adev->auth_alg = algorithm;
4680 /* set flag to make sure the card WEP settings get updated */
4681 if (adev->wep_enabled) {
4682 SET_BIT(adev->set_mask, GETSET_WEP);
4683 acx_s_update_card_settings(adev);
4684 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4687 log(L_IOCTL, "acx: len=%d, key at 0x%p, flags=0x%X\n",
4688 dwrq->length, extra, dwrq->flags);
4689 for (index = 0; index <= 3; index++) {
4690 if (adev->wep_keys[index].size) {
4691 log(L_IOCTL, "acx: index=%d, size=%d, key at 0x%p\n",
4692 adev->wep_keys[index].index,
4693 (int) adev->wep_keys[index].size,
4694 adev->wep_keys[index].key);
4698 result = -EINPROGRESS;
4699 // acx_sem_unlock(adev);
4701 FN_EXIT1(result);
4702 return result;
4708 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4712 int acx_net_set_key(struct ieee80211_hw *ieee,
4713 enum set_key_cmd cmd, const u8 *local_addr,
4714 const u8 * addr, struct ieee80211_key_conf *key)
4716 // return 0;
4717 struct acx_device *adev = ieee2adev(ieee);
4718 unsigned long flags;
4719 u8 algorithm;
4720 u16 index;
4721 int err = -EINVAL;
4722 FN_ENTER;
4723 // TODO();
4724 switch (key->alg) {
4725 default:
4726 /* case ALG_NONE:
4727 case ALG_NULL:
4728 algorithm = ACX_SEC_ALGO_NONE;
4729 break;
4730 */ case ALG_WEP:
4731 if (key->keylen == 5)
4732 algorithm = ACX_SEC_ALGO_WEP;
4733 else
4734 algorithm = ACX_SEC_ALGO_WEP104;
4735 break;
4736 case ALG_TKIP:
4737 algorithm = ACX_SEC_ALGO_TKIP;
4738 break;
4739 case ALG_CCMP:
4740 algorithm = ACX_SEC_ALGO_AES;
4741 break;
4744 index = (u8) (key->keyidx);
4745 if (index >= ARRAY_SIZE(adev->key))
4746 goto out;
4747 acx_lock(adev, flags);
4748 switch (cmd) {
4749 case SET_KEY:
4750 err = acx_key_write(adev, index, algorithm, key, addr);
4751 if (err)
4752 goto out_unlock;
4753 key->hw_key_idx = index;
4754 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4755 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4756 adev->default_key_idx = index;*/
4757 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4758 adev->key[index].enabled = 1;
4759 break;
4760 case DISABLE_KEY:
4761 adev->key[index].enabled = 0;
4762 err = 0;
4763 break;
4764 /* case ENABLE_COMPRESSION:
4765 case DISABLE_COMPRESSION:
4766 err = 0;
4767 break; */
4769 out_unlock:
4770 acx_unlock(adev, flags);
4771 out:
4772 FN_EXIT0;
4773 return err;
4778 /***********************************************************************
4779 ** Common function to parse ALL configoption struct formats
4780 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4781 ** FIXME: logging should be removed here and added to a /proc file instead
4783 ** Look into bcm43xx
4785 void
4786 acx_s_parse_configoption(acx_device_t * adev,
4787 const acx111_ie_configoption_t * pcfg)
4789 const u8 *pEle;
4790 int i;
4791 int is_acx111 = IS_ACX111(adev);
4793 if (acx_debug & L_DEBUG) {
4794 printk("acx: configoption struct content:\n");
4795 acx_dump_bytes(pcfg, sizeof(*pcfg));
4798 if ((is_acx111 && (adev->eeprom_version == 5))
4799 || (!is_acx111 && (adev->eeprom_version == 4))
4800 || (!is_acx111 && (adev->eeprom_version == 5))) {
4801 /* these versions are known to be supported */
4802 } else {
4803 printk("acx: unknown chip and EEPROM version combination (%s, v%d), "
4804 "don't know how to parse config options yet. "
4805 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4806 adev->eeprom_version);
4807 return;
4810 /* first custom-parse the first part which has chip-specific layout */
4812 pEle = (const u8 *)pcfg;
4814 pEle += 4; /* skip (type,len) header */
4816 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4817 pEle += sizeof(adev->cfgopt_NVSv);
4819 if (is_acx111) {
4820 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4821 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4823 adev->cfgopt_probe_delay = 200; /* good default value? */
4824 pEle += 2; /* FIXME: unknown, value 0x0001 */
4825 } else {
4826 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4827 pEle += sizeof(adev->cfgopt_MAC);
4829 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4830 pEle += sizeof(adev->cfgopt_probe_delay);
4831 if ((adev->cfgopt_probe_delay < 100)
4832 || (adev->cfgopt_probe_delay > 500)) {
4833 printk("acx: strange probe_delay value %d, "
4834 "tweaking to 200\n", adev->cfgopt_probe_delay);
4835 adev->cfgopt_probe_delay = 200;
4839 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4840 pEle += sizeof(adev->cfgopt_eof_memory);
4842 printk("acx: NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n",
4843 adev->cfgopt_NVS_vendor_offs,
4844 adev->cfgopt_probe_delay, adev->cfgopt_eof_memory);
4846 adev->cfgopt_dot11CCAModes = *pEle++;
4847 adev->cfgopt_dot11Diversity = *pEle++;
4848 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4849 adev->cfgopt_dot11PBCCOption = *pEle++;
4850 adev->cfgopt_dot11ChannelAgility = *pEle++;
4851 adev->cfgopt_dot11PhyType = *pEle++;
4852 adev->cfgopt_dot11TempType = *pEle++;
4853 printk("acx: CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4854 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4855 adev->cfgopt_dot11CCAModes,
4856 adev->cfgopt_dot11Diversity,
4857 adev->cfgopt_dot11ShortPreambleOption,
4858 adev->cfgopt_dot11PBCCOption,
4859 adev->cfgopt_dot11ChannelAgility,
4860 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4862 /* then use common parsing for next part which has common layout */
4864 pEle++; /* skip table_count (6) */
4866 adev->cfgopt_antennas.type = pEle[0];
4867 adev->cfgopt_antennas.len = pEle[1];
4868 printk("acx: AntennaID:%02X Len:%02X Data:",
4869 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4870 for (i = 0; i < pEle[1]; i++) {
4871 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4872 printk("%02X ", pEle[i + 2]);
4874 printk("\n");
4876 pEle += pEle[1] + 2;
4877 adev->cfgopt_power_levels.type = pEle[0];
4878 adev->cfgopt_power_levels.len = pEle[1];
4879 printk("acx: PowerLevelID:%02X Len:%02X Data:",
4880 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4881 for (i = 0; i < pEle[1]; i++) {
4882 adev->cfgopt_power_levels.list[i] =
4883 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4884 printk("acx: %04X ", adev->cfgopt_power_levels.list[i]);
4886 printk("\n");
4888 pEle += pEle[1] * 2 + 2;
4889 adev->cfgopt_data_rates.type = pEle[0];
4890 adev->cfgopt_data_rates.len = pEle[1];
4891 printk("acx: DataRatesID:%02X Len:%02X Data:",
4892 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4893 for (i = 0; i < pEle[1]; i++) {
4894 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4895 printk("%02X ", pEle[i + 2]);
4897 printk("\n");
4899 pEle += pEle[1] + 2;
4900 adev->cfgopt_domains.type = pEle[0];
4901 adev->cfgopt_domains.len = pEle[1];
4902 printk("acx: DomainID:%02X Len:%02X Data:",
4903 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4904 for (i = 0; i < pEle[1]; i++) {
4905 adev->cfgopt_domains.list[i] = pEle[i + 2];
4906 printk("%02X ", pEle[i + 2]);
4908 printk("\n");
4910 pEle += pEle[1] + 2;
4911 adev->cfgopt_product_id.type = pEle[0];
4912 adev->cfgopt_product_id.len = pEle[1];
4913 for (i = 0; i < pEle[1]; i++) {
4914 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4916 printk("acx: ProductID:%02X Len:%02X Data:%.*s\n",
4917 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4918 adev->cfgopt_product_id.len,
4919 (char *)adev->cfgopt_product_id.list);
4921 pEle += pEle[1] + 2;
4922 adev->cfgopt_manufacturer.type = pEle[0];
4923 adev->cfgopt_manufacturer.len = pEle[1];
4924 for (i = 0; i < pEle[1]; i++) {
4925 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4927 printk("acx: ManufacturerID:%02X Len:%02X Data:%.*s\n",
4928 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4929 adev->cfgopt_manufacturer.len,
4930 (char *)adev->cfgopt_manufacturer.list);
4932 printk("acx: EEPROM part:\n");
4933 for (i=0; i<58; i++) {
4934 printk("%02X =======> 0x%02X\n",
4935 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4941 /***********************************************************************
4942 ** Linux Kernel Specific
4944 static int __init acx_e_init_module(void)
4946 int r1, r2;
4948 acx_struct_size_check();
4950 printk("acx: this driver is still EXPERIMENTAL\n"
4951 "acx: please read the README file and/or "
4952 "go to http://acx100.sourceforge.net/wiki for "
4953 "further information\n");
4955 #if defined(CONFIG_ACX_MAC80211_PCI)
4956 r1 = acxpci_e_init_module();
4957 #else
4958 r1 = -EINVAL;
4959 #endif
4960 #if defined(CONFIG_ACX_MAC80211_USB)
4961 r2 = acxusb_e_init_module();
4962 #else
4963 r2 = -EINVAL;
4964 #endif
4965 if (r2 && r1) /* both failed! */
4966 return r2 ? r2 : r1;
4967 /* return success if at least one succeeded */
4968 return 0;
4971 static void __exit acx_e_cleanup_module(void)
4973 #if defined(CONFIG_ACX_MAC80211_PCI)
4974 acxpci_e_cleanup_module();
4975 #endif
4976 #if defined(CONFIG_ACX_MAC80211_USB)
4977 acxusb_e_cleanup_module();
4978 #endif
4981 module_init(acx_e_init_module)
4982 module_exit(acx_e_cleanup_module)