fix more possible lockups
[acx-mac80211.git] / common.c
blob515ab6e1b0bc53d3b6d57aec571f48f413de0ec6
1 /**** (legal) claimer in README
2 ** Copyright (C) 2003 ACX100 Open Source Project
3 */
5 #include <linux/version.h>
6 #include <linux/module.h>
7 #include <linux/kernel.h>
8 #include <linux/sched.h>
9 #include <linux/types.h>
10 #include <linux/slab.h>
11 #include <linux/delay.h>
12 #include <linux/proc_fs.h>
13 #include <linux/if_arp.h>
14 #include <linux/rtnetlink.h>
15 #include <linux/netdevice.h>
16 #include <linux/etherdevice.h>
17 #include <linux/wireless.h>
18 #include <linux/pm.h>
19 #include <linux/vmalloc.h>
20 #include <linux/firmware.h>
21 //#include <net/iw_handler.h>
22 #include <linux/ethtool.h>
23 //#include <linux/utsrelease.h>
25 #include "acx.h"
28 /***********************************************************************
31 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf);
35 /***********************************************************************
37 #if ACX_DEBUG
38 unsigned int acx_debug /* will add __read_mostly later */ = ACX_DEFAULT_MSG;
39 /* parameter is 'debug', corresponding var is acx_debug */
40 module_param_named(debug, acx_debug, uint, 0);
41 MODULE_PARM_DESC(debug, "Debug level mask (see L_xxx constants)");
42 #endif
44 #ifdef MODULE_LICENSE
45 MODULE_LICENSE("Dual MPL/GPL");
46 #endif
47 /* USB had this: MODULE_AUTHOR("Martin Wawro <martin.wawro AT uni-dortmund.de>"); */
48 MODULE_AUTHOR("ACX100 Open Source Driver development team");
49 MODULE_DESCRIPTION
50 ("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)");
52 #ifdef MODULE_VERSION
53 MODULE_VERSION(ACX_RELEASE);
54 #endif
56 /***********************************************************************
58 /* Probably a number of acx's intermediate buffers for USB transfers,
59 ** not to be confused with number of descriptors in tx/rx rings
60 ** (which are not directly accessible to host in USB devices) */
61 #define USB_RX_CNT 10
62 #define USB_TX_CNT 10
65 /***********************************************************************
68 /* minutes to wait until next radio recalibration: */
69 #define RECALIB_PAUSE 5
71 /* Please keep acx_reg_domain_ids_len in sync... */
72 const u8 acx_reg_domain_ids[acx_reg_domain_ids_len] =
73 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 };
74 static const u16 reg_domain_channel_masks[acx_reg_domain_ids_len] =
75 { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc };
76 const char *const
77 acx_reg_domain_strings[] = {
78 /* 0 */ " 1-11 FCC (USA)",
79 /* 1 */ " 1-11 DOC/IC (Canada)",
80 /* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */
81 /* 2 */ " 1-13 ETSI (Europe)",
82 /* 3 */ "10-11 Spain",
83 /* 4 */ "10-13 France",
84 /* 5 */ " 14 MKK (Japan)",
85 /* 6 */ " 1-14 MKK1",
86 /* 7 */ " 3-9 Israel (not all firmware versions)",
87 NULL /* needs to remain as last entry */
92 /***********************************************************************
93 ** Debugging support
95 #ifdef PARANOID_LOCKING
96 static unsigned max_lock_time;
97 static unsigned max_sem_time;
99 /* Obvious or linux kernel specific derived code follows: */
101 void acx_lock_unhold()
103 max_lock_time = 0;
106 void acx_sem_unhold()
108 max_sem_time = 0;
111 static inline const char *sanitize_str(const char *s)
113 const char *t = strrchr(s, '/');
114 if (t)
115 return t + 1;
116 return s;
119 void acx_lock_debug(acx_device_t * adev, const char *where)
121 unsigned int count = 100 * 1000 * 1000;
122 where = sanitize_str(where);
123 while (--count) {
124 if (!spin_is_locked(&adev->spinlock))
125 break;
126 cpu_relax();
128 if (!count) {
129 printk(KERN_EMERG "LOCKUP: already taken at %s!\n",
130 adev->last_lock);
131 BUG();
133 adev->last_lock = where;
134 rdtscl(adev->lock_time);
137 void acx_unlock_debug(acx_device_t * adev, const char *where)
139 #ifdef SMP
140 if (!spin_is_locked(&adev->spinlock)) {
141 where = sanitize_str(where);
142 printk(KERN_EMERG "STRAY UNLOCK at %s!\n", where);
143 BUG();
145 #endif
146 if (acx_debug & L_LOCK) {
147 unsigned long diff;
148 rdtscl(diff);
149 diff -= adev->lock_time;
150 if (diff > max_lock_time) {
151 where = sanitize_str(where);
152 printk("max lock hold time %ld CPU ticks from %s "
153 "to %s\n", diff, adev->last_lock, where);
154 max_lock_time = diff;
158 #endif /* PARANOID_LOCKING */
161 /***********************************************************************
163 #if ACX_DEBUG > 1
165 static int acx_debug_func_indent;
166 #define DEBUG_TSC 0
167 #define FUNC_INDENT_INCREMENT 2
169 #if DEBUG_TSC
170 #define TIMESTAMP(d) unsigned long d; rdtscl(d)
171 #else
172 #define TIMESTAMP(d) unsigned long d = jiffies
173 #endif
175 static const char spaces[] = " " " "; /* Nx10 spaces */
177 void log_fn_enter(const char *funcname)
179 int indent;
180 TIMESTAMP(d);
182 indent = acx_debug_func_indent;
183 if (indent >= sizeof(spaces))
184 indent = sizeof(spaces) - 1;
186 printk("%08ld %s==> %s\n",
187 d % 100000000, spaces + (sizeof(spaces) - 1) - indent, funcname);
189 acx_debug_func_indent += FUNC_INDENT_INCREMENT;
191 void log_fn_exit(const char *funcname)
193 int indent;
194 TIMESTAMP(d);
196 acx_debug_func_indent -= FUNC_INDENT_INCREMENT;
198 indent = acx_debug_func_indent;
199 if (indent >= sizeof(spaces))
200 indent = sizeof(spaces) - 1;
202 printk("%08ld %s<== %s\n",
203 d % 100000000, spaces + (sizeof(spaces) - 1) - indent, funcname);
205 void log_fn_exit_v(const char *funcname, int v)
207 int indent;
208 TIMESTAMP(d);
210 acx_debug_func_indent -= FUNC_INDENT_INCREMENT;
212 indent = acx_debug_func_indent;
213 if (indent >= sizeof(spaces))
214 indent = sizeof(spaces) - 1;
216 printk("%08ld %s<== %s: %08X\n",
217 d % 100000000,
218 spaces + (sizeof(spaces) - 1) - indent, funcname, v);
220 #endif /* ACX_DEBUG > 1 */
223 /***********************************************************************
224 ** Basically a mdelay/msleep with logging
226 void acx_s_mwait(int ms)
228 FN_ENTER;
229 #ifdef CONFIG_X86
230 mdelay(ms);
231 #else
232 msleep(ms);
233 #endif
234 FN_EXIT0;
238 /***********************************************************************
239 ** Not inlined: it's larger than it seems
241 void acx_print_mac(const char *head, const u8 * mac, const char *tail)
243 printk("%s" MACSTR "%s", head, MAC(mac), tail);
249 /***********************************************************************
250 ** acx_cmd_status_str
252 const char *acx_cmd_status_str(unsigned int state)
254 static const char *const cmd_error_strings[] = {
255 "Idle",
256 "Success",
257 "Unknown Command",
258 "Invalid Information Element",
259 "Channel rejected",
260 "Channel invalid in current regulatory domain",
261 "MAC invalid",
262 "Command rejected (read-only information element)",
263 "Command rejected",
264 "Already asleep",
265 "TX in progress",
266 "Already awake",
267 "Write only",
268 "RX in progress",
269 "Invalid parameter",
270 "Scan in progress",
271 "Failed"
273 return state < ARRAY_SIZE(cmd_error_strings) ?
274 cmd_error_strings[state] : "?";
277 /***********************************************************************
279 #if ACX_DEBUG
280 void acx_dump_bytes(const void *data, int num)
282 const u8 *ptr = (const u8 *)data;
284 FN_ENTER;
286 if (num <= 0) {
287 printk("\n");
288 return;
291 while (num >= 16) {
292 printk("%02X %02X %02X %02X %02X %02X %02X %02X "
293 "%02X %02X %02X %02X %02X %02X %02X %02X\n",
294 ptr[0], ptr[1], ptr[2], ptr[3],
295 ptr[4], ptr[5], ptr[6], ptr[7],
296 ptr[8], ptr[9], ptr[10], ptr[11],
297 ptr[12], ptr[13], ptr[14], ptr[15]);
298 num -= 16;
299 ptr += 16;
301 if (num > 0) {
302 while (--num > 0)
303 printk("%02X \n", *ptr++);
304 printk("%02X\n", *ptr);
307 FN_EXIT0;
310 #endif
313 /***********************************************************************
314 ** acx_s_get_firmware_version
316 ** Obvious
318 void acx_s_get_firmware_version(acx_device_t * adev)
320 fw_ver_t fw;
321 u8 hexarr[4] = { 0, 0, 0, 0 };
322 int hexidx = 0, val = 0;
323 const char *num;
324 char c;
326 FN_ENTER;
328 memset(fw.fw_id, 'E', FW_ID_SIZE);
329 acx_s_interrogate(adev, &fw, ACX1xx_IE_FWREV);
330 memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE);
331 adev->firmware_version[FW_ID_SIZE] = '\0';
333 log(L_DEBUG, "fw_ver: fw_id='%s' hw_id=%08X\n",
334 adev->firmware_version, fw.hw_id);
336 if (strncmp(fw.fw_id, "Rev ", 4) != 0) {
337 printk("acx: strange firmware version string "
338 "'%s', please report\n", adev->firmware_version);
339 adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */
340 } else {
341 num = &fw.fw_id[4];
342 while (1) {
343 c = *num++;
344 if ((c == '.') || (c == '\0')) {
345 hexarr[hexidx++] = val;
346 if ((hexidx > 3) || (c == '\0')) /* end? */
347 break;
348 val = 0;
349 continue;
351 if ((c >= '0') && (c <= '9'))
352 c -= '0';
353 else
354 c = c - 'a' + (char)10;
355 val = val * 16 + c;
358 adev->firmware_numver = (u32) ((hexarr[0] << 24) |
359 (hexarr[1] << 16)
360 | (hexarr[2] << 8) | hexarr[3]);
361 log(L_DEBUG, "firmware_numver 0x%08X\n", adev->firmware_numver);
363 if (IS_ACX111(adev)) {
364 if (adev->firmware_numver == 0x00010011) {
365 /* This one does not survive floodpinging */
366 printk("acx: firmware '%s' is known to be buggy, "
367 "please upgrade\n", adev->firmware_version);
371 adev->firmware_id = le32_to_cpu(fw.hw_id);
373 /* we're able to find out more detailed chip names now */
374 switch (adev->firmware_id & 0xffff0000) {
375 case 0x01010000:
376 case 0x01020000:
377 adev->chip_name = "TNETW1100A";
378 break;
379 case 0x01030000:
380 adev->chip_name = "TNETW1100B";
381 break;
382 case 0x03000000:
383 case 0x03010000:
384 adev->chip_name = "TNETW1130";
385 break;
386 case 0x04030000: /* 0x04030101 is TNETW1450 */
387 adev->chip_name = "TNETW1450";
388 break;
389 default:
390 printk("acx: unknown chip ID 0x%08X, "
391 "please report\n", adev->firmware_id);
392 break;
395 FN_EXIT0;
399 /***********************************************************************
400 ** acx_display_hardware_details
402 ** Displays hw/fw version, radio type etc...
404 ** Obvious
406 void acx_display_hardware_details(acx_device_t * adev)
408 const char *radio_str, *form_str;
410 FN_ENTER;
412 switch (adev->radio_type) {
413 case RADIO_MAXIM_0D:
414 radio_str = "Maxim";
415 break;
416 case RADIO_RFMD_11:
417 radio_str = "RFMD";
418 break;
419 case RADIO_RALINK_15:
420 radio_str = "Ralink";
421 break;
422 case RADIO_RADIA_16:
423 radio_str = "Radia";
424 break;
425 case RADIO_UNKNOWN_17:
426 /* TI seems to have a radio which is
427 * additionally 802.11a capable, too */
428 radio_str = "802.11a/b/g radio?! Please report";
429 break;
430 case RADIO_UNKNOWN_19:
431 radio_str = "A radio used by Safecom cards?! Please report";
432 break;
433 case RADIO_UNKNOWN_1B:
434 radio_str = "An unknown radio used by TNETW1450 USB adapters";
435 break;
436 default:
437 radio_str = "UNKNOWN, please report radio type name!";
438 break;
441 switch (adev->form_factor) {
442 case 0x00:
443 form_str = "unspecified";
444 break;
445 case 0x01:
446 form_str = "(mini-)PCI / CardBus";
447 break;
448 case 0x02:
449 form_str = "USB";
450 break;
451 case 0x03:
452 form_str = "Compact Flash";
453 break;
454 default:
455 form_str = "UNKNOWN, please report";
456 break;
459 printk("acx: chipset %s, radio type 0x%02X (%s), "
460 "form factor 0x%02X (%s), EEPROM version 0x%02X, "
461 "uploaded firmware '%s'\n",
462 adev->chip_name, adev->radio_type, radio_str,
463 adev->form_factor, form_str, adev->eeprom_version,
464 adev->firmware_version);
466 FN_EXIT0;
470 /***********************************************************************
471 ** acx_e_get_stats, acx_e_get_wireless_stats
474 acx_e_get_stats(struct ieee80211_hw *hw,
475 struct ieee80211_low_level_stats *stats)
477 acx_device_t *adev = ieee2adev(hw);
478 unsigned long flags;
479 acx_lock(adev, flags);
480 memcpy(stats, &adev->ieee_stats, sizeof(*stats));
481 acx_unlock(adev, flags);
482 return 0;
486 /***********************************************************************
487 ** maps acx111 tx descr rate field to acx100 one
489 const u8 acx_bitpos2rate100[] = {
490 RATE100_1, /* 0 */
491 RATE100_2, /* 1 */
492 RATE100_5, /* 2 */
493 RATE100_2, /* 3, should not happen */
494 RATE100_2, /* 4, should not happen */
495 RATE100_11, /* 5 */
496 RATE100_2, /* 6, should not happen */
497 RATE100_2, /* 7, should not happen */
498 RATE100_22, /* 8 */
499 RATE100_2, /* 9, should not happen */
500 RATE100_2, /* 10, should not happen */
501 RATE100_2, /* 11, should not happen */
502 RATE100_2, /* 12, should not happen */
503 RATE100_2, /* 13, should not happen */
504 RATE100_2, /* 14, should not happen */
505 RATE100_2, /* 15, should not happen */
508 u8 acx_rate111to100(u16 r)
510 return acx_bitpos2rate100[highest_bit(r)];
514 /***********************************************************************
515 ** Calculate level like the feb 2003 windows driver seems to do
517 static u8 acx_signal_to_winlevel(u8 rawlevel)
519 /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
520 u8 winlevel = ((4 + (rawlevel * 5)) / 8);
522 if (winlevel > 100)
523 winlevel = 100;
524 return winlevel;
527 u8 acx_signal_determine_quality(u8 signal, u8 noise)
529 int qual;
531 qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2;
533 if (qual > 100)
534 return 100;
535 if (qual < 0)
536 return 0;
537 return qual;
541 /***********************************************************************
542 ** Interrogate/configure commands
545 /* FIXME: the lengths given here probably aren't always correct.
546 * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4",
547 * unless the firmware actually expects a different length than the struct length */
548 static const u16 acx100_ie_len[] = {
550 ACX100_IE_ACX_TIMER_LEN,
551 sizeof(acx100_ie_powersave_t) - 4, /* is that 6 or 8??? */
552 ACX1xx_IE_QUEUE_CONFIG_LEN,
553 ACX100_IE_BLOCK_SIZE_LEN,
554 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
555 ACX1xx_IE_RATE_FALLBACK_LEN,
556 ACX100_IE_WEP_OPTIONS_LEN,
557 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
559 ACX1xx_IE_ASSOC_ID_LEN,
561 ACX111_IE_CONFIG_OPTIONS_LEN,
562 ACX1xx_IE_FWREV_LEN,
563 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
564 ACX1xx_IE_MEDIUM_USAGE_LEN,
565 ACX1xx_IE_RXCONFIG_LEN,
568 sizeof(fw_stats_t) - 4,
570 ACX1xx_IE_FEATURE_CONFIG_LEN,
571 ACX111_IE_KEY_CHOOSE_LEN,
572 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
573 ACX1FF_IE_WONE_CONFIG_LEN,
575 ACX1FF_IE_TID_CONFIG_LEN,
579 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
580 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
581 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
582 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
584 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
585 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
586 ACX1FF_IE_CCA_THRESHOLD_LEN,
587 ACX1FF_IE_EVENT_MASK_LEN,
588 ACX1FF_IE_DTIM_PERIOD_LEN,
590 ACX1FF_IE_ACI_CONFIG_SET_LEN,
597 ACX1FF_IE_EEPROM_VER_LEN,
600 static const u16 acx100_ie_len_dot11[] = {
602 ACX1xx_IE_DOT11_STATION_ID_LEN,
604 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
605 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
606 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
607 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
608 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
609 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
611 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
612 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
614 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
615 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
616 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
617 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
623 static const u16 acx111_ie_len[] = {
625 ACX100_IE_ACX_TIMER_LEN,
626 sizeof(acx111_ie_powersave_t) - 4,
627 ACX1xx_IE_QUEUE_CONFIG_LEN,
628 ACX100_IE_BLOCK_SIZE_LEN,
629 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
630 ACX1xx_IE_RATE_FALLBACK_LEN,
631 ACX100_IE_WEP_OPTIONS_LEN,
632 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
634 ACX1xx_IE_ASSOC_ID_LEN,
636 ACX111_IE_CONFIG_OPTIONS_LEN,
637 ACX1xx_IE_FWREV_LEN,
638 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
639 ACX1xx_IE_MEDIUM_USAGE_LEN,
640 ACX1xx_IE_RXCONFIG_LEN,
643 sizeof(fw_stats_t) - 4,
645 ACX1xx_IE_FEATURE_CONFIG_LEN,
646 ACX111_IE_KEY_CHOOSE_LEN,
647 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
648 ACX1FF_IE_WONE_CONFIG_LEN,
650 ACX1FF_IE_TID_CONFIG_LEN,
654 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
655 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
656 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
657 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
659 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
660 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
661 ACX1FF_IE_CCA_THRESHOLD_LEN,
662 ACX1FF_IE_EVENT_MASK_LEN,
663 ACX1FF_IE_DTIM_PERIOD_LEN,
665 ACX1FF_IE_ACI_CONFIG_SET_LEN,
672 ACX1FF_IE_EEPROM_VER_LEN,
675 static const u16 acx111_ie_len_dot11[] = {
677 ACX1xx_IE_DOT11_STATION_ID_LEN,
679 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
680 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
681 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
682 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
683 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
684 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
686 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
687 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
689 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
690 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
691 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
692 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
699 #undef FUNC
700 #define FUNC "configure"
701 #if !ACX_DEBUG
702 int acx_s_configure(acx_device_t * adev, void *pdr, int type)
704 #else
706 acx_s_configure_debug(acx_device_t * adev, void *pdr, int type,
707 const char *typestr)
709 #endif
710 u16 len;
711 int res;
713 if (type < 0x1000)
714 len = adev->ie_len[type];
715 else
716 len = adev->ie_len_dot11[type - 0x1000];
718 log(L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
719 if (unlikely(!len)) {
720 log(L_DEBUG, "zero-length type %s?!\n", typestr);
723 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
724 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
725 res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4);
726 if (unlikely(OK != res)) {
727 #if ACX_DEBUG
728 printk("%s: " FUNC "(type:%s) FAILED\n", wiphy_name(adev->ieee->wiphy),
729 typestr);
730 #else
731 printk("%s: " FUNC "(type:0x%X) FAILED\n", wiphy_name(adev->ieee->wiphy),
732 type);
733 #endif
734 /* dump_stack() is already done in issue_cmd() */
736 return res;
739 #undef FUNC
740 #define FUNC "interrogate"
741 #if !ACX_DEBUG
742 int acx_s_interrogate(acx_device_t * adev, void *pdr, int type)
744 #else
746 acx_s_interrogate_debug(acx_device_t * adev, void *pdr, int type,
747 const char *typestr)
749 #endif
750 u16 len;
751 int res;
753 FN_ENTER;
755 /* FIXME: no check whether this exceeds the array yet.
756 * We should probably remember the number of entries... */
757 if (type < 0x1000)
758 len = adev->ie_len[type];
759 else
760 len = adev->ie_len_dot11[type - 0x1000];
762 log(L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
764 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
765 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
766 res = acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, pdr, len + 4);
767 if (unlikely(OK != res)) {
768 #if ACX_DEBUG
769 printk("%s: " FUNC "(type:%s) FAILED\n", wiphy_name(adev->ieee->wiphy),
770 typestr);
771 #else
772 printk("%s: " FUNC "(type:0x%X) FAILED\n", wiphy_name(adev->ieee->wiphy),
773 type);
774 #endif
775 /* dump_stack() is already done in issue_cmd() */
778 FN_EXIT1(res);
779 return res;
782 #if CMD_DISCOVERY
783 void great_inquisitor(acx_device_t * adev)
785 static struct {
786 u16 type;
787 u16 len;
788 /* 0x200 was too large here: */
789 u8 data[0x100 - 4];
790 } ACX_PACKED ie;
791 u16 type;
793 FN_ENTER;
795 /* 0..0x20, 0x1000..0x1020 */
796 for (type = 0; type <= 0x1020; type++) {
797 if (type == 0x21)
798 type = 0x1000;
799 ie.type = cpu_to_le16(type);
800 ie.len = cpu_to_le16(sizeof(ie) - 4);
801 acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie));
803 FN_EXIT0;
805 #endif
808 #ifdef CONFIG_PROC_FS
809 /***********************************************************************
810 ** /proc files
812 /***********************************************************************
813 ** acx_l_proc_output
814 ** Generate content for our /proc entry
816 ** Arguments:
817 ** buf is a pointer to write output to
818 ** adev is the usual pointer to our private struct acx_device
819 ** Returns:
820 ** number of bytes actually written to buf
821 ** Side effects:
822 ** none
824 static int acx_l_proc_output(char *buf, acx_device_t * adev)
826 char *p = buf;
828 FN_ENTER;
830 p += sprintf(p,
831 "acx driver version:\t\t" ACX_RELEASE "\n"
832 "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n"
833 "chip name:\t\t\t%s (0x%08X)\n"
834 "radio type:\t\t\t0x%02X\n"
835 "form factor:\t\t\t0x%02X\n"
836 "EEPROM version:\t\t\t0x%02X\n"
837 "firmware version:\t\t%s (0x%08X)\n",
838 adev->chip_name, adev->firmware_id,
839 adev->radio_type,
840 adev->form_factor,
841 adev->eeprom_version,
842 adev->firmware_version, adev->firmware_numver);
844 FN_EXIT1(p - buf);
845 return p - buf;
849 /***********************************************************************
851 static int acx_s_proc_diag_output(char *buf, acx_device_t * adev)
853 char *p = buf;
854 unsigned long flags;
855 unsigned int len = 0, partlen;
856 u32 temp1, temp2;
857 u8 *st, *st_end;
858 #ifdef __BIG_ENDIAN
859 u8 *st2;
860 #endif
861 fw_stats_t *fw_stats;
862 char *part_str = NULL;
863 fw_stats_tx_t *tx = NULL;
864 fw_stats_rx_t *rx = NULL;
865 fw_stats_dma_t *dma = NULL;
866 fw_stats_irq_t *irq = NULL;
867 fw_stats_wep_t *wep = NULL;
868 fw_stats_pwr_t *pwr = NULL;
869 fw_stats_mic_t *mic = NULL;
870 fw_stats_aes_t *aes = NULL;
871 fw_stats_event_t *evt = NULL;
873 FN_ENTER;
875 acx_lock(adev, flags);
877 if (IS_PCI(adev))
878 p = acxpci_s_proc_diag_output(p, adev);
880 p += sprintf(p,
881 "\n"
882 "** network status **\n"
883 "dev_state_mask 0x%04X\n"
884 "mode %u, channel %u, "
885 "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
886 adev->dev_state_mask,
887 adev->mode, adev->channel,
888 adev->reg_dom_id, adev->reg_dom_chanmask);
889 p += sprintf(p,
890 "ESSID \"%s\", essid_active %d, essid_len %d, "
891 "essid_for_assoc \"%s\", nick \"%s\"\n"
892 "WEP ena %d, restricted %d, idx %d\n",
893 adev->essid, adev->essid_active, (int)adev->essid_len,
894 adev->essid_for_assoc, adev->nick,
895 adev->wep_enabled, adev->wep_restricted,
896 adev->wep_current_index);
897 p += sprintf(p, "dev_addr " MACSTR "\n", MAC(adev->dev_addr));
898 p += sprintf(p, "bssid " MACSTR "\n", MAC(adev->bssid));
899 p += sprintf(p, "ap_filter " MACSTR "\n", MAC(adev->ap));
901 p += sprintf(p, "\n" "** PHY status **\n"
902 "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
903 "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
904 "rate_basic 0x%04X, rate_oper 0x%04X\n"
905 "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
906 "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
907 adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */
908 adev->sensitivity, adev->antenna, adev->ed_threshold,
909 adev->cca, adev->preamble_mode, adev->rate_basic, adev->rate_oper, adev->rts_threshold,
910 adev->frag_threshold, adev->short_retry, adev->long_retry,
911 adev->msdu_lifetime, adev->listen_interval,
912 adev->beacon_interval);
914 acx_unlock(adev, flags);
916 p += sprintf(p,
917 "\n"
918 "** Firmware **\n"
919 "NOTE: version dependent statistics layout, "
920 "please report if you suspect wrong parsing!\n"
921 "\n" "version \"%s\"\n", adev->firmware_version);
923 /* TODO: may replace kmalloc/memset with kzalloc once
924 * Linux 2.6.14 is widespread */
925 fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL);
926 if (!fw_stats) {
927 FN_EXIT1(0);
928 return 0;
930 memset(fw_stats, 0, sizeof(*fw_stats));
932 st = (u8 *) fw_stats;
934 part_str = "statistics query command";
936 if (OK != acx_s_interrogate(adev, st, ACX1xx_IE_FIRMWARE_STATISTICS))
937 goto fw_stats_end;
939 st += sizeof(u16);
940 len = *(u16 *) st;
942 if (len > sizeof(*fw_stats)) {
943 p += sprintf(p,
944 "firmware version with bigger fw_stats struct detected\n"
945 "(%u vs. %u), please report\n", len,
946 sizeof(fw_stats_t));
947 if (len > sizeof(*fw_stats)) {
948 p += sprintf(p, "struct size exceeded allocation!\n");
949 len = sizeof(*fw_stats);
952 st += sizeof(u16);
953 st_end = st - 2 * sizeof(u16) + len;
955 #ifdef __BIG_ENDIAN
956 /* let's make one bold assumption here:
957 * (hopefully!) *all* statistics fields are u32 only,
958 * thus if we need to make endianness corrections
959 * we can simply do them in one go, in advance */
960 st2 = (u8 *) fw_stats;
961 for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4)
962 *(u32 *) st2 = le32_to_cpu(*(u32 *) st2);
963 #endif
965 part_str = "Rx/Tx";
967 /* directly at end of a struct part? --> no error! */
968 if (st == st_end)
969 goto fw_stats_end;
971 tx = (fw_stats_tx_t *) st;
972 st += sizeof(fw_stats_tx_t);
973 rx = (fw_stats_rx_t *) st;
974 st += sizeof(fw_stats_rx_t);
975 partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t);
977 if (IS_ACX100(adev)) {
978 /* at least ACX100 PCI F/W 1.9.8.b
979 * and ACX100 USB F/W 1.0.7-USB
980 * don't have those two fields... */
981 st -= 2 * sizeof(u32);
983 /* our parsing doesn't quite match this firmware yet,
984 * log failure */
985 if (st > st_end)
986 goto fw_stats_fail;
987 temp1 = temp2 = 999999999;
988 } else {
989 if (st > st_end)
990 goto fw_stats_fail;
991 temp1 = rx->rx_aci_events;
992 temp2 = rx->rx_aci_resets;
995 p += sprintf(p,
996 "%s:\n"
997 " tx_desc_overfl %u\n"
998 " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
999 " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n"
1000 " rx_aci_events %u, rx_aci_resets %u\n",
1001 part_str,
1002 tx->tx_desc_of,
1003 rx->rx_oom,
1004 rx->rx_hdr_of,
1005 rx->rx_hw_stuck,
1006 rx->rx_dropped_frame,
1007 rx->rx_frame_ptr_err, rx->rx_xfr_hint_trig, temp1, temp2);
1009 part_str = "DMA";
1011 if (st == st_end)
1012 goto fw_stats_end;
1014 dma = (fw_stats_dma_t *) st;
1015 partlen = sizeof(fw_stats_dma_t);
1016 st += partlen;
1018 if (st > st_end)
1019 goto fw_stats_fail;
1021 p += sprintf(p,
1022 "%s:\n"
1023 " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n",
1024 part_str,
1025 dma->rx_dma_req,
1026 dma->rx_dma_err, dma->tx_dma_req, dma->tx_dma_err);
1028 part_str = "IRQ";
1030 if (st == st_end)
1031 goto fw_stats_end;
1033 irq = (fw_stats_irq_t *) st;
1034 partlen = sizeof(fw_stats_irq_t);
1035 st += partlen;
1037 if (st > st_end)
1038 goto fw_stats_fail;
1040 p += sprintf(p,
1041 "%s:\n"
1042 " cmd_cplt %u, fiq %u\n"
1043 " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
1044 " irqs %u, tx_procs %u, decrypt_done %u\n"
1045 " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
1046 " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
1047 " host_acks %u, pci_pm %u, acm_wakeups %u\n",
1048 part_str,
1049 irq->cmd_cplt,
1050 irq->fiq,
1051 irq->rx_hdrs,
1052 irq->rx_cmplt,
1053 irq->rx_mem_of,
1054 irq->rx_rdys,
1055 irq->irqs,
1056 irq->tx_procs,
1057 irq->decrypt_done,
1058 irq->dma_0_done,
1059 irq->dma_1_done,
1060 irq->tx_exch_complet,
1061 irq->commands,
1062 irq->rx_procs,
1063 irq->hw_pm_mode_changes,
1064 irq->host_acks, irq->pci_pm, irq->acm_wakeups);
1066 part_str = "WEP";
1068 if (st == st_end)
1069 goto fw_stats_end;
1071 wep = (fw_stats_wep_t *) st;
1072 partlen = sizeof(fw_stats_wep_t);
1073 st += partlen;
1075 if ((IS_PCI(adev) && IS_ACX100(adev))
1076 || (IS_USB(adev) && IS_ACX100(adev))
1078 /* at least ACX100 PCI F/W 1.9.8.b
1079 * and ACX100 USB F/W 1.0.7-USB
1080 * don't have those two fields... */
1081 st -= 2 * sizeof(u32);
1082 if (st > st_end)
1083 goto fw_stats_fail;
1084 temp1 = temp2 = 999999999;
1085 } else {
1086 if (st > st_end)
1087 goto fw_stats_fail;
1088 temp1 = wep->wep_pkt_decrypt;
1089 temp2 = wep->wep_decrypt_irqs;
1092 p += sprintf(p,
1093 "%s:\n"
1094 " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
1095 " wep_key_not_found %u, wep_decrypt_fail %u\n"
1096 " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
1097 part_str,
1098 wep->wep_key_count,
1099 wep->wep_default_key_count,
1100 wep->dot11_def_key_mib,
1101 wep->wep_key_not_found,
1102 wep->wep_decrypt_fail, temp1, temp2);
1104 part_str = "power";
1106 if (st == st_end)
1107 goto fw_stats_end;
1109 pwr = (fw_stats_pwr_t *) st;
1110 partlen = sizeof(fw_stats_pwr_t);
1111 st += partlen;
1113 if (st > st_end)
1114 goto fw_stats_fail;
1116 p += sprintf(p,
1117 "%s:\n"
1118 " tx_start_ctr %u, no_ps_tx_too_short %u\n"
1119 " rx_start_ctr %u, no_ps_rx_too_short %u\n"
1120 " lppd_started %u\n"
1121 " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n",
1122 part_str,
1123 pwr->tx_start_ctr,
1124 pwr->no_ps_tx_too_short,
1125 pwr->rx_start_ctr,
1126 pwr->no_ps_rx_too_short,
1127 pwr->lppd_started,
1128 pwr->no_lppd_too_noisy,
1129 pwr->no_lppd_too_short, pwr->no_lppd_matching_frame);
1131 part_str = "MIC";
1133 if (st == st_end)
1134 goto fw_stats_end;
1136 mic = (fw_stats_mic_t *) st;
1137 partlen = sizeof(fw_stats_mic_t);
1138 st += partlen;
1140 if (st > st_end)
1141 goto fw_stats_fail;
1143 p += sprintf(p,
1144 "%s:\n"
1145 " mic_rx_pkts %u, mic_calc_fail %u\n",
1146 part_str, mic->mic_rx_pkts, mic->mic_calc_fail);
1148 part_str = "AES";
1150 if (st == st_end)
1151 goto fw_stats_end;
1153 aes = (fw_stats_aes_t *) st;
1154 partlen = sizeof(fw_stats_aes_t);
1155 st += partlen;
1157 if (st > st_end)
1158 goto fw_stats_fail;
1160 p += sprintf(p,
1161 "%s:\n"
1162 " aes_enc_fail %u, aes_dec_fail %u\n"
1163 " aes_enc_pkts %u, aes_dec_pkts %u\n"
1164 " aes_enc_irq %u, aes_dec_irq %u\n",
1165 part_str,
1166 aes->aes_enc_fail,
1167 aes->aes_dec_fail,
1168 aes->aes_enc_pkts,
1169 aes->aes_dec_pkts, aes->aes_enc_irq, aes->aes_dec_irq);
1171 part_str = "event";
1173 if (st == st_end)
1174 goto fw_stats_end;
1176 evt = (fw_stats_event_t *) st;
1177 partlen = sizeof(fw_stats_event_t);
1178 st += partlen;
1180 if (st > st_end)
1181 goto fw_stats_fail;
1183 p += sprintf(p,
1184 "%s:\n"
1185 " heartbeat %u, calibration %u\n"
1186 " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
1187 " oom_late %u\n"
1188 " phy_tx_err %u, tx_stuck %u\n",
1189 part_str,
1190 evt->heartbeat,
1191 evt->calibration,
1192 evt->rx_mismatch,
1193 evt->rx_mem_empty,
1194 evt->rx_pool,
1195 evt->oom_late, evt->phy_tx_err, evt->tx_stuck);
1197 if (st < st_end)
1198 goto fw_stats_bigger;
1200 goto fw_stats_end;
1202 fw_stats_fail:
1203 st -= partlen;
1204 p += sprintf(p,
1205 "failed at %s part (size %u), offset %u (struct size %u), "
1206 "please report\n", part_str, partlen,
1207 (int)((void *)st - (void *)fw_stats), len);
1209 fw_stats_bigger:
1210 for (; st < st_end; st += 4)
1211 p += sprintf(p,
1212 "UNKN%3d: %u\n",
1213 (int)((void *)st - (void *)fw_stats), *(u32 *) st);
1215 fw_stats_end:
1216 kfree(fw_stats);
1218 FN_EXIT1(p - buf);
1219 return p - buf;
1223 /***********************************************************************
1225 static int acx_s_proc_phy_output(char *buf, acx_device_t * adev)
1227 char *p = buf;
1228 int i;
1230 FN_ENTER;
1233 if (RADIO_RFMD_11 != adev->radio_type) {
1234 printk("sorry, not yet adapted for radio types "
1235 "other than RFMD, please verify "
1236 "PHY size etc. first!\n");
1237 goto end;
1241 /* The PHY area is only 0x80 bytes long; further pages after that
1242 * only have some page number registers with altered value,
1243 * all other registers remain the same. */
1244 for (i = 0; i < 0x80; i++) {
1245 acx_s_read_phy_reg(adev, i, p++);
1248 FN_EXIT1(p - buf);
1249 return p - buf;
1253 /***********************************************************************
1254 ** acx_e_read_proc_XXXX
1255 ** Handle our /proc entry
1257 ** Arguments:
1258 ** standard kernel read_proc interface
1259 ** Returns:
1260 ** number of bytes written to buf
1261 ** Side effects:
1262 ** none
1264 static int
1265 acx_e_read_proc(char *buf, char **start, off_t offset, int count,
1266 int *eof, void *data)
1268 acx_device_t *adev = (acx_device_t *) data;
1269 unsigned long flags;
1270 int length;
1272 FN_ENTER;
1274 acx_sem_lock(adev);
1275 acx_lock(adev, flags);
1276 /* fill buf */
1277 length = acx_l_proc_output(buf, adev);
1278 acx_unlock(adev, flags);
1279 acx_sem_unlock(adev);
1281 /* housekeeping */
1282 if (length <= offset + count)
1283 *eof = 1;
1284 *start = buf + offset;
1285 length -= offset;
1286 if (length > count)
1287 length = count;
1288 if (length < 0)
1289 length = 0;
1290 FN_EXIT1(length);
1291 return length;
1294 static int
1295 acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count,
1296 int *eof, void *data)
1298 acx_device_t *adev = (acx_device_t *) data;
1299 int length;
1301 FN_ENTER;
1303 acx_sem_lock(adev);
1304 /* fill buf */
1305 length = acx_s_proc_diag_output(buf, adev);
1306 acx_sem_unlock(adev);
1308 /* housekeeping */
1309 if (length <= offset + count)
1310 *eof = 1;
1311 *start = buf + offset;
1312 length -= offset;
1313 if (length > count)
1314 length = count;
1315 if (length < 0)
1316 length = 0;
1317 FN_EXIT1(length);
1318 return length;
1321 static int
1322 acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count,
1323 int *eof, void *data)
1325 acx_device_t *adev = (acx_device_t *) data;
1326 int length;
1328 FN_ENTER;
1330 /* fill buf */
1331 length = 0;
1332 if (IS_PCI(adev)) {
1333 acx_sem_lock(adev);
1334 length = acxpci_proc_eeprom_output(buf, adev);
1335 acx_sem_unlock(adev);
1338 /* housekeeping */
1339 if (length <= offset + count)
1340 *eof = 1;
1341 *start = buf + offset;
1342 length -= offset;
1343 if (length > count)
1344 length = count;
1345 if (length < 0)
1346 length = 0;
1347 FN_EXIT1(length);
1348 return length;
1351 static int
1352 acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count,
1353 int *eof, void *data)
1355 acx_device_t *adev = (acx_device_t *) data;
1356 int length;
1358 FN_ENTER;
1360 acx_sem_lock(adev);
1361 /* fill buf */
1362 length = acx_s_proc_phy_output(buf, adev);
1363 acx_sem_unlock(adev);
1365 /* housekeeping */
1366 if (length <= offset + count)
1367 *eof = 1;
1368 *start = buf + offset;
1369 length -= offset;
1370 if (length > count)
1371 length = count;
1372 if (length < 0)
1373 length = 0;
1374 FN_EXIT1(length);
1375 return length;
1379 /***********************************************************************
1380 ** /proc files registration
1382 static const char *const
1383 proc_files[] = { "", "_diag", "_eeprom", "_phy" };
1385 static read_proc_t *const
1386 proc_funcs[] = {
1387 acx_e_read_proc,
1388 acx_e_read_proc_diag,
1389 acx_e_read_proc_eeprom,
1390 acx_e_read_proc_phy
1393 static int manage_proc_entries(struct ieee80211_hw *hw, int remove)
1395 acx_device_t *adev = ieee2adev(hw);
1396 char procbuf[80];
1397 int i;
1399 FN_ENTER;
1401 for (i = 0; i < ARRAY_SIZE(proc_files); i++) {
1402 snprintf(procbuf, sizeof(procbuf),
1403 "driver/acx%s", proc_files[i]);
1404 log(L_INIT, "%sing /proc entry %s\n",
1405 remove ? "remov" : "creat", procbuf);
1406 if (!remove) {
1407 if (!create_proc_read_entry
1408 (procbuf, 0, NULL, proc_funcs[i], adev)) {
1409 printk("acx: cannot register /proc entry %s\n",
1410 procbuf);
1411 FN_EXIT1(NOT_OK);
1412 return NOT_OK;
1414 } else {
1415 remove_proc_entry(procbuf, NULL);
1418 FN_EXIT0;
1419 return OK;
1422 int acx_proc_register_entries(struct ieee80211_hw *ieee)
1424 return manage_proc_entries(ieee, 0);
1427 int acx_proc_unregister_entries(struct ieee80211_hw *ieee)
1429 return manage_proc_entries(ieee, 1);
1431 #endif /* CONFIG_PROC_FS */
1433 /****
1434 ** Gathered From rt2x00 and bcm43xx_mac80211 projects
1436 void acx_free_modes(acx_device_t * adev)
1439 // kfree(adev->modes);
1440 // adev->modes = NULL;
1444 #define RATETAB_ENT(_rate, _rateid, _flags) \
1446 .rate = (_rate), \
1447 .val = (_rateid), \
1448 .val2 = (_rateid), \
1449 .flags = (_flags), \
1453 static struct ieee80211_rate __acx_rates[] = {
1454 { .rate = 10,
1455 .val = RATE111_1,
1456 .flags = IEEE80211_RATE_CCK },
1457 { .rate = 20,
1458 .val = RATE111_2,
1459 .flags = IEEE80211_RATE_CCK },
1460 { .rate = 55,
1461 .val = RATE111_5,
1462 .flags = IEEE80211_RATE_CCK },
1463 { .rate = 110,
1464 .val = RATE111_11,
1465 .flags = IEEE80211_RATE_CCK },
1466 { .rate = 60,
1467 .val = RATE111_6,
1468 .flags = IEEE80211_RATE_OFDM },
1469 { .rate = 90,
1470 .val = RATE111_9,
1471 .flags = IEEE80211_RATE_OFDM },
1472 { .rate = 120,
1473 .val = RATE111_12,
1474 .flags = IEEE80211_RATE_OFDM },
1475 { .rate = 180,
1476 .val = RATE111_18,
1477 .flags = IEEE80211_RATE_OFDM },
1478 { .rate = 240,
1479 .val = RATE111_24,
1480 .flags = IEEE80211_RATE_OFDM },
1481 { .rate = 360,
1482 .val = RATE111_36,
1483 .flags = IEEE80211_RATE_OFDM },
1484 { .rate = 480,
1485 .val = RATE111_48,
1486 .flags = IEEE80211_RATE_OFDM },
1487 { .rate = 540,
1488 .val = RATE111_54,
1489 .flags = IEEE80211_RATE_OFDM },
1492 #define acx_b_ratetable (__acx_rates + 0)
1493 #define acx_g_ratetable (__acx_rates + 0)
1496 #define CHANTAB_ENT(_chanid, _freq) \
1498 .chan = (_chanid), \
1499 .freq = (_freq), \
1500 .val = (_chanid), \
1501 .flag = IEEE80211_CHAN_W_SCAN | \
1502 IEEE80211_CHAN_W_ACTIVE_SCAN | \
1503 IEEE80211_CHAN_W_IBSS, \
1504 .power_level = 0xf, \
1505 .antenna_max = 0xFF, \
1508 static struct ieee80211_channel channels[] = {
1509 { .chan = 1,
1510 .freq = 2412},
1511 { .chan = 2,
1512 .freq = 2417},
1513 { .chan = 3,
1514 .freq = 2422},
1515 { .chan = 4,
1516 .freq = 2427},
1517 { .chan = 5,
1518 .freq = 2432},
1519 { .chan = 6,
1520 .freq = 2437},
1521 { .chan = 7,
1522 .freq = 2442},
1523 { .chan = 8,
1524 .freq = 2447},
1525 { .chan = 9,
1526 .freq = 2452},
1527 { .chan = 10,
1528 .freq = 2457},
1529 { .chan = 11,
1530 .freq = 2462},
1531 { .chan = 12,
1532 .freq = 2467},
1533 { .chan = 13,
1534 .freq = 2472},
1538 static int acx_setup_modes_bphy(acx_device_t * adev)
1540 int err = 0;
1541 struct ieee80211_hw *hw = adev->ieee;
1542 struct ieee80211_hw_mode *mode;
1544 FN_ENTER;
1546 mode = &adev->modes[0];
1547 mode->mode = MODE_IEEE80211B;
1548 mode->num_channels = acx_chantable_size;
1549 mode->channels = channels;
1550 mode->num_rates = acx_b_ratetable_size;
1551 mode->rates = acx_b_ratetable;
1552 err = ieee80211_register_hwmode(hw,mode);
1554 FN_EXIT1(err);
1555 return err;
1558 static int acx_setup_modes_gphy(acx_device_t * adev)
1560 int err = 0;
1561 struct ieee80211_hw *hw = adev->ieee;
1562 struct ieee80211_hw_mode *mode;
1564 FN_ENTER;
1566 mode = &adev->modes[1];
1567 mode->mode = MODE_IEEE80211G;
1568 mode->num_channels = acx_chantable_size;
1569 mode->channels = channels;
1570 mode->num_rates = acx_g_ratetable_size;
1571 mode->rates = acx_g_ratetable;
1572 err = ieee80211_register_hwmode(hw,mode);
1574 FN_EXIT1(err);
1575 return err;
1579 int acx_setup_modes(acx_device_t * adev)
1581 struct ieee80211_hw *hw = adev->ieee;
1582 struct ieee80211_hw_mode *mode;
1583 int err = -ENOMEM;
1585 FN_ENTER;
1587 if (IS_ACX111(adev)) {
1589 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);
1590 err = acx_setup_modes_gphy(adev);
1592 mode = &adev->modes[0];
1594 /* from the zd1211rw driver: - do we need to do the same? */
1596 memcpy(mode->channels, channels, sizeof(channels));
1597 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1600 mode->mode = MODE_IEEE80211G;
1601 mode->num_channels = ARRAY_SIZE(channels);
1602 mode->num_rates = 12;
1603 mode->rates = acx_g_ratetable;
1604 } else {
1606 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1607 err = acx_setup_modes_bphy(adev);
1609 mode = &adev->modes[1];
1611 /* from the zd1211rw driver: - do we need to do the same? */
1613 memcpy(mode->channels, channels, sizeof(channels));
1614 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1617 mode->mode = MODE_IEEE80211B;
1618 mode->num_channels = ARRAY_SIZE(channels);
1619 mode->num_rates = 4;
1620 mode->rates = acx_b_ratetable;
1623 /* if (err && adev->modes)
1624 kfree(adev->modes);*/
1626 mode->channels = channels;
1627 err = ieee80211_register_hwmode(hw,mode);
1629 FN_EXIT1(err);
1630 return err;
1634 /***********************************************************************
1635 ** acx_fill_beacon_or_proberesp_template
1637 ** Origin: derived from rt2x00 project
1639 static int
1640 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1641 struct acx_template_beacon *templ,
1642 struct sk_buff* skb /* in host order! */)
1644 FN_ENTER;
1646 memcpy(templ,skb->data, skb->len);
1647 FN_EXIT1(skb->len);
1648 return skb->len;
1651 /***********************************************************************
1652 ** acx_s_set_beacon_template
1656 static int
1657 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1659 struct acx_template_beacon bcn;
1660 int len, result;
1662 FN_ENTER;
1663 printk("Size of template: %08X, Size of beacon: %08X\n",sizeof(struct acx_template_beacon),skb->len);
1664 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1665 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1667 FN_EXIT1(result);
1668 return result;
1671 /***********************************************************************
1672 ** acx_cmd_join_bssid
1674 ** Common code for both acx100 and acx111.
1676 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1677 static const u8 bitpos2genframe_txrate[] = {
1678 10, /* 0. 1 Mbit/s */
1679 20, /* 1. 2 Mbit/s */
1680 55, /* 2. 5.5 Mbit/s */
1681 0x0B, /* 3. 6 Mbit/s */
1682 0x0F, /* 4. 9 Mbit/s */
1683 110, /* 5. 11 Mbit/s */
1684 0x0A, /* 6. 12 Mbit/s */
1685 0x0E, /* 7. 18 Mbit/s */
1686 220, /* 8. 22 Mbit/s */
1687 0x09, /* 9. 24 Mbit/s */
1688 0x0D, /* 10. 36 Mbit/s */
1689 0x08, /* 11. 48 Mbit/s */
1690 0x0C, /* 12. 54 Mbit/s */
1691 10, /* 13. 1 Mbit/s, should never happen */
1692 10, /* 14. 1 Mbit/s, should never happen */
1693 10, /* 15. 1 Mbit/s, should never happen */
1696 /* Looks scary, eh?
1697 ** Actually, each one compiled into one AND and one SHIFT,
1698 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1699 static inline unsigned int rate111to5bits(unsigned int rate)
1701 return (rate & 0x7)
1702 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1703 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1707 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1709 acx_joinbss_t tmp;
1710 int dtim_interval;
1711 int i;
1713 if (mac_is_zero(bssid))
1714 return;
1716 FN_ENTER;
1718 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1719 1 : adev->dtim_interval;
1721 memset(&tmp, 0, sizeof(tmp));
1723 for (i = 0; i < ETH_ALEN; i++) {
1724 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1727 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1729 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1730 ** are sent with one of these rates */
1731 if (IS_ACX111(adev)) {
1732 /* It was experimentally determined that rates_basic
1733 ** can take 11g rates as well, not only rates
1734 ** defined with JOINBSS_RATES_BASIC111_nnn.
1735 ** Just use RATE111_nnn constants... */
1736 tmp.u.acx111.dtim_interval = dtim_interval;
1737 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1738 log(L_ASSOC, "rates_basic:%04X, rates_supported:%04X\n",
1739 adev->rate_basic, adev->rate_oper);
1740 } else {
1741 tmp.u.acx100.dtim_interval = dtim_interval;
1742 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1743 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1744 log(L_ASSOC, "rates_basic:%04X->%02X, "
1745 "rates_supported:%04X->%02X\n",
1746 adev->rate_basic, tmp.u.acx100.rates_basic,
1747 adev->rate_oper, tmp.u.acx100.rates_supported);
1750 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1751 ** will be sent (rate/modulation/preamble) */
1752 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1753 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1754 /* we can use short pre *if* all peers can understand it */
1755 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1757 /* we switch fw to STA mode in MONITOR mode, it seems to be
1758 ** the only mode where fw does not emit beacons by itself
1759 ** but allows us to send anything (we really want to retain
1760 ** ability to tx arbitrary frames in MONITOR mode)
1762 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1763 tmp.channel = adev->channel;
1764 tmp.essid_len = adev->essid_len;
1766 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1767 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1769 log(L_ASSOC|L_DEBUG, "BSS_Type = %u\n", tmp.macmode);
1770 acxlog_mac(L_ASSOC|L_DEBUG, "JoinBSSID MAC:", adev->bssid, "\n");
1772 /* acx_update_capabilities(adev); */
1773 FN_EXIT0;
1776 /***********************************************************************
1777 ** acxpci_i_set_multicast_list
1778 ** FIXME: most likely needs refinement
1781 void acx_i_set_multicast_list(struct ieee80211_hw *hw,
1782 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1783 unsigned short netflags, int mc_count)
1784 #else
1785 unsigned int changed_flags,
1786 unsigned int *total_flags,
1787 int mc_count, struct dev_addr_list *mc_list)
1788 #endif
1790 acx_device_t *adev = ieee2adev(hw);
1791 unsigned long flags;
1793 FN_ENTER;
1795 acx_lock(adev, flags);
1797 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
1798 changed_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1799 FIF_CONTROL | FIF_OTHER_BSS);
1800 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1801 FIF_CONTROL | FIF_OTHER_BSS);
1802 /* if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1803 return; */
1804 #endif
1806 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1807 if (netflags & (IFF_PROMISC | IFF_ALLMULTI)) {
1808 #else
1809 if (*total_flags) {
1810 #endif
1811 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1812 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1813 SET_BIT(adev->set_mask, SET_RXCONFIG);
1814 /* let kernel know in case *we* needed to set promiscuous */
1815 } else {
1816 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1817 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1818 SET_BIT(adev->set_mask, SET_RXCONFIG);
1821 /* cannot update card settings directly here, atomic context */
1822 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
1824 acx_unlock(adev, flags);
1826 FN_EXIT0;
1829 /***********************************************************************
1830 ** acx111 feature config
1832 ** Obvious
1834 static int
1835 acx111_s_get_feature_config(acx_device_t * adev,
1836 u32 * feature_options, u32 * data_flow_options)
1838 struct acx111_ie_feature_config feat;
1840 FN_ENTER;
1842 if (!IS_ACX111(adev)) {
1843 return NOT_OK;
1846 memset(&feat, 0, sizeof(feat));
1848 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1849 FN_EXIT1(NOT_OK);
1850 return NOT_OK;
1852 log(L_DEBUG,
1853 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1854 feat.feature_options, feat.data_flow_options);
1856 if (feature_options)
1857 *feature_options = le32_to_cpu(feat.feature_options);
1858 if (data_flow_options)
1859 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1861 FN_EXIT0;
1862 return OK;
1866 static int
1867 acx111_s_set_feature_config(acx_device_t * adev,
1868 u32 feature_options, u32 data_flow_options,
1869 unsigned int mode
1870 /* 0 == remove, 1 == add, 2 == set */ )
1872 struct acx111_ie_feature_config feat;
1874 FN_ENTER;
1876 if (!IS_ACX111(adev)) {
1877 FN_EXIT1(NOT_OK);
1878 return NOT_OK;
1881 if ((mode < 0) || (mode > 2)) {
1882 FN_EXIT1(NOT_OK);
1883 return NOT_OK;
1886 if (mode != 2)
1887 /* need to modify old data */
1888 acx111_s_get_feature_config(adev, &feat.feature_options,
1889 &feat.data_flow_options);
1890 else {
1891 /* need to set a completely new value */
1892 feat.feature_options = 0;
1893 feat.data_flow_options = 0;
1896 if (mode == 0) { /* remove */
1897 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1898 CLEAR_BIT(feat.data_flow_options,
1899 cpu_to_le32(data_flow_options));
1900 } else { /* add or set */
1901 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1902 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1905 log(L_DEBUG,
1906 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1907 "new: feature 0x%08X dataflow 0x%08X\n",
1908 feature_options, data_flow_options, mode,
1909 le32_to_cpu(feat.feature_options),
1910 le32_to_cpu(feat.data_flow_options));
1912 if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1913 FN_EXIT1(NOT_OK);
1914 return NOT_OK;
1917 FN_EXIT0;
1918 return OK;
1921 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1923 return acx111_s_set_feature_config(adev, f, d, 0);
1925 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1927 return acx111_s_set_feature_config(adev, f, d, 1);
1929 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1931 return acx111_s_set_feature_config(adev, f, d, 2);
1935 /***********************************************************************
1936 ** acx100_s_init_memory_pools
1938 static int
1939 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1941 acx100_ie_memblocksize_t MemoryBlockSize;
1942 acx100_ie_memconfigoption_t MemoryConfigOption;
1943 int TotalMemoryBlocks;
1944 int RxBlockNum;
1945 int TotalRxBlockSize;
1946 int TxBlockNum;
1947 int TotalTxBlockSize;
1949 FN_ENTER;
1951 /* Let's see if we can follow this:
1952 first we select our memory block size (which I think is
1953 completely arbitrary) */
1954 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1956 /* Then we alert the card to our decision of block size */
1957 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
1958 goto bad;
1961 /* We figure out how many total blocks we can create, using
1962 the block size we chose, and the beginning and ending
1963 memory pointers, i.e.: end-start/size */
1964 TotalMemoryBlocks =
1965 (le32_to_cpu(mmt->PoolEnd) -
1966 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1968 log(L_DEBUG, "TotalMemoryBlocks=%u (%u bytes)\n",
1969 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1971 /* MemoryConfigOption.DMA_config bitmask:
1972 access to ACX memory is to be done:
1973 0x00080000 using PCI conf space?!
1974 0x00040000 using IO instructions?
1975 0x00000000 using memory access instructions
1976 0x00020000 using local memory block linked list (else what?)
1977 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1979 if (IS_PCI(adev)) {
1980 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1981 /* Declare start of the Rx host pool */
1982 MemoryConfigOption.pRxHostDesc =
1983 cpu2acx(adev->rxhostdesc_startphy);
1984 log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
1985 acx2cpu(MemoryConfigOption.pRxHostDesc),
1986 (long)adev->rxhostdesc_startphy);
1987 } else {
1988 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1991 /* 50% of the allotment of memory blocks go to tx descriptors */
1992 TxBlockNum = TotalMemoryBlocks / 2;
1993 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1995 /* and 50% go to the rx descriptors */
1996 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1997 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1999 /* size of the tx and rx descriptor queues */
2000 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
2001 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
2002 log(L_DEBUG, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u "
2003 "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum,
2004 TotalTxBlockSize, TotalRxBlockSize);
2007 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
2008 MemoryConfigOption.rx_mem =
2009 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
2011 /* align the rx descriptor queue to units of 0x20
2012 * and offset it by the tx descriptor queue */
2013 MemoryConfigOption.tx_mem =
2014 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
2015 0x1f) & ~0x1f);
2016 log(L_DEBUG, "rx_mem %08X rx_mem %08X\n", MemoryConfigOption.tx_mem,
2017 MemoryConfigOption.rx_mem);
2019 /* alert the device to our decision */
2020 if (OK !=
2021 acx_s_configure(adev, &MemoryConfigOption,
2022 ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
2023 goto bad;
2026 /* and tell the device to kick it into gear */
2027 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
2028 goto bad;
2030 FN_EXIT1(OK);
2031 return OK;
2032 bad:
2033 FN_EXIT1(NOT_OK);
2034 return NOT_OK;
2038 /***********************************************************************
2039 ** acx100_s_create_dma_regions
2041 ** Note that this fn messes up heavily with hardware, but we cannot
2042 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2044 /* OLD CODE? - let's rewrite it! */
2045 static int acx100_s_create_dma_regions(acx_device_t * adev)
2047 acx100_ie_queueconfig_t queueconf;
2048 acx_ie_memmap_t memmap;
2049 int res = NOT_OK;
2050 u32 tx_queue_start, rx_queue_start;
2052 FN_ENTER;
2054 /* read out the acx100 physical start address for the queues */
2055 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2056 goto fail;
2059 tx_queue_start = le32_to_cpu(memmap.QueueStart);
2060 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
2062 log(L_DEBUG, "initializing Queue Indicator\n");
2064 memset(&queueconf, 0, sizeof(queueconf));
2066 /* Not needed for PCI, so we can avoid setting them altogether */
2067 if (IS_USB(adev)) {
2068 queueconf.NumTxDesc = USB_TX_CNT;
2069 queueconf.NumRxDesc = USB_RX_CNT;
2072 /* calculate size of queues */
2073 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
2074 RX_CNT * sizeof(rxdesc_t) + 8);
2075 queueconf.NumTxQueues = 1; /* number of tx queues */
2076 /* sets the beginning of the tx descriptor queue */
2077 queueconf.TxQueueStart = memmap.QueueStart;
2078 /* done by memset: queueconf.TxQueuePri = 0; */
2079 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
2080 queueconf.QueueOptions = 1; /* auto reset descriptor */
2081 /* sets the end of the rx descriptor queue */
2082 queueconf.QueueEnd =
2083 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
2085 /* sets the beginning of the next queue */
2086 queueconf.HostQueueEnd =
2087 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
2088 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
2089 goto fail;
2092 if (IS_PCI(adev)) {
2093 /* sets the beginning of the rx descriptor queue, after the tx descrs */
2094 if (OK != acxpci_s_create_hostdesc_queues(adev))
2095 goto fail;
2096 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2099 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2100 goto fail;
2103 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
2104 0x1f) & ~0x1f);
2106 if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2107 goto fail;
2110 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
2111 goto fail;
2114 res = OK;
2115 goto end;
2117 fail:
2118 acx_s_mwait(1000); /* ? */
2119 if (IS_PCI(adev))
2120 acxpci_free_desc_queues(adev);
2121 end:
2122 FN_EXIT1(res);
2123 return res;
2127 /***********************************************************************
2128 ** acx111_s_create_dma_regions
2130 ** Note that this fn messes heavily with hardware, but we cannot
2131 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2133 #define ACX111_PERCENT(percent) ((percent)/5)
2135 static int acx111_s_create_dma_regions(acx_device_t * adev)
2137 struct acx111_ie_memoryconfig memconf;
2138 struct acx111_ie_queueconfig queueconf;
2139 u32 tx_queue_start, rx_queue_start;
2141 FN_ENTER;
2143 /* Calculate memory positions and queue sizes */
2145 /* Set up our host descriptor pool + data pool */
2146 if (IS_PCI(adev)) {
2147 if (OK != acxpci_s_create_hostdesc_queues(adev))
2148 goto fail;
2151 memset(&memconf, 0, sizeof(memconf));
2152 /* the number of STAs (STA contexts) to support
2153 ** NB: was set to 1 and everything seemed to work nevertheless... */
2154 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
2155 /* specify the memory block size. Default is 256 */
2156 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
2157 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
2158 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
2159 /* set the count of our queues
2160 ** NB: struct acx111_ie_memoryconfig shall be modified
2161 ** if we ever will switch to more than one rx and/or tx queue */
2162 memconf.count_rx_queues = 1;
2163 memconf.count_tx_queues = 1;
2164 /* 0 == Busmaster Indirect Memory Organization, which is what we want
2165 * (using linked host descs with their allocated mem).
2166 * 2 == Generic Bus Slave */
2167 /* done by memset: memconf.options = 0; */
2168 /* let's use 25% for fragmentations and 75% for frame transfers
2169 * (specified in units of 5%) */
2170 memconf.fragmentation = ACX111_PERCENT(75);
2171 /* Rx descriptor queue config */
2172 memconf.rx_queue1_count_descs = RX_CNT;
2173 memconf.rx_queue1_type = 7; /* must be set to 7 */
2174 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2175 if (IS_PCI(adev)) {
2176 memconf.rx_queue1_host_rx_start =
2177 cpu2acx(adev->rxhostdesc_startphy);
2179 /* Tx descriptor queue config */
2180 memconf.tx_queue1_count_descs = TX_CNT;
2181 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2183 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
2184 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2185 ** But it is actually correct wrt IE numbers.
2186 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
2187 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2188 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2189 if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
2190 goto fail;
2193 acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
2195 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2196 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2198 log(L_INIT, "dump queue head (from card):\n"
2199 "len: %u\n"
2200 "tx_memory_block_address: %X\n"
2201 "rx_memory_block_address: %X\n"
2202 "tx1_queue address: %X\n"
2203 "rx1_queue address: %X\n",
2204 le16_to_cpu(queueconf.len),
2205 le32_to_cpu(queueconf.tx_memory_block_address),
2206 le32_to_cpu(queueconf.rx_memory_block_address),
2207 tx_queue_start, rx_queue_start);
2209 if (IS_PCI(adev))
2210 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2212 FN_EXIT1(OK);
2213 return OK;
2214 fail:
2215 if (IS_PCI(adev))
2216 acxpci_free_desc_queues(adev);
2218 FN_EXIT1(NOT_OK);
2219 return NOT_OK;
2223 /***********************************************************************
2225 static void acx_s_initialize_rx_config(acx_device_t * adev)
2227 struct {
2228 u16 id;
2229 u16 len;
2230 u16 rx_cfg1;
2231 u16 rx_cfg2;
2232 } ACX_PACKED cfg;
2233 switch (adev->mode) {
2234 case ACX_MODE_MONITOR:
2235 adev->rx_config_1 = (u16) (0
2236 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2237 /* | RX_CFG1_FILTER_SSID */
2238 /* | RX_CFG1_FILTER_BCAST */
2239 /* | RX_CFG1_RCV_MC_ADDR1 */
2240 /* | RX_CFG1_RCV_MC_ADDR0 */
2241 /* | RX_CFG1_FILTER_ALL_MULTI */
2242 /* | RX_CFG1_FILTER_BSSID */
2243 /* | RX_CFG1_FILTER_MAC */
2244 | RX_CFG1_RCV_PROMISCUOUS
2245 | RX_CFG1_INCLUDE_FCS
2246 /* | RX_CFG1_INCLUDE_PHY_HDR */
2248 adev->rx_config_2 = (u16) (0
2249 | RX_CFG2_RCV_ASSOC_REQ
2250 | RX_CFG2_RCV_AUTH_FRAMES
2251 | RX_CFG2_RCV_BEACON_FRAMES
2252 | RX_CFG2_RCV_CONTENTION_FREE
2253 | RX_CFG2_RCV_CTRL_FRAMES
2254 | RX_CFG2_RCV_DATA_FRAMES
2255 | RX_CFG2_RCV_BROKEN_FRAMES
2256 | RX_CFG2_RCV_MGMT_FRAMES
2257 | RX_CFG2_RCV_PROBE_REQ
2258 | RX_CFG2_RCV_PROBE_RESP
2259 | RX_CFG2_RCV_ACK_FRAMES
2260 | RX_CFG2_RCV_OTHER);
2261 break;
2262 default:
2263 adev->rx_config_1 = (u16) (0
2264 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2265 /* | RX_CFG1_FILTER_SSID */
2266 /* | RX_CFG1_FILTER_BCAST */
2267 /* | RX_CFG1_RCV_MC_ADDR1 */
2268 /* | RX_CFG1_RCV_MC_ADDR0 */
2269 /* | RX_CFG1_FILTER_ALL_MULTI */
2270 /* | RX_CFG1_FILTER_BSSID */
2271 /* | RX_CFG1_FILTER_MAC */
2272 | RX_CFG1_RCV_PROMISCUOUS
2273 /* | RX_CFG1_INCLUDE_FCS */
2274 /* | RX_CFG1_INCLUDE_PHY_HDR */
2276 adev->rx_config_2 = (u16) (0
2277 | RX_CFG2_RCV_ASSOC_REQ
2278 | RX_CFG2_RCV_AUTH_FRAMES
2279 | RX_CFG2_RCV_BEACON_FRAMES
2280 | RX_CFG2_RCV_CONTENTION_FREE
2281 | RX_CFG2_RCV_CTRL_FRAMES
2282 | RX_CFG2_RCV_DATA_FRAMES
2283 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2284 | RX_CFG2_RCV_MGMT_FRAMES
2285 | RX_CFG2_RCV_PROBE_REQ
2286 | RX_CFG2_RCV_PROBE_RESP
2287 | RX_CFG2_RCV_ACK_FRAMES
2288 | RX_CFG2_RCV_OTHER);
2289 break;
2291 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2293 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2294 || (adev->firmware_numver >= 0x02000000))
2295 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2296 else
2297 adev->phy_header_len = 0;
2299 log(L_INIT, "setting RXconfig to %04X:%04X\n",
2300 adev->rx_config_1, adev->rx_config_2);
2301 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2302 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2303 acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
2307 /***********************************************************************
2308 ** FIXME: this should be solved in a general way for all radio types
2309 ** by decoding the radio firmware module,
2310 ** since it probably has some standard structure describing how to
2311 ** set the power level of the radio module which it controls.
2312 ** Or maybe not, since the radio module probably has a function interface
2313 ** instead which then manages Tx level programming :-\
2315 ** Obvious
2317 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2319 struct acx111_ie_tx_level tx_level;
2321 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2322 * 1 (30mW) [15dBm]
2323 * 2 (10mW) [10dBm]
2324 * For now, just assume all other acx111 cards have the same.
2325 * FIXME: Ideally we would query it here, but we first need a
2326 * standard way to query individual configoptions easily.
2327 * Well, now we have proper cfgopt txpower variables, but this still
2328 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2329 if (level_dbm <= 12) {
2330 tx_level.level = 2; /* 10 dBm */
2331 adev->tx_level_dbm = 10;
2332 } else {
2333 tx_level.level = 1; /* 15 dBm */
2334 adev->tx_level_dbm = 15;
2336 if (level_dbm != adev->tx_level_dbm)
2337 log(L_INIT, "acx111 firmware has specific "
2338 "power levels only: adjusted %d dBm to %d dBm!\n",
2339 level_dbm, adev->tx_level_dbm);
2341 return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
2344 static int acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
2346 if (IS_ACX111(adev)) {
2347 return acx111_s_set_tx_level(adev, level_dbm);
2349 if (IS_PCI(adev)) {
2350 return acx100pci_s_set_tx_level(adev, level_dbm);
2353 return OK;
2357 /***********************************************************************
2358 ** acx_s_set_defaults
2360 void acx_s_set_defaults(acx_device_t * adev)
2362 struct ieee80211_conf *conf = &adev->ieee->conf;
2363 unsigned long flags;
2365 FN_ENTER;
2367 acx_lock(adev, flags);
2368 /* do it before getting settings, prevent bogus channel 0 warning */
2369 adev->channel = 1;
2371 /* query some settings from the card.
2372 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2373 * query is REQUIRED, otherwise the card won't work correctly! */
2374 adev->get_mask =
2375 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2376 GETSET_REG_DOMAIN;
2377 /* Only ACX100 supports ED and CCA */
2378 if (IS_ACX100(adev))
2379 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2381 acx_unlock(adev, flags);
2383 acx_s_update_card_settings(adev);
2385 acx_lock(adev, flags);
2387 /* set our global interrupt mask */
2388 if (IS_PCI(adev))
2389 acxpci_set_interrupt_mask(adev);
2391 adev->led_power = 1; /* LED is active on startup */
2392 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2393 adev->brange_time_last_state_change = jiffies;
2395 /* copy the MAC address we just got from the card
2396 * into our MAC address used during current 802.11 session */
2397 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
2398 MAC_BCAST(adev->ap);
2400 adev->essid_len =
2401 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2402 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2403 adev->essid_active = 1;
2405 /* we have a nick field to waste, so why not abuse it
2406 * to announce the driver version? ;-) */
2407 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2409 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2410 /* first regulatory domain entry in EEPROM == default reg. domain */
2411 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2414 /* 0xffff would be better, but then we won't get a "scan complete"
2415 * interrupt, so our current infrastructure will fail: */
2416 adev->scan_count = 1;
2417 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2418 adev->scan_duration = 100;
2419 adev->scan_probe_delay = 200;
2420 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2421 adev->scan_rate = ACX_SCAN_RATE_1;
2424 adev->mode = ACX_MODE_2_STA;
2425 adev->listen_interval = 100;
2426 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2427 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2429 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2431 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2432 adev->frag_threshold = 2346;
2434 /* use standard default values for retry limits */
2435 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2436 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2438 adev->preamble_mode = 2; /* auto */
2439 adev->fallback_threshold = 3;
2440 adev->stepup_threshold = 10;
2441 adev->rate_bcast = RATE111_1;
2442 adev->rate_bcast100 = RATE100_1;
2443 adev->rate_basic = RATE111_1 | RATE111_2;
2444 adev->rate_auto = 1;
2445 if (IS_ACX111(adev)) {
2446 adev->rate_oper = RATE111_ALL;
2447 } else {
2448 adev->rate_oper = RATE111_ACX100_COMPAT;
2451 /* Supported Rates element - the rates here are given in units of
2452 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2453 acx_l_update_ratevector(adev);
2455 /* set some more defaults */
2456 if (IS_ACX111(adev)) {
2457 /* 30mW (15dBm) is default, at least in my acx111 card: */
2458 adev->tx_level_dbm = 15;
2459 conf->power_level = adev->tx_level_dbm;
2460 acx_unlock(adev, flags);
2461 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2462 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2463 acx_lock(adev, flags);
2464 } else {
2465 /* don't use max. level, since it might be dangerous
2466 * (e.g. WRT54G people experience
2467 * excessive Tx power damage!) */
2468 adev->tx_level_dbm = 18;
2469 conf->power_level = adev->tx_level_dbm;
2470 acx_unlock(adev, flags);
2471 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2472 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2473 acx_lock(adev, flags);
2476 /* adev->tx_level_auto = 1; */
2477 if (IS_ACX111(adev)) {
2478 /* start with sensitivity level 1 out of 3: */
2479 adev->sensitivity = 1;
2482 /* #define ENABLE_POWER_SAVE */
2483 #ifdef ENABLE_POWER_SAVE
2484 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2485 adev->ps_listen_interval = 1;
2486 adev->ps_options =
2487 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2488 adev->ps_hangover_period = 30;
2489 adev->ps_enhanced_transition_time = 0;
2490 #else
2491 adev->ps_wakeup_cfg = 0;
2492 adev->ps_listen_interval = 0;
2493 adev->ps_options = 0;
2494 adev->ps_hangover_period = 0;
2495 adev->ps_enhanced_transition_time = 0;
2496 #endif
2498 /* These settings will be set in fw on ifup */
2499 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2500 /* configure card to do rate fallback when in auto rate mode */
2501 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2502 /* better re-init the antenna value we got above */
2503 | GETSET_ANTENNA
2504 #if POWER_SAVE_80211
2505 | GETSET_POWER_80211
2506 #endif
2509 acx_unlock(adev, flags);
2510 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2512 acx_s_initialize_rx_config(adev);
2514 FN_EXIT0;
2518 /***********************************************************************
2519 ** acx_l_process_rxbuf
2521 ** NB: used by USB code also
2523 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2525 struct ieee80211_hdr *hdr;
2526 u16 fc, buf_len;
2527 hdr = acx_get_wlan_hdr(adev, rxbuf);
2528 fc = le16_to_cpu(hdr->frame_control);
2529 /* length of frame from control field to first byte of FCS */
2530 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2532 if (unlikely(acx_debug & L_DATA)) {
2533 printk("rx: 802.11 buf[%u]: \n", buf_len);
2534 acx_dump_bytes(hdr, buf_len);
2538 acx_l_rx(adev, rxbuf);
2539 /* Now check Rx quality level, AFTER processing packet.
2540 * I tried to figure out how to map these levels to dBm
2541 * values, but for the life of me I really didn't
2542 * manage to get it. Either these values are not meant to
2543 * be expressed in dBm, or it's some pretty complicated
2544 * calculation. */
2546 #ifdef FROM_SCAN_SOURCE_ONLY
2547 /* only consider packets originating from the MAC
2548 * address of the device that's managing our BSSID.
2549 * Disable it for now, since it removes information (levels
2550 * from different peers) and slows the Rx path. *//*
2551 if (adev->ap_client && mac_is_equal(hdr->a2, adev->ap_client->address)) {
2553 #endif
2557 /***********************************************************************
2558 ** acx_l_handle_txrate_auto
2560 ** Theory of operation:
2561 ** client->rate_cap is a bitmask of rates client is capable of.
2562 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2563 ** It is set as a result of iwconfig rate N [auto]
2564 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2565 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2566 ** auto (0x00ff == 18Mbit or any lower value),
2567 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2569 ** client->rate_cur is a value for rate111 field in tx descriptor.
2570 ** It is always set to txrate_cfg sans zero or more most significant
2571 ** bits. This routine handles selection of new rate_cur value depending on
2572 ** outcome of last tx event.
2574 ** client->rate_100 is a precalculated rate value for acx100
2575 ** (we can do without it, but will need to calculate it on each tx).
2577 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2578 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2579 ** In theory you can implement it, but so far it is considered not worth doing.
2581 ** 22Mbit, of course, is PBCC always. */
2583 /* maps acx100 tx descr rate field to acx111 one */
2585 static u16 rate100to111(u8 r)
2587 switch (r) {
2588 case RATE100_1:
2589 return RATE111_1;
2590 case RATE100_2:
2591 return RATE111_2;
2592 case RATE100_5:
2593 case (RATE100_5 | RATE100_PBCC511):
2594 return RATE111_5;
2595 case RATE100_11:
2596 case (RATE100_11 | RATE100_PBCC511):
2597 return RATE111_11;
2598 case RATE100_22:
2599 return RATE111_22;
2600 default:
2601 printk("acx: unexpected acx100 txrate: %u! "
2602 "Please report\n", r);
2603 return RATE111_1;
2610 acx_i_start_xmit(struct ieee80211_hw *hw,
2611 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2613 acx_device_t *adev = ieee2adev(hw);
2614 tx_t *tx;
2615 void *txbuf;
2616 unsigned long flags;
2618 int txresult = NOT_OK;
2620 FN_ENTER;
2622 acx_lock(adev, flags);
2624 if (unlikely(!skb)) {
2625 /* indicate success */
2626 txresult = OK;
2627 goto end;
2630 if (unlikely(!adev)) {
2631 goto end;
2635 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2636 goto end;
2638 if (unlikely(!adev->initialized)) {
2639 goto end;
2642 tx = acx_l_alloc_tx(adev);
2644 if (unlikely(!tx)) {
2645 printk_ratelimited("%s: start_xmit: txdesc ring is full, "
2646 "dropping tx\n", wiphy_name(adev->ieee->wiphy));
2647 txresult = NOT_OK;
2648 goto end;
2651 txbuf = acx_l_get_txbuf(adev, tx);
2653 if (unlikely(!txbuf)) {
2654 /* Card was removed */
2655 txresult = NOT_OK;
2656 acx_l_dealloc_tx(adev, tx);
2657 goto end;
2659 memcpy(txbuf, skb->data, skb->len);
2661 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2663 txresult = OK;
2664 adev->stats.tx_packets++;
2665 adev->stats.tx_bytes += skb->len;
2667 end:
2668 acx_unlock(adev, flags);
2670 FN_EXIT1(txresult);
2671 return txresult;
2673 /***********************************************************************
2674 ** acx_l_update_ratevector
2676 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2678 const u8 acx_bitpos2ratebyte[] = {
2679 DOT11RATEBYTE_1,
2680 DOT11RATEBYTE_2,
2681 DOT11RATEBYTE_5_5,
2682 DOT11RATEBYTE_6_G,
2683 DOT11RATEBYTE_9_G,
2684 DOT11RATEBYTE_11,
2685 DOT11RATEBYTE_12_G,
2686 DOT11RATEBYTE_18_G,
2687 DOT11RATEBYTE_22,
2688 DOT11RATEBYTE_24_G,
2689 DOT11RATEBYTE_36_G,
2690 DOT11RATEBYTE_48_G,
2691 DOT11RATEBYTE_54_G,
2694 void acx_l_update_ratevector(acx_device_t * adev)
2696 u16 bcfg = adev->rate_basic;
2697 u16 ocfg = adev->rate_oper;
2698 u8 *supp = adev->rate_supported;
2699 const u8 *dot11 = acx_bitpos2ratebyte;
2701 FN_ENTER;
2703 while (ocfg) {
2704 if (ocfg & 1) {
2705 *supp = *dot11;
2706 if (bcfg & 1) {
2707 *supp |= 0x80;
2709 supp++;
2711 dot11++;
2712 ocfg >>= 1;
2713 bcfg >>= 1;
2715 adev->rate_supported_len = supp - adev->rate_supported;
2716 if (acx_debug & L_ASSOC) {
2717 printk("new ratevector: ");
2718 acx_dump_bytes(adev->rate_supported, adev->rate_supported_len);
2720 FN_EXIT0;
2723 /***********************************************************************
2724 ** acx_i_timer
2726 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2728 ** Obvious
2730 void acx_i_timer(unsigned long address)
2732 unsigned long flags;
2733 acx_device_t *adev = (acx_device_t *) address;
2735 FN_ENTER;
2737 acx_lock(adev, flags);
2739 FIXME();
2740 /* We need calibration and stats gather tasks to perform here */
2742 acx_unlock(adev, flags);
2744 FN_EXIT0;
2748 /***********************************************************************
2749 ** acx_set_timer
2751 ** Sets the 802.11 state management timer's timeout.
2753 ** Linux derived
2755 void acx_set_timer(acx_device_t * adev, int timeout_us)
2757 FN_ENTER;
2759 log(L_DEBUG | L_IRQ, "%s(%u ms)\n", __func__, timeout_us / 1000);
2760 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2761 printk("attempt to set the timer "
2762 "when the card interface is not up!\n");
2763 goto end;
2766 /* first check if the timer was already initialized, THEN modify it */
2767 if (adev->mgmt_timer.function) {
2768 mod_timer(&adev->mgmt_timer,
2769 jiffies + (timeout_us * HZ / 1000000));
2771 end:
2772 FN_EXIT0;
2775 /** acx_plcp_get_bitrate_cck
2777 ** Obvious
2779 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2781 switch (plcp) {
2782 case 0x0A:
2783 return ACX_CCK_RATE_1MB;
2784 case 0x14:
2785 return ACX_CCK_RATE_2MB;
2786 case 0x37:
2787 return ACX_CCK_RATE_5MB;
2788 case 0x6E:
2789 return ACX_CCK_RATE_11MB;
2791 return 0;
2794 /* Extract the bitrate out of an OFDM PLCP header. */
2795 /** Obvious **/
2796 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2798 switch (plcp & 0xF) {
2799 case 0xB:
2800 return ACX_OFDM_RATE_6MB;
2801 case 0xF:
2802 return ACX_OFDM_RATE_9MB;
2803 case 0xA:
2804 return ACX_OFDM_RATE_12MB;
2805 case 0xE:
2806 return ACX_OFDM_RATE_18MB;
2807 case 0x9:
2808 return ACX_OFDM_RATE_24MB;
2809 case 0xD:
2810 return ACX_OFDM_RATE_36MB;
2811 case 0x8:
2812 return ACX_OFDM_RATE_48MB;
2813 case 0xC:
2814 return ACX_OFDM_RATE_54MB;
2816 return 0;
2820 /***********************************************************************
2821 ** acx_l_rx
2823 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2824 ** buffer and feeds it to the network stack via netif_rx().
2826 ** Look to bcm43xx or p54
2828 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2831 struct ieee80211_rx_status* status = &adev->rx_status;
2832 struct ieee80211_hdr *w_hdr;
2833 int buflen;
2834 FN_ENTER;
2836 if (likely(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2837 struct sk_buff *skb;
2838 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2839 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2840 skb = dev_alloc_skb(buflen + 2);
2841 skb_reserve(skb, 2);
2842 skb_put(skb, buflen);
2843 memcpy(skb->data, w_hdr, buflen);
2845 // memset(&status, 0, sizeof(status));
2847 if (likely(skb)) {
2848 status->mactime = rxbuf->time;
2849 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2850 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr);
2851 status->flag = 0;
2852 status->rate = rxbuf->phy_plcp_signal;
2853 status->antenna = 1;
2855 #ifndef OLD_QUALITY
2856 qual = acx_signal_determine_quality(adev->wstats.qual.level,
2857 adev->wstats.qual.noise);
2858 #else
2859 qual = (adev->wstats.qual.noise <= 100) ?
2860 100 - adev->wstats.qual.noise : 0;
2861 #endif
2862 adev->wstats.qual.qual = qual;
2863 adev->wstats.qual.updated = 7; *//* all 3 indicators updated */
2865 #ifdef FROM_SCAN_SOURCE_ONLY
2867 #endif
2869 if (rxbuf->phy_stat_baseband & (1 << 3)) /* Uses OFDM */
2871 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2872 } else
2874 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2876 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2877 adev->stats.rx_packets++;
2878 adev->stats.rx_bytes += skb->len;
2881 FN_EXIT0;
2886 /***********************************************************************
2887 ** acx_s_read_fw
2889 ** Loads a firmware image
2891 ** Returns:
2892 ** 0 unable to load file
2893 ** pointer to firmware success
2895 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2896 u32 * size)
2898 firmware_image_t *res;
2899 const struct firmware *fw_entry;
2901 res = NULL;
2902 log(L_INIT, "requesting firmware image '%s'\n", file);
2903 if (!request_firmware(&fw_entry, file, dev)) {
2904 *size = 8;
2905 if (fw_entry->size >= 8)
2906 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2907 if (fw_entry->size != *size) {
2908 printk("acx: firmware size does not match "
2909 "firmware header: %d != %d, "
2910 "aborting fw upload\n",
2911 (int)fw_entry->size, (int)*size);
2912 goto release_ret;
2914 res = vmalloc(*size);
2915 if (!res) {
2916 printk("acx: no memory for firmware "
2917 "(%u bytes)\n", *size);
2918 goto release_ret;
2920 memcpy(res, fw_entry->data, fw_entry->size);
2921 release_ret:
2922 release_firmware(fw_entry);
2923 return res;
2925 printk("acx: firmware image '%s' was not provided. "
2926 "Check your hotplug scripts\n", file);
2928 /* checksum will be verified in write_fw, so don't bother here */
2929 return res;
2933 /***********************************************************************
2934 ** acx_s_set_wepkey
2936 static void acx100_s_set_wepkey(acx_device_t * adev)
2938 ie_dot11WEPDefaultKey_t dk;
2939 int i;
2941 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2942 if (adev->wep_keys[i].size != 0) {
2943 log(L_INIT, "setting WEP key: %d with "
2944 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2945 dk.action = 1;
2946 dk.keySize = adev->wep_keys[i].size;
2947 dk.defaultKeyNum = i;
2948 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2949 acx_s_configure(adev, &dk,
2950 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
2955 static void acx111_s_set_wepkey(acx_device_t * adev)
2957 acx111WEPDefaultKey_t dk;
2958 int i;
2960 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2961 if (adev->wep_keys[i].size != 0) {
2962 log(L_INIT, "setting WEP key: %d with "
2963 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2964 memset(&dk, 0, sizeof(dk));
2965 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2966 dk.keySize = adev->wep_keys[i].size;
2968 /* are these two lines necessary? */
2969 dk.type = 0; /* default WEP key */
2970 dk.index = 0; /* ignored when setting default key */
2972 dk.defaultKeyNum = i;
2973 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2974 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2975 sizeof(dk));
2979 /* Obvious */
2980 static void acx_s_set_wepkey(acx_device_t * adev)
2982 if (IS_ACX111(adev))
2983 acx111_s_set_wepkey(adev);
2984 else
2985 acx100_s_set_wepkey(adev);
2989 /***********************************************************************
2990 ** acx100_s_init_wep
2992 ** FIXME: this should probably be moved into the new card settings
2993 ** management, but since we're also modifying the memory map layout here
2994 ** due to the WEP key space we want, we should take care...
2996 static int acx100_s_init_wep(acx_device_t * adev)
2998 acx100_ie_wep_options_t options;
2999 ie_dot11WEPDefaultKeyID_t dk;
3000 acx_ie_memmap_t pt;
3001 int res = NOT_OK;
3003 FN_ENTER;
3005 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
3006 goto fail;
3009 log(L_DEBUG, "CodeEnd:%X\n", pt.CodeEnd);
3011 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
3012 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
3014 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
3015 goto fail;
3018 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
3019 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3020 options.WEPOption = 0x00;
3022 log(L_ASSOC, "writing WEP options\n");
3023 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3025 acx100_s_set_wepkey(adev);
3027 if (adev->wep_keys[adev->wep_current_index].size != 0) {
3028 log(L_ASSOC, "setting active default WEP key number: %d\n",
3029 adev->wep_current_index);
3030 dk.KeyID = adev->wep_current_index;
3031 acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
3033 /* FIXME!!! wep_key_struct is filled nowhere! But adev
3034 * is initialized to 0, and we don't REALLY need those keys either */
3035 /* for (i = 0; i < 10; i++) {
3036 if (adev->wep_key_struct[i].len != 0) {
3037 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
3038 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
3039 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
3040 wep_mgmt.Action = cpu_to_le16(1);
3041 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
3042 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
3043 adev->wep_key_struct[i].index = i;
3049 /* now retrieve the updated WEPCacheEnd pointer... */
3050 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
3051 printk("%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
3052 wiphy_name(adev->ieee->wiphy));
3053 goto fail;
3055 /* ...and tell it to start allocating templates at that location */
3056 /* (no endianness conversion needed) */
3057 pt.PacketTemplateStart = pt.WEPCacheEnd;
3059 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
3060 printk("%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
3061 wiphy_name(adev->ieee->wiphy));
3062 goto fail;
3064 res = OK;
3066 fail:
3067 FN_EXIT1(res);
3068 return res;
3072 static int
3073 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
3074 unsigned int cmd)
3076 int res;
3077 union {
3078 acx_template_nullframe_t null;
3079 acx_template_beacon_t b;
3080 acx_template_tim_t tim;
3081 acx_template_probereq_t preq;
3082 acx_template_proberesp_t presp;
3083 } templ;
3085 memset(&templ, 0, len);
3086 templ.null.size = cpu_to_le16(len - 2);
3087 res = acx_s_issue_cmd(adev, cmd, &templ, len);
3088 return res;
3091 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
3093 return acx_s_init_max_template_generic(adev,
3094 sizeof(acx_template_nullframe_t),
3095 ACX1xx_CMD_CONFIG_NULL_DATA);
3098 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
3100 return acx_s_init_max_template_generic(adev,
3101 sizeof(acx_template_beacon_t),
3102 ACX1xx_CMD_CONFIG_BEACON);
3105 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
3107 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
3108 ACX1xx_CMD_CONFIG_TIM);
3111 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
3113 return acx_s_init_max_template_generic(adev,
3114 sizeof(acx_template_proberesp_t),
3115 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
3118 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
3120 return acx_s_init_max_template_generic(adev,
3121 sizeof(acx_template_probereq_t),
3122 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
3125 /***********************************************************************
3126 ** acx_s_set_tim_template
3128 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
3129 ** by calling this function
3130 ** (it can be done by irq handler on each DTIM irq or by timer...)
3132 [802.11 7.3.2.6] TIM information element:
3133 - 1 EID
3134 - 1 Length
3135 1 1 DTIM Count
3136 indicates how many beacons (including this) appear before next DTIM
3137 (0=this one is a DTIM)
3138 2 1 DTIM Period
3139 number of beacons between successive DTIMs
3140 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
3141 3 1 Bitmap Control
3142 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
3143 set to 1 in TIM elements with a value of 0 in the DTIM Count field
3144 when one or more broadcast or multicast frames are buffered at the AP.
3145 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
3146 4 n Partial Virtual Bitmap
3147 Visible part of traffic-indication bitmap.
3148 Full bitmap consists of 2008 bits (251 octets) such that bit number N
3149 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
3150 in octet number N/8 where the low-order bit of each octet is bit0,
3151 and the high order bit is bit7.
3152 Each set bit in virtual bitmap corresponds to traffic buffered by AP
3153 for a specific station (with corresponding AID?).
3154 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
3155 Bitmap Offset is a number of skipped zero octets (see above).
3156 'Missing' octets at the tail are also assumed to be zero.
3157 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
3158 This means that traffic-indication bitmap is:
3159 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
3160 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
3162 static int acx_s_set_tim_template(acx_device_t * adev)
3164 /* For now, configure smallish test bitmap, all zero ("no pending data") */
3165 enum { bitmap_size = 5 };
3167 acx_template_tim_t t;
3168 int result;
3170 FN_ENTER;
3172 memset(&t, 0, sizeof(t));
3173 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3174 t.tim_eid = WLAN_EID_TIM;
3175 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3176 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3177 FN_EXIT1(result);
3178 return result;
3184 #if POWER_SAVE_80211
3185 /***********************************************************************
3186 ** acx_s_set_null_data_template
3188 static int acx_s_set_null_data_template(acx_device_t * adev)
3190 struct acx_template_nullframe b;
3191 int result;
3193 FN_ENTER;
3195 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3197 b.size = cpu_to_le16(sizeof(b) - 2);
3198 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3199 b.hdr.dur = 0;
3200 MAC_BCAST(b.hdr.a1);
3201 MAC_COPY(b.hdr.a2, adev->dev_addr);
3202 MAC_COPY(b.hdr.a3, adev->bssid);
3203 b.hdr.seq = 0;
3205 result =
3206 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3208 FN_EXIT1(result);
3209 return result;
3211 #endif
3218 /***********************************************************************
3219 ** acx_s_init_packet_templates()
3221 ** NOTE: order is very important here, to have a correct memory layout!
3222 ** init templates: max Probe Request (station mode), max NULL data,
3223 ** max Beacon, max TIM, max Probe Response.
3225 static int acx_s_init_packet_templates(acx_device_t * adev)
3227 acx_ie_memmap_t mm; /* ACX100 only */
3228 int result = NOT_OK;
3230 FN_ENTER;
3232 log(L_DEBUG | L_INIT, "initializing max packet templates\n");
3234 if (OK != acx_s_init_max_probe_request_template(adev))
3235 goto failed;
3237 if (OK != acx_s_init_max_null_data_template(adev))
3238 goto failed;
3240 if (OK != acx_s_init_max_beacon_template(adev))
3241 goto failed;
3243 if (OK != acx_s_init_max_tim_template(adev))
3244 goto failed;
3246 if (OK != acx_s_init_max_probe_response_template(adev))
3247 goto failed;
3249 if (IS_ACX111(adev)) {
3250 /* ACX111 doesn't need the memory map magic below,
3251 * and the other templates will be set later (acx_start) */
3252 result = OK;
3253 goto success;
3256 /* ACX100 will have its TIM template set,
3257 * and we also need to update the memory map */
3259 if (OK != acx_s_set_tim_template(adev))
3260 goto failed_acx100;
3262 log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3264 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3265 goto failed_acx100;
3267 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3268 if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3269 goto failed_acx100;
3271 result = OK;
3272 goto success;
3274 failed_acx100:
3275 log(L_DEBUG | L_INIT,
3276 /* "cb=0x%X\n" */
3277 "ACXMemoryMap:\n"
3278 ".CodeStart=0x%X\n"
3279 ".CodeEnd=0x%X\n"
3280 ".WEPCacheStart=0x%X\n"
3281 ".WEPCacheEnd=0x%X\n"
3282 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3283 /* len, */
3284 le32_to_cpu(mm.CodeStart),
3285 le32_to_cpu(mm.CodeEnd),
3286 le32_to_cpu(mm.WEPCacheStart),
3287 le32_to_cpu(mm.WEPCacheEnd),
3288 le32_to_cpu(mm.PacketTemplateStart),
3289 le32_to_cpu(mm.PacketTemplateEnd));
3291 failed:
3292 printk("%s: %s() FAILED\n", wiphy_name(adev->ieee->wiphy), __func__);
3294 success:
3295 FN_EXIT1(result);
3296 return result;
3301 /***********************************************************************
3302 ** acx_s_init_mac
3304 int acx_s_init_mac(acx_device_t * adev)
3306 int result = NOT_OK;
3308 FN_ENTER;
3310 if (IS_ACX111(adev)) {
3311 adev->ie_len = acx111_ie_len;
3312 adev->ie_len_dot11 = acx111_ie_len_dot11;
3313 } else {
3314 adev->ie_len = acx100_ie_len;
3315 adev->ie_len_dot11 = acx100_ie_len_dot11;
3318 if (IS_PCI(adev)) {
3319 adev->memblocksize = 256; /* 256 is default */
3320 /* try to load radio for both ACX100 and ACX111, since both
3321 * chips have at least some firmware versions making use of an
3322 * external radio module */
3323 acxpci_s_upload_radio(adev);
3324 } else {
3325 adev->memblocksize = 128;
3328 if (IS_ACX111(adev)) {
3329 /* for ACX111, the order is different from ACX100
3330 1. init packet templates
3331 2. create station context and create dma regions
3332 3. init wep default keys
3334 if (OK != acx_s_init_packet_templates(adev))
3335 goto fail;
3336 if (OK != acx111_s_create_dma_regions(adev)) {
3337 printk("%s: acx111_create_dma_regions FAILED\n",
3338 wiphy_name(adev->ieee->wiphy));
3339 goto fail;
3341 } else {
3342 if (OK != acx100_s_init_wep(adev))
3343 goto fail;
3344 if (OK != acx_s_init_packet_templates(adev))
3345 goto fail;
3346 if (OK != acx100_s_create_dma_regions(adev)) {
3347 printk("%s: acx100_create_dma_regions FAILED\n",
3348 wiphy_name(adev->ieee->wiphy));
3349 goto fail;
3353 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3354 result = OK;
3356 fail:
3357 if (result)
3358 printk("acx: init_mac() FAILED\n");
3359 FN_EXIT1(result);
3360 return result;
3365 #if POWER_SAVE_80211
3366 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3368 /* merge both structs in a union to be able to have common code */
3369 union {
3370 acx111_ie_powersave_t acx111;
3371 acx100_ie_powersave_t acx100;
3372 } pm;
3374 /* change 802.11 power save mode settings */
3375 log(L_INIT, "updating 802.11 power save mode settings: "
3376 "wakeup_cfg 0x%02X, listen interval %u, "
3377 "options 0x%02X, hangover period %u, "
3378 "enhanced_ps_transition_time %u\n",
3379 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3380 adev->ps_options, adev->ps_hangover_period,
3381 adev->ps_enhanced_transition_time);
3382 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3383 log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, "
3384 "listen interval %u, options 0x%02X, "
3385 "hangover period %u, "
3386 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3387 pm.acx111.wakeup_cfg,
3388 pm.acx111.listen_interval,
3389 pm.acx111.options,
3390 pm.acx111.hangover_period,
3391 IS_ACX111(adev) ?
3392 pm.acx111.enhanced_ps_transition_time
3393 : pm.acx100.enhanced_ps_transition_time,
3394 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3395 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3396 pm.acx111.listen_interval = adev->ps_listen_interval;
3397 pm.acx111.options = adev->ps_options;
3398 pm.acx111.hangover_period = adev->ps_hangover_period;
3399 if (IS_ACX111(adev)) {
3400 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3401 pm.acx111.enhanced_ps_transition_time =
3402 cpu_to_le32(adev->ps_enhanced_transition_time);
3403 } else {
3404 pm.acx100.enhanced_ps_transition_time =
3405 cpu_to_le16(adev->ps_enhanced_transition_time);
3407 acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT);
3408 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3409 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3410 acx_s_mwait(40);
3411 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3412 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3413 log(L_INIT, "power save mode change %s\n",
3414 (pm.acx111.
3415 wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful");
3416 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3417 * that power save mode change was successful. */
3418 /* FIXME: we shouldn't trigger a scan immediately after
3419 * fiddling with power save mode (since the firmware is sending
3420 * a NULL frame then). */
3422 #endif
3425 /***********************************************************************
3426 ** acx_s_update_card_settings
3428 ** Applies accumulated changes in various adev->xxxx members
3429 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3430 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3432 void acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
3434 unsigned mask;
3436 unsigned int i;
3438 for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
3439 if (acx_reg_domain_ids[i] == adev->reg_dom_id)
3440 break;
3442 if (sizeof(acx_reg_domain_ids) == i) {
3443 log(L_INIT, "Invalid or unsupported regulatory domain"
3444 " 0x%02X specified, falling back to FCC (USA)!"
3445 " Please report if this sounds fishy!\n",
3446 adev->reg_dom_id);
3447 i = 0;
3448 adev->reg_dom_id = acx_reg_domain_ids[i];
3450 /* since there was a mismatch, we need to force updating */
3451 do_set = 1;
3454 if (do_set) {
3455 acx_ie_generic_t dom;
3456 dom.m.bytes[0] = adev->reg_dom_id;
3457 acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3460 adev->reg_dom_chanmask = reg_domain_channel_masks[i];
3462 mask = (1 << (adev->channel - 1));
3463 if (!(adev->reg_dom_chanmask & mask)) {
3464 /* hmm, need to adjust our channel to reside within domain */
3465 mask = 1;
3466 for (i = 1; i <= 14; i++) {
3467 if (adev->reg_dom_chanmask & mask) {
3468 printk("%s: adjusting selected channel from %d "
3469 "to %d due to new regulatory domain\n",
3470 wiphy_name(adev->ieee->wiphy), adev->channel, i);
3471 adev->channel = i;
3472 break;
3474 mask <<= 1;
3479 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3481 u32 feature1, feature2;
3483 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3484 printk("%s: invalid sensitivity setting (1..3), "
3485 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3486 adev->sensitivity = 1;
3488 acx111_s_get_feature_config(adev, &feature1, &feature2);
3489 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3490 if (adev->sensitivity > 1)
3491 SET_BIT(feature1, FEATURE1_LOW_RX);
3492 if (adev->sensitivity > 2)
3493 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3494 acx111_s_feature_set(adev, feature1, feature2);
3498 void acx_s_update_card_settings(acx_device_t *adev)
3500 unsigned long flags;
3501 unsigned int start_scan = 0;
3502 int i;
3504 FN_ENTER;
3506 log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3507 adev->get_mask, adev->set_mask);
3509 /* Track dependencies betweed various settings */
3511 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3512 log(L_INIT, "important setting has been changed. "
3513 "Need to update packet templates, too\n");
3514 SET_BIT(adev->set_mask, SET_TEMPLATES);
3516 if (adev->set_mask & GETSET_CHANNEL) {
3517 /* This will actually tune RX/TX to the channel */
3518 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3519 switch (adev->mode) {
3520 case ACX_MODE_0_ADHOC:
3521 case ACX_MODE_3_AP:
3522 /* Beacons contain channel# - update them */
3523 SET_BIT(adev->set_mask, SET_TEMPLATES);
3526 switch (adev->mode) {
3527 case ACX_MODE_0_ADHOC:
3528 case ACX_MODE_2_STA:
3529 start_scan = 1;
3533 /* Apply settings */
3536 if (adev->get_mask & GETSET_STATION_ID) {
3537 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3538 const u8 *paddr;
3540 acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3541 paddr = &stationID[4];
3542 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3543 for (i = 0; i < ETH_ALEN; i++) {
3544 /* we copy the MAC address (reversed in
3545 * the card) to the netdevice's MAC
3546 * address, and on ifup it will be
3547 * copied into iwadev->dev_addr */
3548 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3550 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3551 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3554 if (adev->get_mask & GETSET_SENSITIVITY) {
3555 if ((RADIO_RFMD_11 == adev->radio_type)
3556 || (RADIO_MAXIM_0D == adev->radio_type)
3557 || (RADIO_RALINK_15 == adev->radio_type)) {
3558 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3559 } else {
3560 log(L_INIT, "don't know how to get sensitivity "
3561 "for radio type 0x%02X\n", adev->radio_type);
3562 adev->sensitivity = 0;
3564 log(L_INIT, "got sensitivity value %u\n", adev->sensitivity);
3566 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3569 if (adev->get_mask & GETSET_ANTENNA) {
3570 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3572 memset(antenna, 0, sizeof(antenna));
3573 acx_s_interrogate(adev, antenna,
3574 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3575 adev->antenna = antenna[4];
3576 log(L_INIT, "got antenna value 0x%02X\n", adev->antenna);
3577 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3580 if (adev->get_mask & GETSET_ED_THRESH) {
3581 if (IS_ACX100(adev)) {
3582 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3584 memset(ed_threshold, 0, sizeof(ed_threshold));
3585 acx_s_interrogate(adev, ed_threshold,
3586 ACX100_IE_DOT11_ED_THRESHOLD);
3587 adev->ed_threshold = ed_threshold[4];
3588 } else {
3589 log(L_INIT, "acx111 doesn't support ED\n");
3590 adev->ed_threshold = 0;
3592 log(L_INIT, "got Energy Detect (ED) threshold %u\n",
3593 adev->ed_threshold);
3594 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3597 if (adev->get_mask & GETSET_CCA) {
3598 if (IS_ACX100(adev)) {
3599 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3601 memset(cca, 0, sizeof(adev->cca));
3602 acx_s_interrogate(adev, cca,
3603 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3604 adev->cca = cca[4];
3605 } else {
3606 log(L_INIT, "acx111 doesn't support CCA\n");
3607 adev->cca = 0;
3609 log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n",
3610 adev->cca);
3611 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3614 if (adev->get_mask & GETSET_REG_DOMAIN) {
3615 acx_ie_generic_t dom;
3617 acx_s_interrogate(adev, &dom,
3618 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3619 adev->reg_dom_id = dom.m.bytes[0];
3620 acx_s_set_sane_reg_domain(adev, 0);
3621 log(L_INIT, "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3622 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3625 if (adev->set_mask & GETSET_STATION_ID) {
3626 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3627 u8 *paddr;
3629 paddr = &stationID[4];
3630 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3631 for (i = 0; i < ETH_ALEN; i++) {
3632 /* copy the MAC address we obtained when we noticed
3633 * that the ethernet iface's MAC changed
3634 * to the card (reversed in
3635 * the card!) */
3636 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3638 acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3639 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3642 if (adev->set_mask & SET_STA_LIST) {
3643 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3645 if (adev->set_mask & SET_RATE_FALLBACK) {
3646 u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
3648 /* configure to not do fallbacks when not in auto rate mode */
3649 rate[4] =
3650 (adev->
3651 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3652 log(L_INIT, "updating Tx fallback to %u retries\n", rate[4]);
3653 acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK);
3654 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3656 if (adev->set_mask & GETSET_TXPOWER) {
3657 log(L_INIT, "updating transmit power: %u dBm\n",
3658 adev->tx_level_dbm);
3659 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3660 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3663 if (adev->set_mask & GETSET_SENSITIVITY) {
3664 log(L_INIT, "updating sensitivity value: %u\n",
3665 adev->sensitivity);
3666 switch (adev->radio_type) {
3667 case RADIO_RFMD_11:
3668 case RADIO_MAXIM_0D:
3669 case RADIO_RALINK_15:
3670 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3671 break;
3672 case RADIO_RADIA_16:
3673 case RADIO_UNKNOWN_17:
3674 acx111_s_sens_radio_16_17(adev);
3675 break;
3676 default:
3677 log(L_INIT, "don't know how to modify sensitivity "
3678 "for radio type 0x%02X\n", adev->radio_type);
3680 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3683 if (adev->set_mask & GETSET_ANTENNA) {
3684 /* antenna */
3685 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3687 memset(antenna, 0, sizeof(antenna));
3688 antenna[4] = adev->antenna;
3689 log(L_INIT, "updating antenna value: 0x%02X\n", adev->antenna);
3690 acx_s_configure(adev, &antenna,
3691 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3692 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3695 if (adev->set_mask & GETSET_ED_THRESH) {
3696 /* ed_threshold */
3697 log(L_INIT, "updating Energy Detect (ED) threshold: %u\n",
3698 adev->ed_threshold);
3699 if (IS_ACX100(adev)) {
3700 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3702 memset(ed_threshold, 0, sizeof(ed_threshold));
3703 ed_threshold[4] = adev->ed_threshold;
3704 acx_s_configure(adev, &ed_threshold,
3705 ACX100_IE_DOT11_ED_THRESHOLD);
3706 } else
3707 log(L_INIT, "acx111 doesn't support ED!\n");
3708 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3711 if (adev->set_mask & GETSET_CCA) {
3712 /* CCA value */
3713 log(L_INIT, "updating Channel Clear Assessment "
3714 "(CCA) value: 0x%02X\n", adev->cca);
3715 if (IS_ACX100(adev)) {
3716 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3718 memset(cca, 0, sizeof(cca));
3719 cca[4] = adev->cca;
3720 acx_s_configure(adev, &cca,
3721 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3722 } else
3723 log(L_INIT, "acx111 doesn't support CCA!\n");
3724 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3727 if (adev->set_mask & GETSET_LED_POWER) {
3728 /* Enable Tx */
3729 log(L_INIT, "updating power LED status: %u\n", adev->led_power);
3731 acx_lock(adev, flags); /* acxpci_l_power_led expects that the lock is already taken! */
3732 if (IS_PCI(adev))
3733 acxpci_l_power_led(adev, adev->led_power);
3734 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3735 acx_unlock(adev, flags);
3738 if (adev->set_mask & GETSET_POWER_80211) {
3739 #if POWER_SAVE_80211
3740 acx_s_update_80211_powersave_mode(adev);
3741 #endif
3742 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3745 if (adev->set_mask & GETSET_CHANNEL) {
3746 /* channel */
3747 log(L_INIT, "updating channel to: %u\n", adev->channel);
3748 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3751 if (adev->set_mask & GETSET_TX) {
3752 /* set Tx */
3753 log(L_INIT, "updating: %s Tx\n",
3754 adev->tx_disabled ? "disable" : "enable");
3755 if (adev->tx_disabled)
3756 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3757 else {
3758 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3759 &adev->channel, 1);
3760 FIXME();
3761 /* This needs to be keyed on WEP? */
3762 /* acx111_s_feature_on(adev, 0,
3763 FEATURE2_NO_TXCRYPT |
3764 FEATURE2_SNIFFER); */
3765 acx_wake_queue(adev->ieee, NULL);
3767 CLEAR_BIT(adev->set_mask, GETSET_TX);
3770 if (adev->set_mask & GETSET_RX) {
3771 /* Enable Rx */
3772 log(L_INIT, "updating: enable Rx on channel: %u\n",
3773 adev->channel);
3774 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3775 CLEAR_BIT(adev->set_mask, GETSET_RX);
3778 if (adev->set_mask & GETSET_RETRY) {
3779 u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
3780 u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
3782 log(L_INIT,
3783 "updating short retry limit: %u, long retry limit: %u\n",
3784 adev->short_retry, adev->long_retry);
3785 short_retry[0x4] = adev->short_retry;
3786 long_retry[0x4] = adev->long_retry;
3787 acx_s_configure(adev, &short_retry,
3788 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
3789 acx_s_configure(adev, &long_retry,
3790 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
3791 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3794 if (adev->set_mask & SET_MSDU_LIFETIME) {
3795 u8 xmt_msdu_lifetime[4 +
3796 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3798 log(L_INIT, "updating tx MSDU lifetime: %u\n",
3799 adev->msdu_lifetime);
3800 *(u32 *) & xmt_msdu_lifetime[4] =
3801 cpu_to_le32((u32) adev->msdu_lifetime);
3802 acx_s_configure(adev, &xmt_msdu_lifetime,
3803 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
3804 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3807 if (adev->set_mask & GETSET_REG_DOMAIN) {
3808 log(L_INIT, "updating regulatory domain: 0x%02X\n",
3809 adev->reg_dom_id);
3810 acx_s_set_sane_reg_domain(adev, 1);
3811 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3813 if (adev->set_mask & GETSET_MODE ) {
3814 acx111_s_feature_on(adev, 0,
3815 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3816 switch (adev->mode) {
3817 case ACX_MODE_3_AP:
3818 adev->aid = 0;
3819 //acx111_s_feature_off(adev, 0,
3820 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3821 MAC_COPY(adev->bssid, adev->dev_addr);
3822 acx_s_cmd_join_bssid(adev, adev->dev_addr);
3823 break;
3824 case ACX_MODE_MONITOR:
3825 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3826 break;
3827 case ACX_MODE_0_ADHOC:
3828 case ACX_MODE_2_STA:
3829 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3830 break;
3831 default:
3832 break;
3834 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3836 if (adev->set_mask & SET_TEMPLATES) {
3837 switch (adev->mode)
3839 case ACX_MODE_3_AP:
3840 acx_s_set_tim_template(adev);
3841 break;
3842 default:
3843 break;
3845 if (adev->beacon_cache)
3847 acx_s_set_beacon_template(adev, adev->beacon_cache);
3848 dev_kfree_skb(adev->beacon_cache);
3849 adev->beacon_cache = NULL;
3851 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3854 if (adev->set_mask & SET_RXCONFIG) {
3855 acx_s_initialize_rx_config(adev);
3856 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3859 if (adev->set_mask & GETSET_RESCAN) {
3860 /* switch (adev->mode) {
3861 case ACX_MODE_0_ADHOC:
3862 case ACX_MODE_2_STA:
3863 start_scan = 1;
3864 break;
3866 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3869 if (adev->set_mask & GETSET_WEP) {
3870 /* encode */
3872 ie_dot11WEPDefaultKeyID_t dkey;
3873 #ifdef DEBUG_WEP
3874 struct {
3875 u16 type;
3876 u16 len;
3877 u8 val;
3878 } ACX_PACKED keyindic;
3879 #endif
3880 log(L_INIT, "updating WEP key settings\n");
3882 acx_s_set_wepkey(adev);
3883 if (adev->wep_enabled) {
3884 dkey.KeyID = adev->wep_current_index;
3885 log(L_INIT, "setting WEP key %u as default\n",
3886 dkey.KeyID);
3887 acx_s_configure(adev, &dkey,
3888 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
3889 #ifdef DEBUG_WEP
3890 keyindic.val = 3;
3891 acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
3892 #endif
3895 // start_scan = 1;
3896 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3899 if (adev->set_mask & SET_WEP_OPTIONS) {
3900 acx100_ie_wep_options_t options;
3902 if (IS_ACX111(adev)) {
3903 log(L_DEBUG,
3904 "setting WEP Options for acx111 is not supported\n");
3905 } else {
3906 log(L_INIT, "setting WEP Options\n");
3908 /* let's choose maximum setting: 4 default keys,
3909 * plus 10 other keys: */
3910 options.NumKeys =
3911 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3912 /* don't decrypt default key only,
3913 * don't override decryption: */
3914 options.WEPOption = 0;
3915 if (adev->mode == ACX_MODE_3_AP) {
3916 /* don't decrypt default key only,
3917 * override decryption mechanism: */
3918 options.WEPOption = 2;
3921 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3923 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3927 /* debug, rate, and nick don't need any handling */
3928 /* what about sniffing mode?? */
3930 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3931 adev->get_mask, adev->set_mask);
3933 /* end: */
3934 FN_EXIT0;
3937 #if 0
3938 /***********************************************************************
3939 ** acx_e_after_interrupt_task
3941 static int acx_s_recalib_radio(acx_device_t * adev)
3943 if (IS_ACX111(adev)) {
3944 acx111_cmd_radiocalib_t cal;
3946 /* automatic recalibration, choose all methods: */
3947 cal.methods = cpu_to_le32(0x8000000f);
3948 /* automatic recalibration every 60 seconds (value in TUs)
3949 * I wonder what the firmware default here is? */
3950 cal.interval = cpu_to_le32(58594);
3951 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3952 &cal, sizeof(cal),
3953 CMD_TIMEOUT_MS(100));
3954 } else {
3955 /* On ACX100, we need to recalibrate the radio
3956 * by issuing a GETSET_TX|GETSET_RX */
3957 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3958 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3959 (OK ==
3960 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3961 &adev->channel, 1))
3962 && (OK ==
3963 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3964 &adev->channel, 1)))
3965 return OK;
3966 return NOT_OK;
3969 #endif // if 0
3970 #if 0
3971 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3973 int res;
3975 /* this helps with ACX100 at least;
3976 * hopefully ACX111 also does a
3977 * recalibration here */
3979 /* clear flag beforehand, since we want to make sure
3980 * it's cleared; then only set it again on specific circumstances */
3981 CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3983 /* better wait a bit between recalibrations to
3984 * prevent overheating due to torturing the card
3985 * into working too long despite high temperature
3986 * (just a safety measure) */
3987 if (adev->recalib_time_last_success
3988 && time_before(jiffies, adev->recalib_time_last_success
3989 + RECALIB_PAUSE * 60 * HZ)) {
3990 if (adev->recalib_msg_ratelimit <= 4) {
3991 printk("%s: less than " STRING(RECALIB_PAUSE)
3992 " minutes since last radio recalibration, "
3993 "not recalibrating (maybe card is too hot?)\n",
3994 wiphy_name(adev->ieee->wiphy));
3995 adev->recalib_msg_ratelimit++;
3996 if (adev->recalib_msg_ratelimit == 5)
3997 printk("disabling above message until next recalib\n");
3999 return;
4002 adev->recalib_msg_ratelimit = 0;
4004 /* note that commands sometimes fail (card busy),
4005 * so only clear flag if we were fully successful */
4006 res = acx_s_recalib_radio(adev);
4007 if (res == OK) {
4008 printk("%s: successfully recalibrated radio\n",
4009 wiphy_name(adev->ieee->wiphy));
4010 adev->recalib_time_last_success = jiffies;
4011 adev->recalib_failure_count = 0;
4012 } else {
4013 /* failed: resubmit, but only limited
4014 * amount of times within some time range
4015 * to prevent endless loop */
4017 adev->recalib_time_last_success = 0; /* we failed */
4019 /* if some time passed between last
4020 * attempts, then reset failure retry counter
4021 * to be able to do next recalib attempt */
4022 if (time_after
4023 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
4024 adev->recalib_failure_count = 0;
4026 if (adev->recalib_failure_count < 5) {
4027 /* increment inside only, for speedup of outside path */
4028 adev->recalib_failure_count++;
4029 adev->recalib_time_last_attempt = jiffies;
4030 acx_schedule_task(adev,
4031 ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
4035 #endif // if 0
4037 void acx_e_after_interrupt_task(struct work_struct *work)
4039 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
4040 unsigned long flags;
4042 FN_ENTER;
4044 acx_lock(adev, flags);
4046 if (!adev->after_interrupt_jobs || !adev->initialized)
4047 goto end; /* no jobs to do */
4049 /* we see lotsa tx errors */
4050 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) {
4051 // acx_s_after_interrupt_recalib(adev);
4054 /* a poor interrupt code wanted to do update_card_settings() */
4055 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) {
4056 if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
4057 acx_unlock(adev, flags);
4058 acx_s_update_card_settings(adev);
4059 acx_lock(adev, flags);
4061 CLEAR_BIT(adev->after_interrupt_jobs,
4062 ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4065 /* 1) we detected that no Scan_Complete IRQ came from fw, or
4066 ** 2) we found too many STAs */
4067 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) {
4068 log(L_IRQ, "sending a stop scan cmd...\n");
4069 acx_unlock(adev, flags);
4070 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
4071 acx_lock(adev, flags);
4072 /* HACK: set the IRQ bit, since we won't get a
4073 * scan complete IRQ any more on ACX111 (works on ACX100!),
4074 * since _we_, not a fw, have stopped the scan */
4075 SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
4076 CLEAR_BIT(adev->after_interrupt_jobs,
4077 ACX_AFTER_IRQ_CMD_STOP_SCAN);
4080 /* either fw sent Scan_Complete or we detected that
4081 ** no Scan_Complete IRQ came from fw. Finish scanning,
4082 ** pick join partner if any */
4083 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) {
4084 /* + scan kills current join status - restore it
4085 ** (do we need it for STA?) */
4086 /* + does it happen only with active scans?
4087 ** active and passive scans? ALL scans including
4088 ** background one? */
4089 /* + was not verified that everything is restored
4090 ** (but at least we start to emit beacons again) */
4091 CLEAR_BIT(adev->after_interrupt_jobs,
4092 ACX_AFTER_IRQ_COMPLETE_SCAN);
4095 /* STA auth or assoc timed out, start over again */
4097 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) {
4098 log(L_IRQ, "sending a start_scan cmd...\n");
4099 CLEAR_BIT(adev->after_interrupt_jobs,
4100 ACX_AFTER_IRQ_RESTART_SCAN);
4103 /* whee, we got positive assoc response! 8) */
4104 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) {
4105 CLEAR_BIT(adev->after_interrupt_jobs,
4106 ACX_AFTER_IRQ_CMD_ASSOCIATE);
4108 end:
4109 if(adev->after_interrupt_jobs)
4111 printk("Jobs still to be run: %x\n",adev->after_interrupt_jobs);
4112 adev->after_interrupt_jobs = 0;
4114 acx_unlock(adev, flags);
4115 // acx_sem_unlock(adev);
4116 FN_EXIT0;
4120 /***********************************************************************
4121 ** acx_schedule_task
4123 ** Schedule the call of the after_interrupt method after leaving
4124 ** the interrupt context.
4126 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
4128 if (!adev->after_interrupt_jobs)
4130 SET_BIT(adev->after_interrupt_jobs, set_flag);
4131 schedule_work(&adev->after_interrupt_task);
4136 /***********************************************************************
4138 void acx_init_task_scheduler(acx_device_t * adev)
4140 /* configure task scheduler */
4141 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4145 /***********************************************************************
4146 ** acx_s_start
4148 void acx_s_start(acx_device_t * adev)
4150 FN_ENTER;
4153 * Ok, now we do everything that can possibly be done with ioctl
4154 * calls to make sure that when it was called before the card
4155 * was up we get the changes asked for
4158 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4159 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4160 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4161 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4163 log(L_INIT, "updating initial settings on iface activation\n");
4164 acx_s_update_card_settings(adev);
4166 FN_EXIT0;
4170 /***********************************************************************
4171 ** acx_update_capabilities
4172 *//*
4173 void acx_update_capabilities(acx_device_t * adev)
4175 u16 cap = 0;
4177 switch (adev->mode) {
4178 case ACX_MODE_3_AP:
4179 SET_BIT(cap, WF_MGMT_CAP_ESS);
4180 break;
4181 case ACX_MODE_0_ADHOC:
4182 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4183 break;
4184 */ /* other types of stations do not emit beacons */
4185 /* }
4187 if (adev->wep_restricted) {
4188 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4190 if (adev->cfgopt_dot11ShortPreambleOption) {
4191 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4193 if (adev->cfgopt_dot11PBCCOption) {
4194 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4196 if (adev->cfgopt_dot11ChannelAgility) {
4197 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4199 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4200 adev->capabilities, cap);
4201 adev->capabilities = cap;
4205 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4208 static void acx_s_select_opmode(acx_device_t * adev)
4210 int changed = 0;
4211 FN_ENTER;
4213 if (adev->interface.operating) {
4214 switch (adev->interface.type) {
4215 case IEEE80211_IF_TYPE_AP:
4216 if (adev->mode != ACX_MODE_3_AP)
4218 adev->mode = ACX_MODE_3_AP;
4219 changed = 1;
4221 break;
4222 case IEEE80211_IF_TYPE_IBSS:
4223 if (adev->mode != ACX_MODE_0_ADHOC)
4225 adev->mode = ACX_MODE_0_ADHOC;
4226 changed = 1;
4228 break;
4229 case IEEE80211_IF_TYPE_STA:
4230 if (adev->mode != ACX_MODE_2_STA)
4232 adev->mode = ACX_MODE_2_STA;
4233 changed = 1;
4235 break;
4236 case IEEE80211_IF_TYPE_WDS:
4237 default:
4238 if (adev->mode != ACX_MODE_OFF)
4240 adev->mode = ACX_MODE_OFF;
4241 changed = 1;
4243 break;
4245 } else {
4246 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4248 if (adev->mode != ACX_MODE_MONITOR)
4250 adev->mode = ACX_MODE_MONITOR;
4251 changed = 1;
4254 else
4256 if (adev->mode != ACX_MODE_OFF)
4258 adev->mode = ACX_MODE_OFF;
4259 changed = 1;
4263 if (changed)
4265 SET_BIT(adev->set_mask, GETSET_MODE);
4266 acx_s_update_card_settings(adev);
4267 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4270 FN_EXIT0;
4274 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4278 int acx_add_interface(struct ieee80211_hw *ieee,
4279 struct ieee80211_if_init_conf *conf)
4281 acx_device_t *adev = ieee2adev(ieee);
4282 unsigned long flags;
4283 int err = -EOPNOTSUPP;
4285 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4286 DECLARE_MAC_BUF(mac);
4287 #endif
4289 FN_ENTER;
4290 acx_lock(adev, flags);
4292 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4293 adev->interface.monitor++;
4294 } else {
4295 if (adev->interface.operating)
4296 goto out_unlock;
4297 adev->interface.operating = 1;
4299 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
4300 adev->vif = conf->vif;
4301 #else
4302 adev->interface.if_id = conf->if_id;
4303 #endif
4305 adev->interface.mac_addr = conf->mac_addr;
4306 adev->interface.type = conf->type;
4308 // adev->mode = conf->type;
4310 acx_unlock(adev, flags);
4312 if (adev->initialized)
4313 acx_s_select_opmode(adev);
4315 acx_lock(adev, flags);
4317 err = 0;
4319 printk(KERN_INFO "Virtual interface added "
4320 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
4321 "(type: 0x%08X), ID: %pd, MAC: %s\n",
4322 conf->type,
4323 conf->vif,
4324 print_mac(mac, conf->mac_addr));
4325 #else
4326 "(type: 0x%08X, ID: %d, MAC: %s)\n",
4327 conf->type,
4328 conf->if_id,
4329 print_mac(mac, conf->mac_addr));
4330 #endif
4332 out_unlock:
4333 acx_unlock(adev, flags);
4335 FN_EXIT0;
4336 return err;
4339 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4343 void acx_remove_interface(struct ieee80211_hw *hw,
4344 struct ieee80211_if_init_conf *conf)
4346 acx_device_t *adev = ieee2adev(hw);
4347 unsigned long flags;
4349 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4350 DECLARE_MAC_BUF(mac);
4351 #endif
4353 FN_ENTER;
4355 acx_lock(adev, flags);
4356 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4357 adev->interface.monitor--;
4358 // assert(bcm->interface.monitor >= 0);
4359 } else
4360 adev->interface.operating = 0;
4362 printk("Removing interface: %d %d\n", adev->interface.operating, conf->type);
4363 acx_unlock(adev, flags);
4365 if (adev->initialized)
4366 acx_s_select_opmode(adev);
4367 flush_scheduled_work();
4369 printk(KERN_INFO "Virtual interface removed "
4370 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
4371 "(type: 0x%08X, ID: %pd, MAC: %s)\n",
4372 conf->type,
4373 conf->vif,
4374 print_mac(mac, conf->mac_addr));
4376 #else
4377 "(type: 0x%08X, ID: %d, MAC: %s)\n",
4378 conf->type, conf->if_id, print_mac(mac, conf->mac_addr));
4379 #endif
4380 FN_EXIT0;
4383 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4387 int acx_net_reset(struct ieee80211_hw *ieee)
4389 acx_device_t *adev = ieee2adev(ieee);
4390 FN_ENTER;
4391 if (IS_PCI(adev))
4392 acxpci_s_reset_dev(adev);
4393 else
4394 TODO();
4396 FN_EXIT0;
4397 return 0;
4401 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4404 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4406 int result;
4408 FN_ENTER;
4410 acx_sem_lock(adev);
4411 adev->rx_status.channel = channel;
4412 adev->rx_status.freq = freq;
4414 adev->channel = channel;
4415 /* hmm, the following code part is strange, but this is how
4416 * it was being done before... */
4417 log(L_IOCTL, "Changing to channel %d\n", channel);
4418 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4419 result = -EINPROGRESS; /* need to call commit handler */
4421 acx_sem_unlock(adev);
4422 FN_EXIT1(result);
4423 return result;
4427 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4430 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4432 acx_device_t *adev = ieee2adev(hw);
4433 unsigned long flags;
4434 #if 0
4435 int change = 0;
4436 #endif
4437 FN_ENTER;
4439 acx_lock(adev, flags);
4440 //FIXME();
4441 if (!adev->initialized) {
4442 acx_unlock(adev, flags);
4443 return 0;
4445 if (conf->beacon_int != adev->beacon_interval)
4446 adev->beacon_interval = conf->beacon_int;
4447 if (conf->channel != adev->channel) {
4448 acx_unlock(adev, flags);
4449 acx_selectchannel(adev, conf->channel,conf->freq);
4450 acx_lock(adev, flags);
4451 /* acx_schedule_task(adev,
4452 ACX_AFTER_IRQ_UPDATE_CARD_CFG
4453 */ /*+ ACX_AFTER_IRQ_RESTART_SCAN */ /*);*/
4456 if (conf->short_slot_time != adev->short_slot) {
4457 // assert(phy->type == BCM43xx_PHYTYPE_G);
4458 if (conf->short_slot_time)
4459 acx_short_slot_timing_enable(adev);
4460 else
4461 acx_short_slot_timing_disable(adev);
4462 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4465 adev->tx_disabled = !conf->radio_enabled;
4466 /* if (conf->power_level != 0){
4467 adev->tx_level_dbm = conf->power_level;
4468 acx_s_set_tx_level(adev, adev->tx_level_dbm);
4469 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4470 //acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4473 //FIXME: This does not seem to wake up:
4474 #if 0
4475 if (conf->power_level == 0) {
4476 if (radio->enabled)
4477 bcm43xx_radio_turn_off(bcm);
4478 } else {
4479 if (!radio->enabled)
4480 bcm43xx_radio_turn_on(bcm);
4482 #endif
4484 //TODO: phymode
4485 //TODO: antennas
4486 if (adev->set_mask > 0) {
4487 acx_unlock(adev, flags);
4488 acx_s_update_card_settings(adev);
4489 acx_lock(adev, flags);
4491 acx_unlock(adev, flags);
4493 FN_EXIT0;
4494 return 0;
4498 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4502 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
4503 extern int acx_config_interface(struct ieee80211_hw* ieee,
4504 struct ieee80211_vif *vif,
4505 struct ieee80211_if_conf *conf)
4507 acx_device_t *adev = ieee2adev(ieee);
4508 unsigned long flags;
4509 int err = -ENODEV;
4510 FN_ENTER;
4511 if (!adev->interface.operating)
4512 goto err_out;
4514 if (adev->initialized)
4515 acx_s_select_opmode(adev);
4517 acx_lock(adev, flags);
4519 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4520 && (adev->vif == vif)) {
4521 if (conf->bssid)
4523 adev->interface.bssid = conf->bssid;
4524 MAC_COPY(adev->bssid,conf->bssid);
4527 if ((conf->type == IEEE80211_IF_TYPE_AP)
4528 && (adev->vif == vif)) {
4529 #else
4530 int acx_config_interface(struct ieee80211_hw* ieee, int if_id,
4531 struct ieee80211_if_conf *conf)
4533 acx_device_t *adev = ieee2adev(ieee);
4534 unsigned long flags;
4535 int err = -ENODEV;
4536 FN_ENTER;
4537 if (!adev->interface.operating)
4538 goto err_out;
4540 if (adev->initialized)
4541 acx_s_select_opmode(adev);
4543 acx_lock(adev, flags);
4545 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4546 && (adev->interface.if_id == if_id)) {
4547 if (conf->bssid)
4549 adev->interface.bssid = conf->bssid;
4550 MAC_COPY(adev->bssid,conf->bssid);
4553 if ((conf->type == IEEE80211_IF_TYPE_AP)
4554 && (adev->interface.if_id == if_id)) {
4555 #endif
4557 if ((conf->ssid_len > 0) && conf->ssid)
4559 adev->essid_len = conf->ssid_len;
4560 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4561 SET_BIT(adev->set_mask, SET_TEMPLATES);
4564 if (conf->beacon != 0)
4566 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4567 adev->beacon_cache = conf->beacon;
4568 SET_BIT(adev->set_mask, SET_TEMPLATES);
4571 acx_unlock(adev, flags);
4573 if (adev->set_mask != 0)
4574 acx_s_update_card_settings(adev);
4575 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4576 err = 0;
4577 err_out:
4578 FN_EXIT1(err);
4579 return err;
4583 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4587 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4588 struct ieee80211_tx_queue_stats *stats)
4590 // acx_device_t *adev = ndev2adev(net_dev);
4591 struct ieee80211_tx_queue_stats_data *data;
4592 int err = -ENODEV;
4594 FN_ENTER;
4596 // acx_lock(adev, flags);
4597 data = &(stats->data[0]);
4598 data->len = 0;
4599 data->limit = TX_CNT;
4600 data->count = 0;
4601 // acx_unlock(adev, flags);
4603 FN_EXIT0;
4604 return err;
4607 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4611 int acx_net_conf_tx(struct ieee80211_hw *hw,
4612 int queue, const struct ieee80211_tx_queue_params *params)
4614 FN_ENTER;
4615 // TODO();
4616 FN_EXIT0;
4617 return 0;
4620 static void keymac_write(acx_device_t * adev, u16 index, const u32 * addr)
4622 /* for keys 0-3 there is no associated mac address */
4623 if (index < 4)
4624 return;
4626 index -= 4;
4627 if (1) {
4628 TODO();
4630 bcm43xx_shm_write32(bcm,
4631 BCM43xx_SHM_HWMAC,
4632 index * 2,
4633 cpu_to_be32(*addr));
4634 bcm43xx_shm_write16(bcm,
4635 BCM43xx_SHM_HWMAC,
4636 (index * 2) + 1,
4637 cpu_to_be16(*((u16 *)(addr + 1))));
4639 } else {
4640 if (index < 8) {
4641 TODO(); /* Put them in the macaddress filter */
4642 } else {
4643 TODO();
4644 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4645 Keep in mind to update the count of keymacs in 0x003 */
4651 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4655 int acx_clear_keys(acx_device_t * adev)
4657 static const u32 zero_mac[2] = { 0 };
4658 unsigned int i, j, nr_keys = 54;
4659 u16 offset;
4661 /* FixMe:Check for Number of Keys available */
4663 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4665 for (i = 0; i < nr_keys; i++) {
4666 adev->key[i].enabled = 0;
4667 /* returns for i < 4 immediately */
4668 keymac_write(adev, i, zero_mac);
4670 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4671 0x100 + (i * 2), 0x0000);
4673 for (j = 0; j < 8; j++) {
4674 offset =
4675 adev->security_offset + (j * 4) +
4676 (i * ACX_SEC_KEYSIZE);
4678 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4679 offset, 0x0000);
4683 return 1;
4687 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4691 int acx_key_write(acx_device_t * adev,
4692 u16 index, u8 algorithm,
4693 const struct ieee80211_key_conf *key, const u8 * mac_addr)
4695 // struct iw_point *dwrq = &wrqu->encoding;
4696 int result;
4698 FN_ENTER;
4700 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4701 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4703 // acx_sem_lock(adev);
4705 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4706 if (key->keylen > 0) {
4707 /* if index is 0 or invalid, use default key */
4708 if (index > 3)
4709 index = (int)adev->wep_current_index;
4710 if ((algorithm == ACX_SEC_ALGO_WEP) ||
4711 (algorithm == ACX_SEC_ALGO_WEP104)) {
4712 switch(key->keylen) {
4713 case 40 / 8:
4714 /* WEP 40-bit =
4715 40-bit entered key + 24 bit IV = 64-bit */
4716 adev->wep_keys[index].size = 13;
4717 break;
4718 case 104 / 8:
4719 /* WEP 104-bit =
4720 104-bit entered key + 24-bit IV = 128-bit */
4721 adev->wep_keys[index].size = 29;
4722 break;
4723 case 128 / 8:
4724 /* WEP 128-bit =
4725 128-bit entered key + 24 bit IV = 152-bit */
4726 adev->wep_keys[index].size = 16;
4727 break;
4728 default:
4729 adev->wep_keys[index].size = 0;
4730 return -EINVAL; /* shouldn't happen */
4733 memset(adev->wep_keys[index].key, 0,
4734 sizeof(adev->wep_keys[index].key));
4735 memcpy(adev->wep_keys[index].key, key, key->keylen);
4736 } else {
4737 /* set transmit key */
4738 if (index <= 3)
4739 adev->wep_current_index = index;
4740 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4741 /* complain if we were not just setting
4742 * the key mode */
4743 // result = -EINVAL;
4744 // goto end_unlock;
4745 // }
4749 adev->wep_enabled = (algorithm == ALG_WEP);
4751 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4753 if (algorithm & IW_ENCODE_OPEN) {
4754 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4755 adev->wep_restricted = 0;
4757 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4758 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4759 adev->wep_restricted = 1;
4762 // adev->auth_alg = algorithm;
4763 /* set flag to make sure the card WEP settings get updated */
4764 if (adev->wep_enabled) {
4765 SET_BIT(adev->set_mask, GETSET_WEP);
4766 acx_s_update_card_settings(adev);
4767 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4770 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4771 dwrq->length, extra, dwrq->flags);
4772 for (index = 0; index <= 3; index++) {
4773 if (adev->wep_keys[index].size) {
4774 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4775 adev->wep_keys[index].index,
4776 (int) adev->wep_keys[index].size,
4777 adev->wep_keys[index].key);
4781 result = -EINPROGRESS;
4782 // acx_sem_unlock(adev);
4784 FN_EXIT1(result);
4785 return result;
4791 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4795 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4796 int acx_net_set_key(struct ieee80211_hw *ieee,
4797 set_key_cmd cmd,
4798 u8 * addr, struct ieee80211_key_conf *key, int aid)
4799 #else
4800 int acx_net_set_key(struct ieee80211_hw *ieee,
4801 enum set_key_cmd cmd, const u8 *local_addr,
4802 const u8 * addr, struct ieee80211_key_conf *key)
4803 #endif
4805 // return 0;
4806 struct acx_device *adev = ieee2adev(ieee);
4807 unsigned long flags;
4808 u8 algorithm;
4809 u16 index;
4810 int err = -EINVAL;
4811 FN_ENTER;
4812 // TODO();
4813 switch (key->alg) {
4814 default:
4815 /* case ALG_NONE:
4816 case ALG_NULL:
4817 algorithm = ACX_SEC_ALGO_NONE;
4818 break;
4819 */ case ALG_WEP:
4820 if (key->keylen == 5)
4821 algorithm = ACX_SEC_ALGO_WEP;
4822 else
4823 algorithm = ACX_SEC_ALGO_WEP104;
4824 break;
4825 case ALG_TKIP:
4826 algorithm = ACX_SEC_ALGO_TKIP;
4827 break;
4828 case ALG_CCMP:
4829 algorithm = ACX_SEC_ALGO_AES;
4830 break;
4833 index = (u8) (key->keyidx);
4834 if (index >= ARRAY_SIZE(adev->key))
4835 goto out;
4836 acx_lock(adev, flags);
4837 switch (cmd) {
4838 case SET_KEY:
4839 err = acx_key_write(adev, index, algorithm, key, addr);
4840 if (err)
4841 goto out_unlock;
4842 key->hw_key_idx = index;
4843 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4844 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4845 adev->default_key_idx = index;*/
4846 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4847 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4848 #endif
4849 adev->key[index].enabled = 1;
4850 break;
4851 case DISABLE_KEY:
4852 adev->key[index].enabled = 0;
4853 err = 0;
4854 break;
4855 /* case ENABLE_COMPRESSION:
4856 case DISABLE_COMPRESSION:
4857 err = 0;
4858 break; */
4860 out_unlock:
4861 acx_unlock(adev, flags);
4862 out:
4863 FN_EXIT0;
4864 return err;
4869 /***********************************************************************
4870 ** Common function to parse ALL configoption struct formats
4871 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4872 ** FIXME: logging should be removed here and added to a /proc file instead
4874 ** Look into bcm43xx
4876 void
4877 acx_s_parse_configoption(acx_device_t * adev,
4878 const acx111_ie_configoption_t * pcfg)
4880 const u8 *pEle;
4881 int i;
4882 int is_acx111 = IS_ACX111(adev);
4884 if (acx_debug & L_DEBUG) {
4885 printk("configoption struct content:\n");
4886 acx_dump_bytes(pcfg, sizeof(*pcfg));
4889 if ((is_acx111 && (adev->eeprom_version == 5))
4890 || (!is_acx111 && (adev->eeprom_version == 4))
4891 || (!is_acx111 && (adev->eeprom_version == 5))) {
4892 /* these versions are known to be supported */
4893 } else {
4894 printk("unknown chip and EEPROM version combination (%s, v%d), "
4895 "don't know how to parse config options yet. "
4896 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4897 adev->eeprom_version);
4898 return;
4901 /* first custom-parse the first part which has chip-specific layout */
4903 pEle = (const u8 *)pcfg;
4905 pEle += 4; /* skip (type,len) header */
4907 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4908 pEle += sizeof(adev->cfgopt_NVSv);
4910 if (is_acx111) {
4911 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4912 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4914 adev->cfgopt_probe_delay = 200; /* good default value? */
4915 pEle += 2; /* FIXME: unknown, value 0x0001 */
4916 } else {
4917 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4918 pEle += sizeof(adev->cfgopt_MAC);
4920 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4921 pEle += sizeof(adev->cfgopt_probe_delay);
4922 if ((adev->cfgopt_probe_delay < 100)
4923 || (adev->cfgopt_probe_delay > 500)) {
4924 printk("strange probe_delay value %d, "
4925 "tweaking to 200\n", adev->cfgopt_probe_delay);
4926 adev->cfgopt_probe_delay = 200;
4930 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4931 pEle += sizeof(adev->cfgopt_eof_memory);
4933 printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n",
4934 adev->cfgopt_NVS_vendor_offs,
4935 adev->cfgopt_probe_delay, adev->cfgopt_eof_memory);
4937 adev->cfgopt_dot11CCAModes = *pEle++;
4938 adev->cfgopt_dot11Diversity = *pEle++;
4939 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4940 adev->cfgopt_dot11PBCCOption = *pEle++;
4941 adev->cfgopt_dot11ChannelAgility = *pEle++;
4942 adev->cfgopt_dot11PhyType = *pEle++;
4943 adev->cfgopt_dot11TempType = *pEle++;
4944 printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4945 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4946 adev->cfgopt_dot11CCAModes,
4947 adev->cfgopt_dot11Diversity,
4948 adev->cfgopt_dot11ShortPreambleOption,
4949 adev->cfgopt_dot11PBCCOption,
4950 adev->cfgopt_dot11ChannelAgility,
4951 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4953 /* then use common parsing for next part which has common layout */
4955 pEle++; /* skip table_count (6) */
4957 adev->cfgopt_antennas.type = pEle[0];
4958 adev->cfgopt_antennas.len = pEle[1];
4959 printk("AntennaID:%02X Len:%02X Data:",
4960 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4961 for (i = 0; i < pEle[1]; i++) {
4962 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4963 printk("%02X ", pEle[i + 2]);
4965 printk("\n");
4967 pEle += pEle[1] + 2;
4968 adev->cfgopt_power_levels.type = pEle[0];
4969 adev->cfgopt_power_levels.len = pEle[1];
4970 printk("PowerLevelID:%02X Len:%02X Data:",
4971 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4972 for (i = 0; i < pEle[1]; i++) {
4973 adev->cfgopt_power_levels.list[i] =
4974 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4975 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4977 printk("\n");
4979 pEle += pEle[1] * 2 + 2;
4980 adev->cfgopt_data_rates.type = pEle[0];
4981 adev->cfgopt_data_rates.len = pEle[1];
4982 printk("DataRatesID:%02X Len:%02X Data:",
4983 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4984 for (i = 0; i < pEle[1]; i++) {
4985 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4986 printk("%02X ", pEle[i + 2]);
4988 printk("\n");
4990 pEle += pEle[1] + 2;
4991 adev->cfgopt_domains.type = pEle[0];
4992 adev->cfgopt_domains.len = pEle[1];
4993 printk("DomainID:%02X Len:%02X Data:",
4994 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4995 for (i = 0; i < pEle[1]; i++) {
4996 adev->cfgopt_domains.list[i] = pEle[i + 2];
4997 printk("%02X ", pEle[i + 2]);
4999 printk("\n");
5001 pEle += pEle[1] + 2;
5002 adev->cfgopt_product_id.type = pEle[0];
5003 adev->cfgopt_product_id.len = pEle[1];
5004 for (i = 0; i < pEle[1]; i++) {
5005 adev->cfgopt_product_id.list[i] = pEle[i + 2];
5007 printk("ProductID:%02X Len:%02X Data:%.*s\n",
5008 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
5009 adev->cfgopt_product_id.len,
5010 (char *)adev->cfgopt_product_id.list);
5012 pEle += pEle[1] + 2;
5013 adev->cfgopt_manufacturer.type = pEle[0];
5014 adev->cfgopt_manufacturer.len = pEle[1];
5015 for (i = 0; i < pEle[1]; i++) {
5016 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
5018 printk("ManufacturerID:%02X Len:%02X Data:%.*s\n",
5019 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
5020 adev->cfgopt_manufacturer.len,
5021 (char *)adev->cfgopt_manufacturer.list);
5023 printk("EEPROM part:\n");
5024 for (i=0; i<58; i++) {
5025 printk("%02X =======> 0x%02X\n",
5026 i, (u8 *)adev->cfgopt_NVSv[i-2]);
5032 /***********************************************************************
5033 ** Linux Kernel Specific
5035 static int __init acx_e_init_module(void)
5037 int r1, r2;
5039 acx_struct_size_check();
5041 printk("acx: this driver is still EXPERIMENTAL\n"
5042 "acx: reading README file and/or Craig's HOWTO is "
5043 "recommended, visit http://acx100.sourceforge.net/wiki in case "
5044 "of further questions/discussion\n");
5046 #if defined(CONFIG_ACX_MAC80211_PCI)
5047 r1 = acxpci_e_init_module();
5048 #else
5049 r1 = -EINVAL;
5050 #endif
5051 #if defined(CONFIG_ACX_MAC80211_USB)
5052 r2 = acxusb_e_init_module();
5053 #else
5054 r2 = -EINVAL;
5055 #endif
5056 if (r2 && r1) /* both failed! */
5057 return r2 ? r2 : r1;
5058 /* return success if at least one succeeded */
5059 return 0;
5062 static void __exit acx_e_cleanup_module(void)
5064 #if defined(CONFIG_ACX_MAC80211_PCI)
5065 acxpci_e_cleanup_module();
5066 #endif
5067 #if defined(CONFIG_ACX_MAC80211_USB)
5068 acxusb_e_cleanup_module();
5069 #endif
5072 module_init(acx_e_init_module)
5073 module_exit(acx_e_cleanup_module)