more coding style fixes
[acx-mac80211.git] / common.c
blob3cd0a97c2e3de28f99d0458e86cf512f05ceff0c
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 static struct ieee80211_channel channels[] = {
1493 { .chan = 1,
1494 .freq = 2412},
1495 { .chan = 2,
1496 .freq = 2417},
1497 { .chan = 3,
1498 .freq = 2422},
1499 { .chan = 4,
1500 .freq = 2427},
1501 { .chan = 5,
1502 .freq = 2432},
1503 { .chan = 6,
1504 .freq = 2437},
1505 { .chan = 7,
1506 .freq = 2442},
1507 { .chan = 8,
1508 .freq = 2447},
1509 { .chan = 9,
1510 .freq = 2452},
1511 { .chan = 10,
1512 .freq = 2457},
1513 { .chan = 11,
1514 .freq = 2462},
1515 { .chan = 12,
1516 .freq = 2467},
1517 { .chan = 13,
1518 .freq = 2472},
1521 int acx_setup_modes(acx_device_t * adev)
1523 struct ieee80211_hw *hw = adev->ieee;
1524 struct ieee80211_hw_mode *mode;
1525 int err = -ENOMEM;
1527 FN_ENTER;
1529 if (IS_ACX111(adev)) {
1531 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);
1532 err = acx_setup_modes_gphy(adev);
1534 mode = &adev->modes[0];
1536 /* from the zd1211rw driver: - do we need to do the same? */
1538 memcpy(mode->channels, channels, sizeof(channels));
1539 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1542 mode->mode = MODE_IEEE80211G;
1543 mode->num_channels = ARRAY_SIZE(channels);
1544 mode->num_rates = 12;
1545 mode->rates = __acx_rates;
1546 } else {
1548 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1549 err = acx_setup_modes_bphy(adev);
1551 mode = &adev->modes[1];
1553 /* from the zd1211rw driver: - do we need to do the same? */
1555 memcpy(mode->channels, channels, sizeof(channels));
1556 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1559 mode->mode = MODE_IEEE80211B;
1560 mode->num_channels = ARRAY_SIZE(channels);
1561 mode->num_rates = 4;
1562 mode->rates = __acx_rates;
1565 /* if (err && adev->modes)
1566 kfree(adev->modes);*/
1568 mode->channels = channels;
1569 err = ieee80211_register_hwmode(hw, mode);
1571 FN_EXIT1(err);
1572 return err;
1576 /***********************************************************************
1577 ** acx_fill_beacon_or_proberesp_template
1579 ** Origin: derived from rt2x00 project
1581 static int
1582 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1583 struct acx_template_beacon *templ,
1584 struct sk_buff* skb /* in host order! */)
1586 FN_ENTER;
1588 memcpy(templ,skb->data, skb->len);
1589 FN_EXIT1(skb->len);
1590 return skb->len;
1593 /***********************************************************************
1594 ** acx_s_set_beacon_template
1598 static int
1599 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1601 struct acx_template_beacon bcn;
1602 int len, result;
1604 FN_ENTER;
1605 printk("Size of template: %08X, Size of beacon: %08X\n",sizeof(struct acx_template_beacon),skb->len);
1606 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1607 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1609 FN_EXIT1(result);
1610 return result;
1613 /***********************************************************************
1614 ** acx_cmd_join_bssid
1616 ** Common code for both acx100 and acx111.
1618 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1619 static const u8 bitpos2genframe_txrate[] = {
1620 10, /* 0. 1 Mbit/s */
1621 20, /* 1. 2 Mbit/s */
1622 55, /* 2. 5.5 Mbit/s */
1623 0x0B, /* 3. 6 Mbit/s */
1624 0x0F, /* 4. 9 Mbit/s */
1625 110, /* 5. 11 Mbit/s */
1626 0x0A, /* 6. 12 Mbit/s */
1627 0x0E, /* 7. 18 Mbit/s */
1628 220, /* 8. 22 Mbit/s */
1629 0x09, /* 9. 24 Mbit/s */
1630 0x0D, /* 10. 36 Mbit/s */
1631 0x08, /* 11. 48 Mbit/s */
1632 0x0C, /* 12. 54 Mbit/s */
1633 10, /* 13. 1 Mbit/s, should never happen */
1634 10, /* 14. 1 Mbit/s, should never happen */
1635 10, /* 15. 1 Mbit/s, should never happen */
1638 /* Looks scary, eh?
1639 ** Actually, each one compiled into one AND and one SHIFT,
1640 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1641 static inline unsigned int rate111to5bits(unsigned int rate)
1643 return (rate & 0x7)
1644 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1645 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1649 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1651 acx_joinbss_t tmp;
1652 int dtim_interval;
1653 int i;
1655 if (mac_is_zero(bssid))
1656 return;
1658 FN_ENTER;
1660 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1661 1 : adev->dtim_interval;
1663 memset(&tmp, 0, sizeof(tmp));
1665 for (i = 0; i < ETH_ALEN; i++) {
1666 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1669 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1671 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1672 ** are sent with one of these rates */
1673 if (IS_ACX111(adev)) {
1674 /* It was experimentally determined that rates_basic
1675 ** can take 11g rates as well, not only rates
1676 ** defined with JOINBSS_RATES_BASIC111_nnn.
1677 ** Just use RATE111_nnn constants... */
1678 tmp.u.acx111.dtim_interval = dtim_interval;
1679 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1680 log(L_ASSOC, "rates_basic:%04X, rates_supported:%04X\n",
1681 adev->rate_basic, adev->rate_oper);
1682 } else {
1683 tmp.u.acx100.dtim_interval = dtim_interval;
1684 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1685 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1686 log(L_ASSOC, "rates_basic:%04X->%02X, "
1687 "rates_supported:%04X->%02X\n",
1688 adev->rate_basic, tmp.u.acx100.rates_basic,
1689 adev->rate_oper, tmp.u.acx100.rates_supported);
1692 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1693 ** will be sent (rate/modulation/preamble) */
1694 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1695 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1696 /* we can use short pre *if* all peers can understand it */
1697 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1699 /* we switch fw to STA mode in MONITOR mode, it seems to be
1700 ** the only mode where fw does not emit beacons by itself
1701 ** but allows us to send anything (we really want to retain
1702 ** ability to tx arbitrary frames in MONITOR mode)
1704 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1705 tmp.channel = adev->channel;
1706 tmp.essid_len = adev->essid_len;
1708 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1709 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1711 log(L_ASSOC|L_DEBUG, "BSS_Type = %u\n", tmp.macmode);
1712 acxlog_mac(L_ASSOC|L_DEBUG, "JoinBSSID MAC:", adev->bssid, "\n");
1714 /* acx_update_capabilities(adev); */
1715 FN_EXIT0;
1718 /***********************************************************************
1719 ** acxpci_i_set_multicast_list
1720 ** FIXME: most likely needs refinement
1723 void acx_i_set_multicast_list(struct ieee80211_hw *hw,
1724 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1725 unsigned short netflags, int mc_count)
1726 #else
1727 unsigned int changed_flags,
1728 unsigned int *total_flags,
1729 int mc_count, struct dev_addr_list *mc_list)
1730 #endif
1732 acx_device_t *adev = ieee2adev(hw);
1733 unsigned long flags;
1735 FN_ENTER;
1737 acx_lock(adev, flags);
1739 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
1740 changed_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1741 FIF_CONTROL | FIF_OTHER_BSS);
1742 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1743 FIF_CONTROL | FIF_OTHER_BSS);
1744 /* if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1745 return; */
1746 #endif
1748 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1749 if (netflags & (IFF_PROMISC | IFF_ALLMULTI)) {
1750 #else
1751 if (*total_flags) {
1752 #endif
1753 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1754 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1755 SET_BIT(adev->set_mask, SET_RXCONFIG);
1756 /* let kernel know in case *we* needed to set promiscuous */
1757 } else {
1758 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1759 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1760 SET_BIT(adev->set_mask, SET_RXCONFIG);
1763 /* cannot update card settings directly here, atomic context */
1764 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
1766 acx_unlock(adev, flags);
1768 FN_EXIT0;
1771 /***********************************************************************
1772 ** acx111 feature config
1774 ** Obvious
1776 static int
1777 acx111_s_get_feature_config(acx_device_t * adev,
1778 u32 * feature_options, u32 * data_flow_options)
1780 struct acx111_ie_feature_config feat;
1782 FN_ENTER;
1784 if (!IS_ACX111(adev)) {
1785 return NOT_OK;
1788 memset(&feat, 0, sizeof(feat));
1790 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1791 FN_EXIT1(NOT_OK);
1792 return NOT_OK;
1794 log(L_DEBUG,
1795 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1796 feat.feature_options, feat.data_flow_options);
1798 if (feature_options)
1799 *feature_options = le32_to_cpu(feat.feature_options);
1800 if (data_flow_options)
1801 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1803 FN_EXIT0;
1804 return OK;
1808 static int
1809 acx111_s_set_feature_config(acx_device_t * adev,
1810 u32 feature_options, u32 data_flow_options,
1811 unsigned int mode
1812 /* 0 == remove, 1 == add, 2 == set */ )
1814 struct acx111_ie_feature_config feat;
1816 FN_ENTER;
1818 if (!IS_ACX111(adev)) {
1819 FN_EXIT1(NOT_OK);
1820 return NOT_OK;
1823 if ((mode < 0) || (mode > 2)) {
1824 FN_EXIT1(NOT_OK);
1825 return NOT_OK;
1828 if (mode != 2)
1829 /* need to modify old data */
1830 acx111_s_get_feature_config(adev, &feat.feature_options,
1831 &feat.data_flow_options);
1832 else {
1833 /* need to set a completely new value */
1834 feat.feature_options = 0;
1835 feat.data_flow_options = 0;
1838 if (mode == 0) { /* remove */
1839 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1840 CLEAR_BIT(feat.data_flow_options,
1841 cpu_to_le32(data_flow_options));
1842 } else { /* add or set */
1843 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1844 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1847 log(L_DEBUG,
1848 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1849 "new: feature 0x%08X dataflow 0x%08X\n",
1850 feature_options, data_flow_options, mode,
1851 le32_to_cpu(feat.feature_options),
1852 le32_to_cpu(feat.data_flow_options));
1854 if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1855 FN_EXIT1(NOT_OK);
1856 return NOT_OK;
1859 FN_EXIT0;
1860 return OK;
1863 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1865 return acx111_s_set_feature_config(adev, f, d, 0);
1867 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1869 return acx111_s_set_feature_config(adev, f, d, 1);
1871 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1873 return acx111_s_set_feature_config(adev, f, d, 2);
1877 /***********************************************************************
1878 ** acx100_s_init_memory_pools
1880 static int
1881 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1883 acx100_ie_memblocksize_t MemoryBlockSize;
1884 acx100_ie_memconfigoption_t MemoryConfigOption;
1885 int TotalMemoryBlocks;
1886 int RxBlockNum;
1887 int TotalRxBlockSize;
1888 int TxBlockNum;
1889 int TotalTxBlockSize;
1891 FN_ENTER;
1893 /* Let's see if we can follow this:
1894 first we select our memory block size (which I think is
1895 completely arbitrary) */
1896 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1898 /* Then we alert the card to our decision of block size */
1899 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
1900 goto bad;
1903 /* We figure out how many total blocks we can create, using
1904 the block size we chose, and the beginning and ending
1905 memory pointers, i.e.: end-start/size */
1906 TotalMemoryBlocks =
1907 (le32_to_cpu(mmt->PoolEnd) -
1908 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1910 log(L_DEBUG, "TotalMemoryBlocks=%u (%u bytes)\n",
1911 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1913 /* MemoryConfigOption.DMA_config bitmask:
1914 access to ACX memory is to be done:
1915 0x00080000 using PCI conf space?!
1916 0x00040000 using IO instructions?
1917 0x00000000 using memory access instructions
1918 0x00020000 using local memory block linked list (else what?)
1919 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1921 if (IS_PCI(adev)) {
1922 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1923 /* Declare start of the Rx host pool */
1924 MemoryConfigOption.pRxHostDesc =
1925 cpu2acx(adev->rxhostdesc_startphy);
1926 log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
1927 acx2cpu(MemoryConfigOption.pRxHostDesc),
1928 (long)adev->rxhostdesc_startphy);
1929 } else {
1930 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1933 /* 50% of the allotment of memory blocks go to tx descriptors */
1934 TxBlockNum = TotalMemoryBlocks / 2;
1935 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1937 /* and 50% go to the rx descriptors */
1938 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1939 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1941 /* size of the tx and rx descriptor queues */
1942 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1943 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1944 log(L_DEBUG, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u "
1945 "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum,
1946 TotalTxBlockSize, TotalRxBlockSize);
1949 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1950 MemoryConfigOption.rx_mem =
1951 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1953 /* align the rx descriptor queue to units of 0x20
1954 * and offset it by the tx descriptor queue */
1955 MemoryConfigOption.tx_mem =
1956 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
1957 0x1f) & ~0x1f);
1958 log(L_DEBUG, "rx_mem %08X rx_mem %08X\n", MemoryConfigOption.tx_mem,
1959 MemoryConfigOption.rx_mem);
1961 /* alert the device to our decision */
1962 if (OK !=
1963 acx_s_configure(adev, &MemoryConfigOption,
1964 ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
1965 goto bad;
1968 /* and tell the device to kick it into gear */
1969 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
1970 goto bad;
1972 FN_EXIT1(OK);
1973 return OK;
1974 bad:
1975 FN_EXIT1(NOT_OK);
1976 return NOT_OK;
1980 /***********************************************************************
1981 ** acx100_s_create_dma_regions
1983 ** Note that this fn messes up heavily with hardware, but we cannot
1984 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1986 /* OLD CODE? - let's rewrite it! */
1987 static int acx100_s_create_dma_regions(acx_device_t * adev)
1989 acx100_ie_queueconfig_t queueconf;
1990 acx_ie_memmap_t memmap;
1991 int res = NOT_OK;
1992 u32 tx_queue_start, rx_queue_start;
1994 FN_ENTER;
1996 /* read out the acx100 physical start address for the queues */
1997 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1998 goto fail;
2001 tx_queue_start = le32_to_cpu(memmap.QueueStart);
2002 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
2004 log(L_DEBUG, "initializing Queue Indicator\n");
2006 memset(&queueconf, 0, sizeof(queueconf));
2008 /* Not needed for PCI, so we can avoid setting them altogether */
2009 if (IS_USB(adev)) {
2010 queueconf.NumTxDesc = USB_TX_CNT;
2011 queueconf.NumRxDesc = USB_RX_CNT;
2014 /* calculate size of queues */
2015 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
2016 RX_CNT * sizeof(rxdesc_t) + 8);
2017 queueconf.NumTxQueues = 1; /* number of tx queues */
2018 /* sets the beginning of the tx descriptor queue */
2019 queueconf.TxQueueStart = memmap.QueueStart;
2020 /* done by memset: queueconf.TxQueuePri = 0; */
2021 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
2022 queueconf.QueueOptions = 1; /* auto reset descriptor */
2023 /* sets the end of the rx descriptor queue */
2024 queueconf.QueueEnd =
2025 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
2027 /* sets the beginning of the next queue */
2028 queueconf.HostQueueEnd =
2029 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
2030 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
2031 goto fail;
2034 if (IS_PCI(adev)) {
2035 /* sets the beginning of the rx descriptor queue, after the tx descrs */
2036 if (OK != acxpci_s_create_hostdesc_queues(adev))
2037 goto fail;
2038 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2041 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2042 goto fail;
2045 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
2046 0x1f) & ~0x1f);
2048 if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
2049 goto fail;
2052 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
2053 goto fail;
2056 res = OK;
2057 goto end;
2059 fail:
2060 acx_s_mwait(1000); /* ? */
2061 if (IS_PCI(adev))
2062 acxpci_free_desc_queues(adev);
2063 end:
2064 FN_EXIT1(res);
2065 return res;
2069 /***********************************************************************
2070 ** acx111_s_create_dma_regions
2072 ** Note that this fn messes heavily with hardware, but we cannot
2073 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2075 #define ACX111_PERCENT(percent) ((percent)/5)
2077 static int acx111_s_create_dma_regions(acx_device_t * adev)
2079 struct acx111_ie_memoryconfig memconf;
2080 struct acx111_ie_queueconfig queueconf;
2081 u32 tx_queue_start, rx_queue_start;
2083 FN_ENTER;
2085 /* Calculate memory positions and queue sizes */
2087 /* Set up our host descriptor pool + data pool */
2088 if (IS_PCI(adev)) {
2089 if (OK != acxpci_s_create_hostdesc_queues(adev))
2090 goto fail;
2093 memset(&memconf, 0, sizeof(memconf));
2094 /* the number of STAs (STA contexts) to support
2095 ** NB: was set to 1 and everything seemed to work nevertheless... */
2096 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
2097 /* specify the memory block size. Default is 256 */
2098 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
2099 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
2100 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
2101 /* set the count of our queues
2102 ** NB: struct acx111_ie_memoryconfig shall be modified
2103 ** if we ever will switch to more than one rx and/or tx queue */
2104 memconf.count_rx_queues = 1;
2105 memconf.count_tx_queues = 1;
2106 /* 0 == Busmaster Indirect Memory Organization, which is what we want
2107 * (using linked host descs with their allocated mem).
2108 * 2 == Generic Bus Slave */
2109 /* done by memset: memconf.options = 0; */
2110 /* let's use 25% for fragmentations and 75% for frame transfers
2111 * (specified in units of 5%) */
2112 memconf.fragmentation = ACX111_PERCENT(75);
2113 /* Rx descriptor queue config */
2114 memconf.rx_queue1_count_descs = RX_CNT;
2115 memconf.rx_queue1_type = 7; /* must be set to 7 */
2116 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2117 if (IS_PCI(adev)) {
2118 memconf.rx_queue1_host_rx_start =
2119 cpu2acx(adev->rxhostdesc_startphy);
2121 /* Tx descriptor queue config */
2122 memconf.tx_queue1_count_descs = TX_CNT;
2123 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2125 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
2126 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2127 ** But it is actually correct wrt IE numbers.
2128 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
2129 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2130 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2131 if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
2132 goto fail;
2135 acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
2137 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2138 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2140 log(L_INIT, "dump queue head (from card):\n"
2141 "len: %u\n"
2142 "tx_memory_block_address: %X\n"
2143 "rx_memory_block_address: %X\n"
2144 "tx1_queue address: %X\n"
2145 "rx1_queue address: %X\n",
2146 le16_to_cpu(queueconf.len),
2147 le32_to_cpu(queueconf.tx_memory_block_address),
2148 le32_to_cpu(queueconf.rx_memory_block_address),
2149 tx_queue_start, rx_queue_start);
2151 if (IS_PCI(adev))
2152 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2154 FN_EXIT1(OK);
2155 return OK;
2156 fail:
2157 if (IS_PCI(adev))
2158 acxpci_free_desc_queues(adev);
2160 FN_EXIT1(NOT_OK);
2161 return NOT_OK;
2165 /***********************************************************************
2167 static void acx_s_initialize_rx_config(acx_device_t * adev)
2169 struct {
2170 u16 id;
2171 u16 len;
2172 u16 rx_cfg1;
2173 u16 rx_cfg2;
2174 } ACX_PACKED cfg;
2175 switch (adev->mode) {
2176 case ACX_MODE_MONITOR:
2177 adev->rx_config_1 = (u16) (0
2178 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2179 /* | RX_CFG1_FILTER_SSID */
2180 /* | RX_CFG1_FILTER_BCAST */
2181 /* | RX_CFG1_RCV_MC_ADDR1 */
2182 /* | RX_CFG1_RCV_MC_ADDR0 */
2183 /* | RX_CFG1_FILTER_ALL_MULTI */
2184 /* | RX_CFG1_FILTER_BSSID */
2185 /* | RX_CFG1_FILTER_MAC */
2186 | RX_CFG1_RCV_PROMISCUOUS
2187 | RX_CFG1_INCLUDE_FCS
2188 /* | RX_CFG1_INCLUDE_PHY_HDR */
2190 adev->rx_config_2 = (u16) (0
2191 | RX_CFG2_RCV_ASSOC_REQ
2192 | RX_CFG2_RCV_AUTH_FRAMES
2193 | RX_CFG2_RCV_BEACON_FRAMES
2194 | RX_CFG2_RCV_CONTENTION_FREE
2195 | RX_CFG2_RCV_CTRL_FRAMES
2196 | RX_CFG2_RCV_DATA_FRAMES
2197 | RX_CFG2_RCV_BROKEN_FRAMES
2198 | RX_CFG2_RCV_MGMT_FRAMES
2199 | RX_CFG2_RCV_PROBE_REQ
2200 | RX_CFG2_RCV_PROBE_RESP
2201 | RX_CFG2_RCV_ACK_FRAMES
2202 | RX_CFG2_RCV_OTHER);
2203 break;
2204 default:
2205 adev->rx_config_1 = (u16) (0
2206 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2207 /* | RX_CFG1_FILTER_SSID */
2208 /* | RX_CFG1_FILTER_BCAST */
2209 /* | RX_CFG1_RCV_MC_ADDR1 */
2210 /* | RX_CFG1_RCV_MC_ADDR0 */
2211 /* | RX_CFG1_FILTER_ALL_MULTI */
2212 /* | RX_CFG1_FILTER_BSSID */
2213 /* | RX_CFG1_FILTER_MAC */
2214 | RX_CFG1_RCV_PROMISCUOUS
2215 /* | RX_CFG1_INCLUDE_FCS */
2216 /* | RX_CFG1_INCLUDE_PHY_HDR */
2218 adev->rx_config_2 = (u16) (0
2219 | RX_CFG2_RCV_ASSOC_REQ
2220 | RX_CFG2_RCV_AUTH_FRAMES
2221 | RX_CFG2_RCV_BEACON_FRAMES
2222 | RX_CFG2_RCV_CONTENTION_FREE
2223 | RX_CFG2_RCV_CTRL_FRAMES
2224 | RX_CFG2_RCV_DATA_FRAMES
2225 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2226 | RX_CFG2_RCV_MGMT_FRAMES
2227 | RX_CFG2_RCV_PROBE_REQ
2228 | RX_CFG2_RCV_PROBE_RESP
2229 | RX_CFG2_RCV_ACK_FRAMES
2230 | RX_CFG2_RCV_OTHER);
2231 break;
2233 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2235 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2236 || (adev->firmware_numver >= 0x02000000))
2237 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2238 else
2239 adev->phy_header_len = 0;
2241 log(L_INIT, "setting RXconfig to %04X:%04X\n",
2242 adev->rx_config_1, adev->rx_config_2);
2243 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2244 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2245 acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
2249 /***********************************************************************
2250 ** FIXME: this should be solved in a general way for all radio types
2251 ** by decoding the radio firmware module,
2252 ** since it probably has some standard structure describing how to
2253 ** set the power level of the radio module which it controls.
2254 ** Or maybe not, since the radio module probably has a function interface
2255 ** instead which then manages Tx level programming :-\
2257 ** Obvious
2259 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2261 struct acx111_ie_tx_level tx_level;
2263 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2264 * 1 (30mW) [15dBm]
2265 * 2 (10mW) [10dBm]
2266 * For now, just assume all other acx111 cards have the same.
2267 * FIXME: Ideally we would query it here, but we first need a
2268 * standard way to query individual configoptions easily.
2269 * Well, now we have proper cfgopt txpower variables, but this still
2270 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2271 if (level_dbm <= 12) {
2272 tx_level.level = 2; /* 10 dBm */
2273 adev->tx_level_dbm = 10;
2274 } else {
2275 tx_level.level = 1; /* 15 dBm */
2276 adev->tx_level_dbm = 15;
2278 if (level_dbm != adev->tx_level_dbm)
2279 log(L_INIT, "acx111 firmware has specific "
2280 "power levels only: adjusted %d dBm to %d dBm!\n",
2281 level_dbm, adev->tx_level_dbm);
2283 return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
2286 static int acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
2288 if (IS_ACX111(adev)) {
2289 return acx111_s_set_tx_level(adev, level_dbm);
2291 if (IS_PCI(adev)) {
2292 return acx100pci_s_set_tx_level(adev, level_dbm);
2295 return OK;
2299 /***********************************************************************
2300 ** acx_s_set_defaults
2302 void acx_s_set_defaults(acx_device_t * adev)
2304 struct ieee80211_conf *conf = &adev->ieee->conf;
2305 unsigned long flags;
2307 FN_ENTER;
2309 acx_lock(adev, flags);
2310 /* do it before getting settings, prevent bogus channel 0 warning */
2311 adev->channel = 1;
2313 /* query some settings from the card.
2314 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2315 * query is REQUIRED, otherwise the card won't work correctly! */
2316 adev->get_mask =
2317 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2318 GETSET_REG_DOMAIN;
2319 /* Only ACX100 supports ED and CCA */
2320 if (IS_ACX100(adev))
2321 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2323 acx_unlock(adev, flags);
2325 acx_s_update_card_settings(adev);
2327 acx_lock(adev, flags);
2329 /* set our global interrupt mask */
2330 if (IS_PCI(adev))
2331 acxpci_set_interrupt_mask(adev);
2333 adev->led_power = 1; /* LED is active on startup */
2334 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2335 adev->brange_time_last_state_change = jiffies;
2337 /* copy the MAC address we just got from the card
2338 * into our MAC address used during current 802.11 session */
2339 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
2340 MAC_BCAST(adev->ap);
2342 adev->essid_len =
2343 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2344 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2345 adev->essid_active = 1;
2347 /* we have a nick field to waste, so why not abuse it
2348 * to announce the driver version? ;-) */
2349 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2351 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2352 /* first regulatory domain entry in EEPROM == default reg. domain */
2353 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2356 /* 0xffff would be better, but then we won't get a "scan complete"
2357 * interrupt, so our current infrastructure will fail: */
2358 adev->scan_count = 1;
2359 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2360 adev->scan_duration = 100;
2361 adev->scan_probe_delay = 200;
2362 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2363 adev->scan_rate = ACX_SCAN_RATE_1;
2366 adev->mode = ACX_MODE_2_STA;
2367 adev->listen_interval = 100;
2368 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2369 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2371 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2373 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2374 adev->frag_threshold = 2346;
2376 /* use standard default values for retry limits */
2377 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2378 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2380 adev->preamble_mode = 2; /* auto */
2381 adev->fallback_threshold = 3;
2382 adev->stepup_threshold = 10;
2383 adev->rate_bcast = RATE111_1;
2384 adev->rate_bcast100 = RATE100_1;
2385 adev->rate_basic = RATE111_1 | RATE111_2;
2386 adev->rate_auto = 1;
2387 if (IS_ACX111(adev)) {
2388 adev->rate_oper = RATE111_ALL;
2389 } else {
2390 adev->rate_oper = RATE111_ACX100_COMPAT;
2393 /* Supported Rates element - the rates here are given in units of
2394 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2395 acx_l_update_ratevector(adev);
2397 /* set some more defaults */
2398 if (IS_ACX111(adev)) {
2399 /* 30mW (15dBm) is default, at least in my acx111 card: */
2400 adev->tx_level_dbm = 15;
2401 conf->power_level = adev->tx_level_dbm;
2402 acx_unlock(adev, flags);
2403 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2404 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2405 acx_lock(adev, flags);
2406 } else {
2407 /* don't use max. level, since it might be dangerous
2408 * (e.g. WRT54G people experience
2409 * excessive Tx power damage!) */
2410 adev->tx_level_dbm = 18;
2411 conf->power_level = adev->tx_level_dbm;
2412 acx_unlock(adev, flags);
2413 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2414 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2415 acx_lock(adev, flags);
2418 /* adev->tx_level_auto = 1; */
2419 if (IS_ACX111(adev)) {
2420 /* start with sensitivity level 1 out of 3: */
2421 adev->sensitivity = 1;
2424 /* #define ENABLE_POWER_SAVE */
2425 #ifdef ENABLE_POWER_SAVE
2426 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2427 adev->ps_listen_interval = 1;
2428 adev->ps_options =
2429 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2430 adev->ps_hangover_period = 30;
2431 adev->ps_enhanced_transition_time = 0;
2432 #else
2433 adev->ps_wakeup_cfg = 0;
2434 adev->ps_listen_interval = 0;
2435 adev->ps_options = 0;
2436 adev->ps_hangover_period = 0;
2437 adev->ps_enhanced_transition_time = 0;
2438 #endif
2440 /* These settings will be set in fw on ifup */
2441 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2442 /* configure card to do rate fallback when in auto rate mode */
2443 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2444 /* better re-init the antenna value we got above */
2445 | GETSET_ANTENNA
2446 #if POWER_SAVE_80211
2447 | GETSET_POWER_80211
2448 #endif
2451 acx_unlock(adev, flags);
2452 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2454 acx_s_initialize_rx_config(adev);
2456 FN_EXIT0;
2460 /***********************************************************************
2461 ** acx_l_process_rxbuf
2463 ** NB: used by USB code also
2465 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2467 struct ieee80211_hdr *hdr;
2468 u16 fc, buf_len;
2470 FN_ENTER;
2472 hdr = acx_get_wlan_hdr(adev, rxbuf);
2473 fc = le16_to_cpu(hdr->frame_control);
2474 /* length of frame from control field to first byte of FCS */
2475 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2477 if (unlikely(acx_debug & L_DATA)) {
2478 printk("rx: 802.11 buf[%u]: \n", buf_len);
2479 acx_dump_bytes(hdr, buf_len);
2483 acx_l_rx(adev, rxbuf);
2484 /* Now check Rx quality level, AFTER processing packet.
2485 * I tried to figure out how to map these levels to dBm
2486 * values, but for the life of me I really didn't
2487 * manage to get it. Either these values are not meant to
2488 * be expressed in dBm, or it's some pretty complicated
2489 * calculation. */
2491 #ifdef FROM_SCAN_SOURCE_ONLY
2492 /* only consider packets originating from the MAC
2493 * address of the device that's managing our BSSID.
2494 * Disable it for now, since it removes information (levels
2495 * from different peers) and slows the Rx path. *//*
2496 if (adev->ap_client && mac_is_equal(hdr->a2, adev->ap_client->address)) {
2498 #endif
2500 FN_EXIT0;
2504 /***********************************************************************
2505 ** acx_l_handle_txrate_auto
2507 ** Theory of operation:
2508 ** client->rate_cap is a bitmask of rates client is capable of.
2509 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2510 ** It is set as a result of iwconfig rate N [auto]
2511 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2512 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2513 ** auto (0x00ff == 18Mbit or any lower value),
2514 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2516 ** client->rate_cur is a value for rate111 field in tx descriptor.
2517 ** It is always set to txrate_cfg sans zero or more most significant
2518 ** bits. This routine handles selection of new rate_cur value depending on
2519 ** outcome of last tx event.
2521 ** client->rate_100 is a precalculated rate value for acx100
2522 ** (we can do without it, but will need to calculate it on each tx).
2524 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2525 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2526 ** In theory you can implement it, but so far it is considered not worth doing.
2528 ** 22Mbit, of course, is PBCC always. */
2530 /* maps acx100 tx descr rate field to acx111 one */
2532 static u16 rate100to111(u8 r)
2534 switch (r) {
2535 case RATE100_1:
2536 return RATE111_1;
2537 case RATE100_2:
2538 return RATE111_2;
2539 case RATE100_5:
2540 case (RATE100_5 | RATE100_PBCC511):
2541 return RATE111_5;
2542 case RATE100_11:
2543 case (RATE100_11 | RATE100_PBCC511):
2544 return RATE111_11;
2545 case RATE100_22:
2546 return RATE111_22;
2547 default:
2548 printk("acx: unexpected acx100 txrate: %u! "
2549 "Please report\n", r);
2550 return RATE111_1;
2557 acx_i_start_xmit(struct ieee80211_hw *hw,
2558 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2560 acx_device_t *adev = ieee2adev(hw);
2561 tx_t *tx;
2562 void *txbuf;
2563 unsigned long flags;
2565 int txresult = NOT_OK;
2567 FN_ENTER;
2569 acx_lock(adev, flags);
2571 if (unlikely(!skb)) {
2572 /* indicate success */
2573 txresult = OK;
2574 goto end;
2577 if (unlikely(!adev)) {
2578 goto end;
2582 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2583 goto end;
2585 if (unlikely(!adev->initialized)) {
2586 goto end;
2589 tx = acx_l_alloc_tx(adev);
2591 if (unlikely(!tx)) {
2592 printk_ratelimited("%s: start_xmit: txdesc ring is full, "
2593 "dropping tx\n", wiphy_name(adev->ieee->wiphy));
2594 txresult = NOT_OK;
2595 goto end;
2598 txbuf = acx_l_get_txbuf(adev, tx);
2600 if (unlikely(!txbuf)) {
2601 /* Card was removed */
2602 txresult = NOT_OK;
2603 acx_l_dealloc_tx(adev, tx);
2604 goto end;
2606 memcpy(txbuf, skb->data, skb->len);
2608 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2610 txresult = OK;
2611 adev->stats.tx_packets++;
2612 adev->stats.tx_bytes += skb->len;
2614 end:
2615 acx_unlock(adev, flags);
2617 FN_EXIT1(txresult);
2618 return txresult;
2620 /***********************************************************************
2621 ** acx_l_update_ratevector
2623 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2625 const u8 acx_bitpos2ratebyte[] = {
2626 DOT11RATEBYTE_1,
2627 DOT11RATEBYTE_2,
2628 DOT11RATEBYTE_5_5,
2629 DOT11RATEBYTE_6_G,
2630 DOT11RATEBYTE_9_G,
2631 DOT11RATEBYTE_11,
2632 DOT11RATEBYTE_12_G,
2633 DOT11RATEBYTE_18_G,
2634 DOT11RATEBYTE_22,
2635 DOT11RATEBYTE_24_G,
2636 DOT11RATEBYTE_36_G,
2637 DOT11RATEBYTE_48_G,
2638 DOT11RATEBYTE_54_G,
2641 void acx_l_update_ratevector(acx_device_t * adev)
2643 u16 bcfg = adev->rate_basic;
2644 u16 ocfg = adev->rate_oper;
2645 u8 *supp = adev->rate_supported;
2646 const u8 *dot11 = acx_bitpos2ratebyte;
2648 FN_ENTER;
2650 while (ocfg) {
2651 if (ocfg & 1) {
2652 *supp = *dot11;
2653 if (bcfg & 1) {
2654 *supp |= 0x80;
2656 supp++;
2658 dot11++;
2659 ocfg >>= 1;
2660 bcfg >>= 1;
2662 adev->rate_supported_len = supp - adev->rate_supported;
2663 if (acx_debug & L_ASSOC) {
2664 printk("new ratevector: ");
2665 acx_dump_bytes(adev->rate_supported, adev->rate_supported_len);
2667 FN_EXIT0;
2670 /***********************************************************************
2671 ** acx_i_timer
2673 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2675 ** Obvious
2677 void acx_i_timer(unsigned long address)
2679 unsigned long flags;
2680 acx_device_t *adev = (acx_device_t *) address;
2682 FN_ENTER;
2684 acx_lock(adev, flags);
2686 FIXME();
2687 /* We need calibration and stats gather tasks to perform here */
2689 acx_unlock(adev, flags);
2691 FN_EXIT0;
2695 /***********************************************************************
2696 ** acx_set_timer
2698 ** Sets the 802.11 state management timer's timeout.
2700 ** Linux derived
2702 void acx_set_timer(acx_device_t * adev, int timeout_us)
2704 FN_ENTER;
2706 log(L_DEBUG | L_IRQ, "%s(%u ms)\n", __func__, timeout_us / 1000);
2707 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2708 printk("attempt to set the timer "
2709 "when the card interface is not up!\n");
2710 goto end;
2713 /* first check if the timer was already initialized, THEN modify it */
2714 if (adev->mgmt_timer.function) {
2715 mod_timer(&adev->mgmt_timer,
2716 jiffies + (timeout_us * HZ / 1000000));
2718 end:
2719 FN_EXIT0;
2722 /** acx_plcp_get_bitrate_cck
2724 ** Obvious
2726 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2728 switch (plcp) {
2729 case 0x0A:
2730 return ACX_CCK_RATE_1MB;
2731 case 0x14:
2732 return ACX_CCK_RATE_2MB;
2733 case 0x37:
2734 return ACX_CCK_RATE_5MB;
2735 case 0x6E:
2736 return ACX_CCK_RATE_11MB;
2738 return 0;
2741 /* Extract the bitrate out of an OFDM PLCP header. */
2742 /** Obvious **/
2743 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2745 switch (plcp & 0xF) {
2746 case 0xB:
2747 return ACX_OFDM_RATE_6MB;
2748 case 0xF:
2749 return ACX_OFDM_RATE_9MB;
2750 case 0xA:
2751 return ACX_OFDM_RATE_12MB;
2752 case 0xE:
2753 return ACX_OFDM_RATE_18MB;
2754 case 0x9:
2755 return ACX_OFDM_RATE_24MB;
2756 case 0xD:
2757 return ACX_OFDM_RATE_36MB;
2758 case 0x8:
2759 return ACX_OFDM_RATE_48MB;
2760 case 0xC:
2761 return ACX_OFDM_RATE_54MB;
2763 return 0;
2767 /***********************************************************************
2768 ** acx_l_rx
2770 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2771 ** buffer and feeds it to the network stack via netif_rx().
2773 ** Look to bcm43xx or p54
2775 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2778 struct ieee80211_rx_status* status = &adev->rx_status;
2779 struct ieee80211_hdr *w_hdr;
2780 int buflen;
2781 FN_ENTER;
2783 if (likely(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2784 struct sk_buff *skb;
2785 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2786 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2787 skb = dev_alloc_skb(buflen + 2);
2788 skb_reserve(skb, 2);
2789 skb_put(skb, buflen);
2790 memcpy(skb->data, w_hdr, buflen);
2792 // memset(&status, 0, sizeof(status));
2794 if (likely(skb)) {
2795 status->mactime = rxbuf->time;
2796 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2797 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr);
2798 status->flag = 0;
2799 status->rate = rxbuf->phy_plcp_signal;
2800 status->antenna = 1;
2802 #ifndef OLD_QUALITY
2803 qual = acx_signal_determine_quality(adev->wstats.qual.level,
2804 adev->wstats.qual.noise);
2805 #else
2806 qual = (adev->wstats.qual.noise <= 100) ?
2807 100 - adev->wstats.qual.noise : 0;
2808 #endif
2809 adev->wstats.qual.qual = qual;
2810 adev->wstats.qual.updated = 7; *//* all 3 indicators updated */
2812 #ifdef FROM_SCAN_SOURCE_ONLY
2814 #endif
2816 if (rxbuf->phy_stat_baseband & (1 << 3)) /* Uses OFDM */
2818 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2819 } else
2821 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2823 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2824 adev->stats.rx_packets++;
2825 adev->stats.rx_bytes += skb->len;
2828 FN_EXIT0;
2833 /***********************************************************************
2834 ** acx_s_read_fw
2836 ** Loads a firmware image
2838 ** Returns:
2839 ** 0 unable to load file
2840 ** pointer to firmware success
2842 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2843 u32 * size)
2845 firmware_image_t *res;
2846 const struct firmware *fw_entry;
2848 res = NULL;
2849 log(L_INIT, "requesting firmware image '%s'\n", file);
2850 if (!request_firmware(&fw_entry, file, dev)) {
2851 *size = 8;
2852 if (fw_entry->size >= 8)
2853 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2854 if (fw_entry->size != *size) {
2855 printk("acx: firmware size does not match "
2856 "firmware header: %d != %d, "
2857 "aborting fw upload\n",
2858 (int)fw_entry->size, (int)*size);
2859 goto release_ret;
2861 res = vmalloc(*size);
2862 if (!res) {
2863 printk("acx: no memory for firmware "
2864 "(%u bytes)\n", *size);
2865 goto release_ret;
2867 memcpy(res, fw_entry->data, fw_entry->size);
2868 release_ret:
2869 release_firmware(fw_entry);
2870 return res;
2872 printk("acx: firmware image '%s' was not provided. "
2873 "Check your hotplug scripts\n", file);
2875 /* checksum will be verified in write_fw, so don't bother here */
2876 return res;
2880 /***********************************************************************
2881 ** acx_s_set_wepkey
2883 static void acx100_s_set_wepkey(acx_device_t * adev)
2885 ie_dot11WEPDefaultKey_t dk;
2886 int i;
2888 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2889 if (adev->wep_keys[i].size != 0) {
2890 log(L_INIT, "setting WEP key: %d with "
2891 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2892 dk.action = 1;
2893 dk.keySize = adev->wep_keys[i].size;
2894 dk.defaultKeyNum = i;
2895 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2896 acx_s_configure(adev, &dk,
2897 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
2902 static void acx111_s_set_wepkey(acx_device_t * adev)
2904 acx111WEPDefaultKey_t dk;
2905 int i;
2907 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2908 if (adev->wep_keys[i].size != 0) {
2909 log(L_INIT, "setting WEP key: %d with "
2910 "total size: %d\n", i, (int)adev->wep_keys[i].size);
2911 memset(&dk, 0, sizeof(dk));
2912 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2913 dk.keySize = adev->wep_keys[i].size;
2915 /* are these two lines necessary? */
2916 dk.type = 0; /* default WEP key */
2917 dk.index = 0; /* ignored when setting default key */
2919 dk.defaultKeyNum = i;
2920 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2921 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2922 sizeof(dk));
2926 /* Obvious */
2927 static void acx_s_set_wepkey(acx_device_t * adev)
2929 if (IS_ACX111(adev))
2930 acx111_s_set_wepkey(adev);
2931 else
2932 acx100_s_set_wepkey(adev);
2936 /***********************************************************************
2937 ** acx100_s_init_wep
2939 ** FIXME: this should probably be moved into the new card settings
2940 ** management, but since we're also modifying the memory map layout here
2941 ** due to the WEP key space we want, we should take care...
2943 static int acx100_s_init_wep(acx_device_t * adev)
2945 acx100_ie_wep_options_t options;
2946 ie_dot11WEPDefaultKeyID_t dk;
2947 acx_ie_memmap_t pt;
2948 int res = NOT_OK;
2950 FN_ENTER;
2952 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2953 goto fail;
2956 log(L_DEBUG, "CodeEnd:%X\n", pt.CodeEnd);
2958 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2959 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2961 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2962 goto fail;
2965 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2966 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2967 options.WEPOption = 0x00;
2969 log(L_ASSOC, "writing WEP options\n");
2970 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
2972 acx100_s_set_wepkey(adev);
2974 if (adev->wep_keys[adev->wep_current_index].size != 0) {
2975 log(L_ASSOC, "setting active default WEP key number: %d\n",
2976 adev->wep_current_index);
2977 dk.KeyID = adev->wep_current_index;
2978 acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
2980 /* FIXME!!! wep_key_struct is filled nowhere! But adev
2981 * is initialized to 0, and we don't REALLY need those keys either */
2982 /* for (i = 0; i < 10; i++) {
2983 if (adev->wep_key_struct[i].len != 0) {
2984 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
2985 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
2986 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
2987 wep_mgmt.Action = cpu_to_le16(1);
2988 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
2989 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
2990 adev->wep_key_struct[i].index = i;
2996 /* now retrieve the updated WEPCacheEnd pointer... */
2997 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2998 printk("%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
2999 wiphy_name(adev->ieee->wiphy));
3000 goto fail;
3002 /* ...and tell it to start allocating templates at that location */
3003 /* (no endianness conversion needed) */
3004 pt.PacketTemplateStart = pt.WEPCacheEnd;
3006 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
3007 printk("%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
3008 wiphy_name(adev->ieee->wiphy));
3009 goto fail;
3011 res = OK;
3013 fail:
3014 FN_EXIT1(res);
3015 return res;
3019 static int
3020 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
3021 unsigned int cmd)
3023 int res;
3024 union {
3025 acx_template_nullframe_t null;
3026 acx_template_beacon_t b;
3027 acx_template_tim_t tim;
3028 acx_template_probereq_t preq;
3029 acx_template_proberesp_t presp;
3030 } templ;
3032 memset(&templ, 0, len);
3033 templ.null.size = cpu_to_le16(len - 2);
3034 res = acx_s_issue_cmd(adev, cmd, &templ, len);
3035 return res;
3038 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
3040 return acx_s_init_max_template_generic(adev,
3041 sizeof(acx_template_nullframe_t),
3042 ACX1xx_CMD_CONFIG_NULL_DATA);
3045 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
3047 return acx_s_init_max_template_generic(adev,
3048 sizeof(acx_template_beacon_t),
3049 ACX1xx_CMD_CONFIG_BEACON);
3052 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
3054 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
3055 ACX1xx_CMD_CONFIG_TIM);
3058 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
3060 return acx_s_init_max_template_generic(adev,
3061 sizeof(acx_template_proberesp_t),
3062 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
3065 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
3067 return acx_s_init_max_template_generic(adev,
3068 sizeof(acx_template_probereq_t),
3069 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
3072 /***********************************************************************
3073 ** acx_s_set_tim_template
3075 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
3076 ** by calling this function
3077 ** (it can be done by irq handler on each DTIM irq or by timer...)
3079 [802.11 7.3.2.6] TIM information element:
3080 - 1 EID
3081 - 1 Length
3082 1 1 DTIM Count
3083 indicates how many beacons (including this) appear before next DTIM
3084 (0=this one is a DTIM)
3085 2 1 DTIM Period
3086 number of beacons between successive DTIMs
3087 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
3088 3 1 Bitmap Control
3089 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
3090 set to 1 in TIM elements with a value of 0 in the DTIM Count field
3091 when one or more broadcast or multicast frames are buffered at the AP.
3092 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
3093 4 n Partial Virtual Bitmap
3094 Visible part of traffic-indication bitmap.
3095 Full bitmap consists of 2008 bits (251 octets) such that bit number N
3096 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
3097 in octet number N/8 where the low-order bit of each octet is bit0,
3098 and the high order bit is bit7.
3099 Each set bit in virtual bitmap corresponds to traffic buffered by AP
3100 for a specific station (with corresponding AID?).
3101 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
3102 Bitmap Offset is a number of skipped zero octets (see above).
3103 'Missing' octets at the tail are also assumed to be zero.
3104 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
3105 This means that traffic-indication bitmap is:
3106 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
3107 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
3109 static int acx_s_set_tim_template(acx_device_t * adev)
3111 /* For now, configure smallish test bitmap, all zero ("no pending data") */
3112 enum { bitmap_size = 5 };
3114 acx_template_tim_t t;
3115 int result;
3117 FN_ENTER;
3119 memset(&t, 0, sizeof(t));
3120 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3121 t.tim_eid = WLAN_EID_TIM;
3122 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3123 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3124 FN_EXIT1(result);
3125 return result;
3131 #if POWER_SAVE_80211
3132 /***********************************************************************
3133 ** acx_s_set_null_data_template
3135 static int acx_s_set_null_data_template(acx_device_t * adev)
3137 struct acx_template_nullframe b;
3138 int result;
3140 FN_ENTER;
3142 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3144 b.size = cpu_to_le16(sizeof(b) - 2);
3145 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3146 b.hdr.dur = 0;
3147 MAC_BCAST(b.hdr.a1);
3148 MAC_COPY(b.hdr.a2, adev->dev_addr);
3149 MAC_COPY(b.hdr.a3, adev->bssid);
3150 b.hdr.seq = 0;
3152 result =
3153 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3155 FN_EXIT1(result);
3156 return result;
3158 #endif
3165 /***********************************************************************
3166 ** acx_s_init_packet_templates()
3168 ** NOTE: order is very important here, to have a correct memory layout!
3169 ** init templates: max Probe Request (station mode), max NULL data,
3170 ** max Beacon, max TIM, max Probe Response.
3172 static int acx_s_init_packet_templates(acx_device_t * adev)
3174 acx_ie_memmap_t mm; /* ACX100 only */
3175 int result = NOT_OK;
3177 FN_ENTER;
3179 log(L_DEBUG | L_INIT, "initializing max packet templates\n");
3181 if (OK != acx_s_init_max_probe_request_template(adev))
3182 goto failed;
3184 if (OK != acx_s_init_max_null_data_template(adev))
3185 goto failed;
3187 if (OK != acx_s_init_max_beacon_template(adev))
3188 goto failed;
3190 if (OK != acx_s_init_max_tim_template(adev))
3191 goto failed;
3193 if (OK != acx_s_init_max_probe_response_template(adev))
3194 goto failed;
3196 if (IS_ACX111(adev)) {
3197 /* ACX111 doesn't need the memory map magic below,
3198 * and the other templates will be set later (acx_start) */
3199 result = OK;
3200 goto success;
3203 /* ACX100 will have its TIM template set,
3204 * and we also need to update the memory map */
3206 if (OK != acx_s_set_tim_template(adev))
3207 goto failed_acx100;
3209 log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3211 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3212 goto failed_acx100;
3214 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3215 if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3216 goto failed_acx100;
3218 result = OK;
3219 goto success;
3221 failed_acx100:
3222 log(L_DEBUG | L_INIT,
3223 /* "cb=0x%X\n" */
3224 "ACXMemoryMap:\n"
3225 ".CodeStart=0x%X\n"
3226 ".CodeEnd=0x%X\n"
3227 ".WEPCacheStart=0x%X\n"
3228 ".WEPCacheEnd=0x%X\n"
3229 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3230 /* len, */
3231 le32_to_cpu(mm.CodeStart),
3232 le32_to_cpu(mm.CodeEnd),
3233 le32_to_cpu(mm.WEPCacheStart),
3234 le32_to_cpu(mm.WEPCacheEnd),
3235 le32_to_cpu(mm.PacketTemplateStart),
3236 le32_to_cpu(mm.PacketTemplateEnd));
3238 failed:
3239 printk("%s: %s() FAILED\n", wiphy_name(adev->ieee->wiphy), __func__);
3241 success:
3242 FN_EXIT1(result);
3243 return result;
3248 /***********************************************************************
3249 ** acx_s_init_mac
3251 int acx_s_init_mac(acx_device_t * adev)
3253 int result = NOT_OK;
3255 FN_ENTER;
3257 if (IS_ACX111(adev)) {
3258 adev->ie_len = acx111_ie_len;
3259 adev->ie_len_dot11 = acx111_ie_len_dot11;
3260 } else {
3261 adev->ie_len = acx100_ie_len;
3262 adev->ie_len_dot11 = acx100_ie_len_dot11;
3265 if (IS_PCI(adev)) {
3266 adev->memblocksize = 256; /* 256 is default */
3267 /* try to load radio for both ACX100 and ACX111, since both
3268 * chips have at least some firmware versions making use of an
3269 * external radio module */
3270 acxpci_s_upload_radio(adev);
3271 } else {
3272 adev->memblocksize = 128;
3275 if (IS_ACX111(adev)) {
3276 /* for ACX111, the order is different from ACX100
3277 1. init packet templates
3278 2. create station context and create dma regions
3279 3. init wep default keys
3281 if (OK != acx_s_init_packet_templates(adev))
3282 goto fail;
3283 if (OK != acx111_s_create_dma_regions(adev)) {
3284 printk("%s: acx111_create_dma_regions FAILED\n",
3285 wiphy_name(adev->ieee->wiphy));
3286 goto fail;
3288 } else {
3289 if (OK != acx100_s_init_wep(adev))
3290 goto fail;
3291 if (OK != acx_s_init_packet_templates(adev))
3292 goto fail;
3293 if (OK != acx100_s_create_dma_regions(adev)) {
3294 printk("%s: acx100_create_dma_regions FAILED\n",
3295 wiphy_name(adev->ieee->wiphy));
3296 goto fail;
3300 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3301 result = OK;
3303 fail:
3304 if (result)
3305 printk("acx: init_mac() FAILED\n");
3306 FN_EXIT1(result);
3307 return result;
3312 #if POWER_SAVE_80211
3313 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3315 /* merge both structs in a union to be able to have common code */
3316 union {
3317 acx111_ie_powersave_t acx111;
3318 acx100_ie_powersave_t acx100;
3319 } pm;
3321 /* change 802.11 power save mode settings */
3322 log(L_INIT, "updating 802.11 power save mode settings: "
3323 "wakeup_cfg 0x%02X, listen interval %u, "
3324 "options 0x%02X, hangover period %u, "
3325 "enhanced_ps_transition_time %u\n",
3326 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3327 adev->ps_options, adev->ps_hangover_period,
3328 adev->ps_enhanced_transition_time);
3329 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3330 log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, "
3331 "listen interval %u, options 0x%02X, "
3332 "hangover period %u, "
3333 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3334 pm.acx111.wakeup_cfg,
3335 pm.acx111.listen_interval,
3336 pm.acx111.options,
3337 pm.acx111.hangover_period,
3338 IS_ACX111(adev) ?
3339 pm.acx111.enhanced_ps_transition_time
3340 : pm.acx100.enhanced_ps_transition_time,
3341 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3342 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3343 pm.acx111.listen_interval = adev->ps_listen_interval;
3344 pm.acx111.options = adev->ps_options;
3345 pm.acx111.hangover_period = adev->ps_hangover_period;
3346 if (IS_ACX111(adev)) {
3347 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3348 pm.acx111.enhanced_ps_transition_time =
3349 cpu_to_le32(adev->ps_enhanced_transition_time);
3350 } else {
3351 pm.acx100.enhanced_ps_transition_time =
3352 cpu_to_le16(adev->ps_enhanced_transition_time);
3354 acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT);
3355 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3356 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3357 acx_s_mwait(40);
3358 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3359 log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
3360 log(L_INIT, "power save mode change %s\n",
3361 (pm.acx111.
3362 wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful");
3363 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3364 * that power save mode change was successful. */
3365 /* FIXME: we shouldn't trigger a scan immediately after
3366 * fiddling with power save mode (since the firmware is sending
3367 * a NULL frame then). */
3369 #endif
3372 /***********************************************************************
3373 ** acx_s_update_card_settings
3375 ** Applies accumulated changes in various adev->xxxx members
3376 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3377 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3379 void acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
3381 unsigned mask;
3383 unsigned int i;
3385 for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
3386 if (acx_reg_domain_ids[i] == adev->reg_dom_id)
3387 break;
3389 if (sizeof(acx_reg_domain_ids) == i) {
3390 log(L_INIT, "Invalid or unsupported regulatory domain"
3391 " 0x%02X specified, falling back to FCC (USA)!"
3392 " Please report if this sounds fishy!\n",
3393 adev->reg_dom_id);
3394 i = 0;
3395 adev->reg_dom_id = acx_reg_domain_ids[i];
3397 /* since there was a mismatch, we need to force updating */
3398 do_set = 1;
3401 if (do_set) {
3402 acx_ie_generic_t dom;
3403 dom.m.bytes[0] = adev->reg_dom_id;
3404 acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3407 adev->reg_dom_chanmask = reg_domain_channel_masks[i];
3409 mask = (1 << (adev->channel - 1));
3410 if (!(adev->reg_dom_chanmask & mask)) {
3411 /* hmm, need to adjust our channel to reside within domain */
3412 mask = 1;
3413 for (i = 1; i <= 14; i++) {
3414 if (adev->reg_dom_chanmask & mask) {
3415 printk("%s: adjusting selected channel from %d "
3416 "to %d due to new regulatory domain\n",
3417 wiphy_name(adev->ieee->wiphy), adev->channel, i);
3418 adev->channel = i;
3419 break;
3421 mask <<= 1;
3426 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3428 u32 feature1, feature2;
3430 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3431 printk("%s: invalid sensitivity setting (1..3), "
3432 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3433 adev->sensitivity = 1;
3435 acx111_s_get_feature_config(adev, &feature1, &feature2);
3436 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3437 if (adev->sensitivity > 1)
3438 SET_BIT(feature1, FEATURE1_LOW_RX);
3439 if (adev->sensitivity > 2)
3440 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3441 acx111_s_feature_set(adev, feature1, feature2);
3445 void acx_s_update_card_settings(acx_device_t *adev)
3447 unsigned long flags;
3448 unsigned int start_scan = 0;
3449 int i;
3451 FN_ENTER;
3453 log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3454 adev->get_mask, adev->set_mask);
3456 /* Track dependencies betweed various settings */
3458 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3459 log(L_INIT, "important setting has been changed. "
3460 "Need to update packet templates, too\n");
3461 SET_BIT(adev->set_mask, SET_TEMPLATES);
3463 if (adev->set_mask & GETSET_CHANNEL) {
3464 /* This will actually tune RX/TX to the channel */
3465 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3466 switch (adev->mode) {
3467 case ACX_MODE_0_ADHOC:
3468 case ACX_MODE_3_AP:
3469 /* Beacons contain channel# - update them */
3470 SET_BIT(adev->set_mask, SET_TEMPLATES);
3473 switch (adev->mode) {
3474 case ACX_MODE_0_ADHOC:
3475 case ACX_MODE_2_STA:
3476 start_scan = 1;
3480 /* Apply settings */
3483 if (adev->get_mask & GETSET_STATION_ID) {
3484 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3485 const u8 *paddr;
3487 acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3488 paddr = &stationID[4];
3489 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3490 for (i = 0; i < ETH_ALEN; i++) {
3491 /* we copy the MAC address (reversed in
3492 * the card) to the netdevice's MAC
3493 * address, and on ifup it will be
3494 * copied into iwadev->dev_addr */
3495 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3497 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3498 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3501 if (adev->get_mask & GETSET_SENSITIVITY) {
3502 if ((RADIO_RFMD_11 == adev->radio_type)
3503 || (RADIO_MAXIM_0D == adev->radio_type)
3504 || (RADIO_RALINK_15 == adev->radio_type)) {
3505 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3506 } else {
3507 log(L_INIT, "don't know how to get sensitivity "
3508 "for radio type 0x%02X\n", adev->radio_type);
3509 adev->sensitivity = 0;
3511 log(L_INIT, "got sensitivity value %u\n", adev->sensitivity);
3513 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3516 if (adev->get_mask & GETSET_ANTENNA) {
3517 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3519 memset(antenna, 0, sizeof(antenna));
3520 acx_s_interrogate(adev, antenna,
3521 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3522 adev->antenna = antenna[4];
3523 log(L_INIT, "got antenna value 0x%02X\n", adev->antenna);
3524 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3527 if (adev->get_mask & GETSET_ED_THRESH) {
3528 if (IS_ACX100(adev)) {
3529 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3531 memset(ed_threshold, 0, sizeof(ed_threshold));
3532 acx_s_interrogate(adev, ed_threshold,
3533 ACX100_IE_DOT11_ED_THRESHOLD);
3534 adev->ed_threshold = ed_threshold[4];
3535 } else {
3536 log(L_INIT, "acx111 doesn't support ED\n");
3537 adev->ed_threshold = 0;
3539 log(L_INIT, "got Energy Detect (ED) threshold %u\n",
3540 adev->ed_threshold);
3541 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3544 if (adev->get_mask & GETSET_CCA) {
3545 if (IS_ACX100(adev)) {
3546 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3548 memset(cca, 0, sizeof(adev->cca));
3549 acx_s_interrogate(adev, cca,
3550 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3551 adev->cca = cca[4];
3552 } else {
3553 log(L_INIT, "acx111 doesn't support CCA\n");
3554 adev->cca = 0;
3556 log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n",
3557 adev->cca);
3558 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3561 if (adev->get_mask & GETSET_REG_DOMAIN) {
3562 acx_ie_generic_t dom;
3564 acx_s_interrogate(adev, &dom,
3565 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3566 adev->reg_dom_id = dom.m.bytes[0];
3567 acx_s_set_sane_reg_domain(adev, 0);
3568 log(L_INIT, "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3569 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3572 if (adev->set_mask & GETSET_STATION_ID) {
3573 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3574 u8 *paddr;
3576 paddr = &stationID[4];
3577 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3578 for (i = 0; i < ETH_ALEN; i++) {
3579 /* copy the MAC address we obtained when we noticed
3580 * that the ethernet iface's MAC changed
3581 * to the card (reversed in
3582 * the card!) */
3583 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3585 acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3586 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3589 if (adev->set_mask & SET_STA_LIST) {
3590 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3592 if (adev->set_mask & SET_RATE_FALLBACK) {
3593 u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
3595 /* configure to not do fallbacks when not in auto rate mode */
3596 rate[4] =
3597 (adev->
3598 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3599 log(L_INIT, "updating Tx fallback to %u retries\n", rate[4]);
3600 acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK);
3601 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3603 if (adev->set_mask & GETSET_TXPOWER) {
3604 log(L_INIT, "updating transmit power: %u dBm\n",
3605 adev->tx_level_dbm);
3606 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3607 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3610 if (adev->set_mask & GETSET_SENSITIVITY) {
3611 log(L_INIT, "updating sensitivity value: %u\n",
3612 adev->sensitivity);
3613 switch (adev->radio_type) {
3614 case RADIO_RFMD_11:
3615 case RADIO_MAXIM_0D:
3616 case RADIO_RALINK_15:
3617 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3618 break;
3619 case RADIO_RADIA_16:
3620 case RADIO_UNKNOWN_17:
3621 acx111_s_sens_radio_16_17(adev);
3622 break;
3623 default:
3624 log(L_INIT, "don't know how to modify sensitivity "
3625 "for radio type 0x%02X\n", adev->radio_type);
3627 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3630 if (adev->set_mask & GETSET_ANTENNA) {
3631 /* antenna */
3632 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3634 memset(antenna, 0, sizeof(antenna));
3635 antenna[4] = adev->antenna;
3636 log(L_INIT, "updating antenna value: 0x%02X\n", adev->antenna);
3637 acx_s_configure(adev, &antenna,
3638 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3639 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3642 if (adev->set_mask & GETSET_ED_THRESH) {
3643 /* ed_threshold */
3644 log(L_INIT, "updating Energy Detect (ED) threshold: %u\n",
3645 adev->ed_threshold);
3646 if (IS_ACX100(adev)) {
3647 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3649 memset(ed_threshold, 0, sizeof(ed_threshold));
3650 ed_threshold[4] = adev->ed_threshold;
3651 acx_s_configure(adev, &ed_threshold,
3652 ACX100_IE_DOT11_ED_THRESHOLD);
3653 } else
3654 log(L_INIT, "acx111 doesn't support ED!\n");
3655 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3658 if (adev->set_mask & GETSET_CCA) {
3659 /* CCA value */
3660 log(L_INIT, "updating Channel Clear Assessment "
3661 "(CCA) value: 0x%02X\n", adev->cca);
3662 if (IS_ACX100(adev)) {
3663 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3665 memset(cca, 0, sizeof(cca));
3666 cca[4] = adev->cca;
3667 acx_s_configure(adev, &cca,
3668 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3669 } else
3670 log(L_INIT, "acx111 doesn't support CCA!\n");
3671 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3674 if (adev->set_mask & GETSET_LED_POWER) {
3675 /* Enable Tx */
3676 log(L_INIT, "updating power LED status: %u\n", adev->led_power);
3678 acx_lock(adev, flags); /* acxpci_l_power_led expects that the lock is already taken! */
3679 if (IS_PCI(adev))
3680 acxpci_l_power_led(adev, adev->led_power);
3681 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3682 acx_unlock(adev, flags);
3685 if (adev->set_mask & GETSET_POWER_80211) {
3686 #if POWER_SAVE_80211
3687 acx_s_update_80211_powersave_mode(adev);
3688 #endif
3689 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3692 if (adev->set_mask & GETSET_CHANNEL) {
3693 /* channel */
3694 log(L_INIT, "updating channel to: %u\n", adev->channel);
3695 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3698 if (adev->set_mask & GETSET_TX) {
3699 /* set Tx */
3700 log(L_INIT, "updating: %s Tx\n",
3701 adev->tx_disabled ? "disable" : "enable");
3702 if (adev->tx_disabled)
3703 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3704 else {
3705 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3706 &adev->channel, 1);
3707 FIXME();
3708 /* This needs to be keyed on WEP? */
3709 /* acx111_s_feature_on(adev, 0,
3710 FEATURE2_NO_TXCRYPT |
3711 FEATURE2_SNIFFER); */
3712 acx_wake_queue(adev->ieee, NULL);
3714 CLEAR_BIT(adev->set_mask, GETSET_TX);
3717 if (adev->set_mask & GETSET_RX) {
3718 /* Enable Rx */
3719 log(L_INIT, "updating: enable Rx on channel: %u\n",
3720 adev->channel);
3721 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3722 CLEAR_BIT(adev->set_mask, GETSET_RX);
3725 if (adev->set_mask & GETSET_RETRY) {
3726 u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
3727 u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
3729 log(L_INIT,
3730 "updating short retry limit: %u, long retry limit: %u\n",
3731 adev->short_retry, adev->long_retry);
3732 short_retry[0x4] = adev->short_retry;
3733 long_retry[0x4] = adev->long_retry;
3734 acx_s_configure(adev, &short_retry,
3735 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
3736 acx_s_configure(adev, &long_retry,
3737 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
3738 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3741 if (adev->set_mask & SET_MSDU_LIFETIME) {
3742 u8 xmt_msdu_lifetime[4 +
3743 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3745 log(L_INIT, "updating tx MSDU lifetime: %u\n",
3746 adev->msdu_lifetime);
3747 *(u32 *) & xmt_msdu_lifetime[4] =
3748 cpu_to_le32((u32) adev->msdu_lifetime);
3749 acx_s_configure(adev, &xmt_msdu_lifetime,
3750 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
3751 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3754 if (adev->set_mask & GETSET_REG_DOMAIN) {
3755 log(L_INIT, "updating regulatory domain: 0x%02X\n",
3756 adev->reg_dom_id);
3757 acx_s_set_sane_reg_domain(adev, 1);
3758 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3760 if (adev->set_mask & GETSET_MODE ) {
3761 acx111_s_feature_on(adev, 0,
3762 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3763 switch (adev->mode) {
3764 case ACX_MODE_3_AP:
3765 adev->aid = 0;
3766 //acx111_s_feature_off(adev, 0,
3767 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3768 MAC_COPY(adev->bssid, adev->dev_addr);
3769 acx_s_cmd_join_bssid(adev, adev->dev_addr);
3770 break;
3771 case ACX_MODE_MONITOR:
3772 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3773 break;
3774 case ACX_MODE_0_ADHOC:
3775 case ACX_MODE_2_STA:
3776 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3777 break;
3778 default:
3779 break;
3781 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3783 if (adev->set_mask & SET_TEMPLATES) {
3784 switch (adev->mode)
3786 case ACX_MODE_3_AP:
3787 acx_s_set_tim_template(adev);
3788 break;
3789 default:
3790 break;
3792 if (adev->beacon_cache)
3794 acx_s_set_beacon_template(adev, adev->beacon_cache);
3795 dev_kfree_skb(adev->beacon_cache);
3796 adev->beacon_cache = NULL;
3798 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3801 if (adev->set_mask & SET_RXCONFIG) {
3802 acx_s_initialize_rx_config(adev);
3803 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3806 if (adev->set_mask & GETSET_RESCAN) {
3807 /* switch (adev->mode) {
3808 case ACX_MODE_0_ADHOC:
3809 case ACX_MODE_2_STA:
3810 start_scan = 1;
3811 break;
3813 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3816 if (adev->set_mask & GETSET_WEP) {
3817 /* encode */
3819 ie_dot11WEPDefaultKeyID_t dkey;
3820 #ifdef DEBUG_WEP
3821 struct {
3822 u16 type;
3823 u16 len;
3824 u8 val;
3825 } ACX_PACKED keyindic;
3826 #endif
3827 log(L_INIT, "updating WEP key settings\n");
3829 acx_s_set_wepkey(adev);
3830 if (adev->wep_enabled) {
3831 dkey.KeyID = adev->wep_current_index;
3832 log(L_INIT, "setting WEP key %u as default\n",
3833 dkey.KeyID);
3834 acx_s_configure(adev, &dkey,
3835 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
3836 #ifdef DEBUG_WEP
3837 keyindic.val = 3;
3838 acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
3839 #endif
3842 // start_scan = 1;
3843 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3846 if (adev->set_mask & SET_WEP_OPTIONS) {
3847 acx100_ie_wep_options_t options;
3849 if (IS_ACX111(adev)) {
3850 log(L_DEBUG,
3851 "setting WEP Options for acx111 is not supported\n");
3852 } else {
3853 log(L_INIT, "setting WEP Options\n");
3855 /* let's choose maximum setting: 4 default keys,
3856 * plus 10 other keys: */
3857 options.NumKeys =
3858 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3859 /* don't decrypt default key only,
3860 * don't override decryption: */
3861 options.WEPOption = 0;
3862 if (adev->mode == ACX_MODE_3_AP) {
3863 /* don't decrypt default key only,
3864 * override decryption mechanism: */
3865 options.WEPOption = 2;
3868 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3870 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3874 /* debug, rate, and nick don't need any handling */
3875 /* what about sniffing mode?? */
3877 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3878 adev->get_mask, adev->set_mask);
3880 /* end: */
3881 FN_EXIT0;
3884 #if 0
3885 /***********************************************************************
3886 ** acx_e_after_interrupt_task
3888 static int acx_s_recalib_radio(acx_device_t * adev)
3890 if (IS_ACX111(adev)) {
3891 acx111_cmd_radiocalib_t cal;
3893 /* automatic recalibration, choose all methods: */
3894 cal.methods = cpu_to_le32(0x8000000f);
3895 /* automatic recalibration every 60 seconds (value in TUs)
3896 * I wonder what the firmware default here is? */
3897 cal.interval = cpu_to_le32(58594);
3898 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3899 &cal, sizeof(cal),
3900 CMD_TIMEOUT_MS(100));
3901 } else {
3902 /* On ACX100, we need to recalibrate the radio
3903 * by issuing a GETSET_TX|GETSET_RX */
3904 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3905 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3906 (OK ==
3907 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3908 &adev->channel, 1))
3909 && (OK ==
3910 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3911 &adev->channel, 1)))
3912 return OK;
3913 return NOT_OK;
3916 #endif // if 0
3917 #if 0
3918 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3920 int res;
3922 /* this helps with ACX100 at least;
3923 * hopefully ACX111 also does a
3924 * recalibration here */
3926 /* clear flag beforehand, since we want to make sure
3927 * it's cleared; then only set it again on specific circumstances */
3928 CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3930 /* better wait a bit between recalibrations to
3931 * prevent overheating due to torturing the card
3932 * into working too long despite high temperature
3933 * (just a safety measure) */
3934 if (adev->recalib_time_last_success
3935 && time_before(jiffies, adev->recalib_time_last_success
3936 + RECALIB_PAUSE * 60 * HZ)) {
3937 if (adev->recalib_msg_ratelimit <= 4) {
3938 printk("%s: less than " STRING(RECALIB_PAUSE)
3939 " minutes since last radio recalibration, "
3940 "not recalibrating (maybe card is too hot?)\n",
3941 wiphy_name(adev->ieee->wiphy));
3942 adev->recalib_msg_ratelimit++;
3943 if (adev->recalib_msg_ratelimit == 5)
3944 printk("disabling above message until next recalib\n");
3946 return;
3949 adev->recalib_msg_ratelimit = 0;
3951 /* note that commands sometimes fail (card busy),
3952 * so only clear flag if we were fully successful */
3953 res = acx_s_recalib_radio(adev);
3954 if (res == OK) {
3955 printk("%s: successfully recalibrated radio\n",
3956 wiphy_name(adev->ieee->wiphy));
3957 adev->recalib_time_last_success = jiffies;
3958 adev->recalib_failure_count = 0;
3959 } else {
3960 /* failed: resubmit, but only limited
3961 * amount of times within some time range
3962 * to prevent endless loop */
3964 adev->recalib_time_last_success = 0; /* we failed */
3966 /* if some time passed between last
3967 * attempts, then reset failure retry counter
3968 * to be able to do next recalib attempt */
3969 if (time_after
3970 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3971 adev->recalib_failure_count = 0;
3973 if (adev->recalib_failure_count < 5) {
3974 /* increment inside only, for speedup of outside path */
3975 adev->recalib_failure_count++;
3976 adev->recalib_time_last_attempt = jiffies;
3977 acx_schedule_task(adev,
3978 ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
3982 #endif // if 0
3984 void acx_e_after_interrupt_task(struct work_struct *work)
3986 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
3987 unsigned long flags;
3989 FN_ENTER;
3991 acx_lock(adev, flags);
3993 if (!adev->after_interrupt_jobs || !adev->initialized)
3994 goto end; /* no jobs to do */
3996 /* we see lotsa tx errors */
3997 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) {
3998 // acx_s_after_interrupt_recalib(adev);
4001 /* a poor interrupt code wanted to do update_card_settings() */
4002 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) {
4003 if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
4004 acx_unlock(adev, flags);
4005 acx_s_update_card_settings(adev);
4006 acx_lock(adev, flags);
4008 CLEAR_BIT(adev->after_interrupt_jobs,
4009 ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4012 /* 1) we detected that no Scan_Complete IRQ came from fw, or
4013 ** 2) we found too many STAs */
4014 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) {
4015 log(L_IRQ, "sending a stop scan cmd...\n");
4016 acx_unlock(adev, flags);
4017 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
4018 acx_lock(adev, flags);
4019 /* HACK: set the IRQ bit, since we won't get a
4020 * scan complete IRQ any more on ACX111 (works on ACX100!),
4021 * since _we_, not a fw, have stopped the scan */
4022 SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
4023 CLEAR_BIT(adev->after_interrupt_jobs,
4024 ACX_AFTER_IRQ_CMD_STOP_SCAN);
4027 /* either fw sent Scan_Complete or we detected that
4028 ** no Scan_Complete IRQ came from fw. Finish scanning,
4029 ** pick join partner if any */
4030 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) {
4031 /* + scan kills current join status - restore it
4032 ** (do we need it for STA?) */
4033 /* + does it happen only with active scans?
4034 ** active and passive scans? ALL scans including
4035 ** background one? */
4036 /* + was not verified that everything is restored
4037 ** (but at least we start to emit beacons again) */
4038 CLEAR_BIT(adev->after_interrupt_jobs,
4039 ACX_AFTER_IRQ_COMPLETE_SCAN);
4042 /* STA auth or assoc timed out, start over again */
4044 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) {
4045 log(L_IRQ, "sending a start_scan cmd...\n");
4046 CLEAR_BIT(adev->after_interrupt_jobs,
4047 ACX_AFTER_IRQ_RESTART_SCAN);
4050 /* whee, we got positive assoc response! 8) */
4051 if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) {
4052 CLEAR_BIT(adev->after_interrupt_jobs,
4053 ACX_AFTER_IRQ_CMD_ASSOCIATE);
4055 end:
4056 if(adev->after_interrupt_jobs)
4058 printk("Jobs still to be run: %x\n",adev->after_interrupt_jobs);
4059 adev->after_interrupt_jobs = 0;
4061 acx_unlock(adev, flags);
4062 // acx_sem_unlock(adev);
4063 FN_EXIT0;
4067 /***********************************************************************
4068 ** acx_schedule_task
4070 ** Schedule the call of the after_interrupt method after leaving
4071 ** the interrupt context.
4073 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
4075 if (!adev->after_interrupt_jobs)
4077 SET_BIT(adev->after_interrupt_jobs, set_flag);
4078 schedule_work(&adev->after_interrupt_task);
4083 /***********************************************************************
4085 void acx_init_task_scheduler(acx_device_t * adev)
4087 /* configure task scheduler */
4088 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4092 /***********************************************************************
4093 ** acx_s_start
4095 void acx_s_start(acx_device_t * adev)
4097 FN_ENTER;
4100 * Ok, now we do everything that can possibly be done with ioctl
4101 * calls to make sure that when it was called before the card
4102 * was up we get the changes asked for
4105 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4106 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4107 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4108 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4110 log(L_INIT, "updating initial settings on iface activation\n");
4111 acx_s_update_card_settings(adev);
4113 FN_EXIT0;
4117 /***********************************************************************
4118 ** acx_update_capabilities
4119 *//*
4120 void acx_update_capabilities(acx_device_t * adev)
4122 u16 cap = 0;
4124 switch (adev->mode) {
4125 case ACX_MODE_3_AP:
4126 SET_BIT(cap, WF_MGMT_CAP_ESS);
4127 break;
4128 case ACX_MODE_0_ADHOC:
4129 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4130 break;
4131 */ /* other types of stations do not emit beacons */
4132 /* }
4134 if (adev->wep_restricted) {
4135 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4137 if (adev->cfgopt_dot11ShortPreambleOption) {
4138 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4140 if (adev->cfgopt_dot11PBCCOption) {
4141 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4143 if (adev->cfgopt_dot11ChannelAgility) {
4144 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4146 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4147 adev->capabilities, cap);
4148 adev->capabilities = cap;
4152 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4155 static void acx_s_select_opmode(acx_device_t * adev)
4157 int changed = 0;
4158 FN_ENTER;
4160 if (adev->interface.operating) {
4161 switch (adev->interface.type) {
4162 case IEEE80211_IF_TYPE_AP:
4163 if (adev->mode != ACX_MODE_3_AP)
4165 adev->mode = ACX_MODE_3_AP;
4166 changed = 1;
4168 break;
4169 case IEEE80211_IF_TYPE_IBSS:
4170 if (adev->mode != ACX_MODE_0_ADHOC)
4172 adev->mode = ACX_MODE_0_ADHOC;
4173 changed = 1;
4175 break;
4176 case IEEE80211_IF_TYPE_STA:
4177 if (adev->mode != ACX_MODE_2_STA)
4179 adev->mode = ACX_MODE_2_STA;
4180 changed = 1;
4182 break;
4183 case IEEE80211_IF_TYPE_WDS:
4184 default:
4185 if (adev->mode != ACX_MODE_OFF)
4187 adev->mode = ACX_MODE_OFF;
4188 changed = 1;
4190 break;
4192 } else {
4193 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4195 if (adev->mode != ACX_MODE_MONITOR)
4197 adev->mode = ACX_MODE_MONITOR;
4198 changed = 1;
4201 else
4203 if (adev->mode != ACX_MODE_OFF)
4205 adev->mode = ACX_MODE_OFF;
4206 changed = 1;
4210 if (changed)
4212 SET_BIT(adev->set_mask, GETSET_MODE);
4213 acx_s_update_card_settings(adev);
4214 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4217 FN_EXIT0;
4221 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4225 int acx_add_interface(struct ieee80211_hw *ieee,
4226 struct ieee80211_if_init_conf *conf)
4228 acx_device_t *adev = ieee2adev(ieee);
4229 unsigned long flags;
4230 int err = -EOPNOTSUPP;
4232 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4233 DECLARE_MAC_BUF(mac);
4234 #endif
4236 FN_ENTER;
4237 acx_lock(adev, flags);
4239 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4240 adev->interface.monitor++;
4241 } else {
4242 if (adev->interface.operating)
4243 goto out_unlock;
4244 adev->interface.operating = 1;
4245 adev->interface.mac_addr = conf->mac_addr;
4246 adev->interface.type = conf->type;
4248 // adev->mode = conf->type;
4250 acx_unlock(adev, flags);
4252 if (adev->initialized)
4253 acx_s_select_opmode(adev);
4255 acx_lock(adev, flags);
4257 err = 0;
4259 printk(KERN_INFO "Virtual interface added "
4260 "(type: 0x%08X, ID: %d, MAC: %s)\n",
4261 conf->type,
4262 adev->interface.if_id,
4263 print_mac(mac, conf->mac_addr));
4265 out_unlock:
4266 acx_unlock(adev, flags);
4268 FN_EXIT0;
4269 return err;
4272 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4276 void acx_remove_interface(struct ieee80211_hw *hw,
4277 struct ieee80211_if_init_conf *conf)
4279 acx_device_t *adev = ieee2adev(hw);
4280 unsigned long flags;
4282 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4283 DECLARE_MAC_BUF(mac);
4284 #endif
4286 FN_ENTER;
4288 acx_lock(adev, flags);
4289 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4290 adev->interface.monitor--;
4291 // assert(bcm->interface.monitor >= 0);
4292 } else
4293 adev->interface.operating = 0;
4295 printk("Removing interface: %d %d\n", adev->interface.operating, conf->type);
4296 acx_unlock(adev, flags);
4298 if (adev->initialized)
4299 acx_s_select_opmode(adev);
4300 flush_scheduled_work();
4302 printk(KERN_INFO "Virtual interface removed "
4303 "(type: 0x%08X, ID: %d, MAC: %s)\n",
4304 conf->type, adev->interface.if_id, print_mac(mac, conf->mac_addr));
4306 FN_EXIT0;
4309 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4313 int acx_net_reset(struct ieee80211_hw *ieee)
4315 acx_device_t *adev = ieee2adev(ieee);
4316 FN_ENTER;
4317 if (IS_PCI(adev))
4318 acxpci_s_reset_dev(adev);
4319 else
4320 TODO();
4322 FN_EXIT0;
4323 return 0;
4327 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4330 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4332 int result;
4334 FN_ENTER;
4336 acx_sem_lock(adev);
4337 adev->rx_status.channel = channel;
4338 adev->rx_status.freq = freq;
4340 adev->channel = channel;
4341 /* hmm, the following code part is strange, but this is how
4342 * it was being done before... */
4343 log(L_IOCTL, "Changing to channel %d\n", channel);
4344 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4345 result = -EINPROGRESS; /* need to call commit handler */
4347 acx_sem_unlock(adev);
4348 FN_EXIT1(result);
4349 return result;
4353 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4356 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4358 acx_device_t *adev = ieee2adev(hw);
4359 unsigned long flags;
4360 #if 0
4361 int change = 0;
4362 #endif
4363 FN_ENTER;
4365 acx_lock(adev, flags);
4366 //FIXME();
4367 if (!adev->initialized) {
4368 acx_unlock(adev, flags);
4369 return 0;
4371 if (conf->beacon_int != adev->beacon_interval)
4372 adev->beacon_interval = conf->beacon_int;
4373 if (conf->channel != adev->channel) {
4374 acx_unlock(adev, flags);
4375 acx_selectchannel(adev, conf->channel,conf->freq);
4376 acx_lock(adev, flags);
4377 /* acx_schedule_task(adev,
4378 ACX_AFTER_IRQ_UPDATE_CARD_CFG
4379 */ /*+ ACX_AFTER_IRQ_RESTART_SCAN */ /*);*/
4382 if (conf->short_slot_time != adev->short_slot) {
4383 // assert(phy->type == BCM43xx_PHYTYPE_G);
4384 if (conf->short_slot_time)
4385 acx_short_slot_timing_enable(adev);
4386 else
4387 acx_short_slot_timing_disable(adev);
4388 acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4391 adev->tx_disabled = !conf->radio_enabled;
4392 /* if (conf->power_level != 0){
4393 adev->tx_level_dbm = conf->power_level;
4394 acx_s_set_tx_level(adev, adev->tx_level_dbm);
4395 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4396 //acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4399 //FIXME: This does not seem to wake up:
4400 #if 0
4401 if (conf->power_level == 0) {
4402 if (radio->enabled)
4403 bcm43xx_radio_turn_off(bcm);
4404 } else {
4405 if (!radio->enabled)
4406 bcm43xx_radio_turn_on(bcm);
4408 #endif
4410 //TODO: phymode
4411 //TODO: antennas
4412 if (adev->set_mask > 0) {
4413 acx_unlock(adev, flags);
4414 acx_s_update_card_settings(adev);
4415 acx_lock(adev, flags);
4417 acx_unlock(adev, flags);
4419 FN_EXIT0;
4420 return 0;
4424 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4428 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
4429 extern int acx_config_interface(struct ieee80211_hw* ieee,
4430 struct ieee80211_vif *vif,
4431 struct ieee80211_if_conf *conf)
4433 acx_device_t *adev = ieee2adev(ieee);
4434 unsigned long flags;
4435 int err = -ENODEV;
4436 FN_ENTER;
4437 if (!adev->interface.operating)
4438 goto err_out;
4440 if (adev->initialized)
4441 acx_s_select_opmode(adev);
4443 acx_lock(adev, flags);
4445 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4446 && (adev->vif == vif)) {
4447 if (conf->bssid)
4449 adev->interface.bssid = conf->bssid;
4450 MAC_COPY(adev->bssid,conf->bssid);
4453 if ((conf->type == IEEE80211_IF_TYPE_AP)
4454 && (adev->vif == vif)) {
4455 #else
4456 int acx_config_interface(struct ieee80211_hw* ieee, int if_id,
4457 struct ieee80211_if_conf *conf)
4459 acx_device_t *adev = ieee2adev(ieee);
4460 unsigned long flags;
4461 int err = -ENODEV;
4462 FN_ENTER;
4463 if (!adev->interface.operating)
4464 goto err_out;
4466 if (adev->initialized)
4467 acx_s_select_opmode(adev);
4469 acx_lock(adev, flags);
4471 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4472 && (adev->interface.if_id == if_id)) {
4473 if (conf->bssid)
4475 adev->interface.bssid = conf->bssid;
4476 MAC_COPY(adev->bssid,conf->bssid);
4479 if ((conf->type == IEEE80211_IF_TYPE_AP)
4480 && (adev->interface.if_id == if_id)) {
4481 #endif
4483 if ((conf->ssid_len > 0) && conf->ssid)
4485 adev->essid_len = conf->ssid_len;
4486 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4487 SET_BIT(adev->set_mask, SET_TEMPLATES);
4490 if (conf->beacon != 0)
4492 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4493 adev->beacon_cache = conf->beacon;
4494 SET_BIT(adev->set_mask, SET_TEMPLATES);
4497 acx_unlock(adev, flags);
4499 if (adev->set_mask != 0)
4500 acx_s_update_card_settings(adev);
4501 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4502 err = 0;
4503 err_out:
4504 FN_EXIT1(err);
4505 return err;
4509 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4513 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4514 struct ieee80211_tx_queue_stats *stats)
4516 // acx_device_t *adev = ndev2adev(net_dev);
4517 struct ieee80211_tx_queue_stats_data *data;
4518 int err = -ENODEV;
4520 FN_ENTER;
4522 // acx_lock(adev, flags);
4523 data = &(stats->data[0]);
4524 data->len = 0;
4525 data->limit = TX_CNT;
4526 data->count = 0;
4527 // acx_unlock(adev, flags);
4529 FN_EXIT0;
4530 return err;
4533 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4537 int acx_net_conf_tx(struct ieee80211_hw *hw,
4538 int queue, const struct ieee80211_tx_queue_params *params)
4540 FN_ENTER;
4541 // TODO();
4542 FN_EXIT0;
4543 return 0;
4546 static void keymac_write(acx_device_t * adev, u16 index, const u32 * addr)
4548 /* for keys 0-3 there is no associated mac address */
4549 if (index < 4)
4550 return;
4552 index -= 4;
4553 if (1) {
4554 TODO();
4556 bcm43xx_shm_write32(bcm,
4557 BCM43xx_SHM_HWMAC,
4558 index * 2,
4559 cpu_to_be32(*addr));
4560 bcm43xx_shm_write16(bcm,
4561 BCM43xx_SHM_HWMAC,
4562 (index * 2) + 1,
4563 cpu_to_be16(*((u16 *)(addr + 1))));
4565 } else {
4566 if (index < 8) {
4567 TODO(); /* Put them in the macaddress filter */
4568 } else {
4569 TODO();
4570 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4571 Keep in mind to update the count of keymacs in 0x003 */
4577 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4581 int acx_clear_keys(acx_device_t * adev)
4583 static const u32 zero_mac[2] = { 0 };
4584 unsigned int i, j, nr_keys = 54;
4585 u16 offset;
4587 /* FixMe:Check for Number of Keys available */
4589 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4591 for (i = 0; i < nr_keys; i++) {
4592 adev->key[i].enabled = 0;
4593 /* returns for i < 4 immediately */
4594 keymac_write(adev, i, zero_mac);
4596 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4597 0x100 + (i * 2), 0x0000);
4599 for (j = 0; j < 8; j++) {
4600 offset =
4601 adev->security_offset + (j * 4) +
4602 (i * ACX_SEC_KEYSIZE);
4604 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4605 offset, 0x0000);
4609 return 1;
4613 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4617 int acx_key_write(acx_device_t * adev,
4618 u16 index, u8 algorithm,
4619 const struct ieee80211_key_conf *key, const u8 * mac_addr)
4621 // struct iw_point *dwrq = &wrqu->encoding;
4622 int result;
4624 FN_ENTER;
4626 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4627 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4629 // acx_sem_lock(adev);
4631 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4632 if (key->keylen > 0) {
4633 /* if index is 0 or invalid, use default key */
4634 if (index > 3)
4635 index = (int)adev->wep_current_index;
4636 if ((algorithm == ACX_SEC_ALGO_WEP) ||
4637 (algorithm == ACX_SEC_ALGO_WEP104)) {
4638 switch(key->keylen) {
4639 case 40 / 8:
4640 /* WEP 40-bit =
4641 40-bit entered key + 24 bit IV = 64-bit */
4642 adev->wep_keys[index].size = 13;
4643 break;
4644 case 104 / 8:
4645 /* WEP 104-bit =
4646 104-bit entered key + 24-bit IV = 128-bit */
4647 adev->wep_keys[index].size = 29;
4648 break;
4649 case 128 / 8:
4650 /* WEP 128-bit =
4651 128-bit entered key + 24 bit IV = 152-bit */
4652 adev->wep_keys[index].size = 16;
4653 break;
4654 default:
4655 adev->wep_keys[index].size = 0;
4656 return -EINVAL; /* shouldn't happen */
4659 memset(adev->wep_keys[index].key, 0,
4660 sizeof(adev->wep_keys[index].key));
4661 memcpy(adev->wep_keys[index].key, key, key->keylen);
4662 } else {
4663 /* set transmit key */
4664 if (index <= 3)
4665 adev->wep_current_index = index;
4666 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4667 /* complain if we were not just setting
4668 * the key mode */
4669 // result = -EINVAL;
4670 // goto end_unlock;
4671 // }
4675 adev->wep_enabled = (algorithm == ALG_WEP);
4677 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4679 if (algorithm & IW_ENCODE_OPEN) {
4680 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4681 adev->wep_restricted = 0;
4683 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4684 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4685 adev->wep_restricted = 1;
4688 // adev->auth_alg = algorithm;
4689 /* set flag to make sure the card WEP settings get updated */
4690 if (adev->wep_enabled) {
4691 SET_BIT(adev->set_mask, GETSET_WEP);
4692 acx_s_update_card_settings(adev);
4693 // acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
4696 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4697 dwrq->length, extra, dwrq->flags);
4698 for (index = 0; index <= 3; index++) {
4699 if (adev->wep_keys[index].size) {
4700 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4701 adev->wep_keys[index].index,
4702 (int) adev->wep_keys[index].size,
4703 adev->wep_keys[index].key);
4707 result = -EINPROGRESS;
4708 // acx_sem_unlock(adev);
4710 FN_EXIT1(result);
4711 return result;
4717 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4721 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
4722 int acx_net_set_key(struct ieee80211_hw *ieee,
4723 set_key_cmd cmd,
4724 u8 * addr, struct ieee80211_key_conf *key, int aid)
4725 #else
4726 int acx_net_set_key(struct ieee80211_hw *ieee,
4727 enum set_key_cmd cmd, const u8 *local_addr,
4728 const u8 * addr, struct ieee80211_key_conf *key)
4729 #endif
4731 // return 0;
4732 struct acx_device *adev = ieee2adev(ieee);
4733 unsigned long flags;
4734 u8 algorithm;
4735 u16 index;
4736 int err = -EINVAL;
4737 FN_ENTER;
4738 // TODO();
4739 switch (key->alg) {
4740 default:
4741 /* case ALG_NONE:
4742 case ALG_NULL:
4743 algorithm = ACX_SEC_ALGO_NONE;
4744 break;
4745 */ case ALG_WEP:
4746 if (key->keylen == 5)
4747 algorithm = ACX_SEC_ALGO_WEP;
4748 else
4749 algorithm = ACX_SEC_ALGO_WEP104;
4750 break;
4751 case ALG_TKIP:
4752 algorithm = ACX_SEC_ALGO_TKIP;
4753 break;
4754 case ALG_CCMP:
4755 algorithm = ACX_SEC_ALGO_AES;
4756 break;
4759 index = (u8) (key->keyidx);
4760 if (index >= ARRAY_SIZE(adev->key))
4761 goto out;
4762 acx_lock(adev, flags);
4763 switch (cmd) {
4764 case SET_KEY:
4765 err = acx_key_write(adev, index, algorithm, key, addr);
4766 if (err)
4767 goto out_unlock;
4768 key->hw_key_idx = index;
4769 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4770 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4771 adev->default_key_idx = index;*/
4772 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4773 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4774 #endif
4775 adev->key[index].enabled = 1;
4776 break;
4777 case DISABLE_KEY:
4778 adev->key[index].enabled = 0;
4779 err = 0;
4780 break;
4781 /* case ENABLE_COMPRESSION:
4782 case DISABLE_COMPRESSION:
4783 err = 0;
4784 break; */
4786 out_unlock:
4787 acx_unlock(adev, flags);
4788 out:
4789 FN_EXIT0;
4790 return err;
4795 /***********************************************************************
4796 ** Common function to parse ALL configoption struct formats
4797 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4798 ** FIXME: logging should be removed here and added to a /proc file instead
4800 ** Look into bcm43xx
4802 void
4803 acx_s_parse_configoption(acx_device_t * adev,
4804 const acx111_ie_configoption_t * pcfg)
4806 const u8 *pEle;
4807 int i;
4808 int is_acx111 = IS_ACX111(adev);
4810 if (acx_debug & L_DEBUG) {
4811 printk("configoption struct content:\n");
4812 acx_dump_bytes(pcfg, sizeof(*pcfg));
4815 if ((is_acx111 && (adev->eeprom_version == 5))
4816 || (!is_acx111 && (adev->eeprom_version == 4))
4817 || (!is_acx111 && (adev->eeprom_version == 5))) {
4818 /* these versions are known to be supported */
4819 } else {
4820 printk("unknown chip and EEPROM version combination (%s, v%d), "
4821 "don't know how to parse config options yet. "
4822 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4823 adev->eeprom_version);
4824 return;
4827 /* first custom-parse the first part which has chip-specific layout */
4829 pEle = (const u8 *)pcfg;
4831 pEle += 4; /* skip (type,len) header */
4833 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4834 pEle += sizeof(adev->cfgopt_NVSv);
4836 if (is_acx111) {
4837 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4838 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4840 adev->cfgopt_probe_delay = 200; /* good default value? */
4841 pEle += 2; /* FIXME: unknown, value 0x0001 */
4842 } else {
4843 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4844 pEle += sizeof(adev->cfgopt_MAC);
4846 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4847 pEle += sizeof(adev->cfgopt_probe_delay);
4848 if ((adev->cfgopt_probe_delay < 100)
4849 || (adev->cfgopt_probe_delay > 500)) {
4850 printk("strange probe_delay value %d, "
4851 "tweaking to 200\n", adev->cfgopt_probe_delay);
4852 adev->cfgopt_probe_delay = 200;
4856 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4857 pEle += sizeof(adev->cfgopt_eof_memory);
4859 printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n",
4860 adev->cfgopt_NVS_vendor_offs,
4861 adev->cfgopt_probe_delay, adev->cfgopt_eof_memory);
4863 adev->cfgopt_dot11CCAModes = *pEle++;
4864 adev->cfgopt_dot11Diversity = *pEle++;
4865 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4866 adev->cfgopt_dot11PBCCOption = *pEle++;
4867 adev->cfgopt_dot11ChannelAgility = *pEle++;
4868 adev->cfgopt_dot11PhyType = *pEle++;
4869 adev->cfgopt_dot11TempType = *pEle++;
4870 printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4871 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4872 adev->cfgopt_dot11CCAModes,
4873 adev->cfgopt_dot11Diversity,
4874 adev->cfgopt_dot11ShortPreambleOption,
4875 adev->cfgopt_dot11PBCCOption,
4876 adev->cfgopt_dot11ChannelAgility,
4877 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4879 /* then use common parsing for next part which has common layout */
4881 pEle++; /* skip table_count (6) */
4883 adev->cfgopt_antennas.type = pEle[0];
4884 adev->cfgopt_antennas.len = pEle[1];
4885 printk("AntennaID:%02X Len:%02X Data:",
4886 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4887 for (i = 0; i < pEle[1]; i++) {
4888 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4889 printk("%02X ", pEle[i + 2]);
4891 printk("\n");
4893 pEle += pEle[1] + 2;
4894 adev->cfgopt_power_levels.type = pEle[0];
4895 adev->cfgopt_power_levels.len = pEle[1];
4896 printk("PowerLevelID:%02X Len:%02X Data:",
4897 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4898 for (i = 0; i < pEle[1]; i++) {
4899 adev->cfgopt_power_levels.list[i] =
4900 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4901 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4903 printk("\n");
4905 pEle += pEle[1] * 2 + 2;
4906 adev->cfgopt_data_rates.type = pEle[0];
4907 adev->cfgopt_data_rates.len = pEle[1];
4908 printk("DataRatesID:%02X Len:%02X Data:",
4909 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4910 for (i = 0; i < pEle[1]; i++) {
4911 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4912 printk("%02X ", pEle[i + 2]);
4914 printk("\n");
4916 pEle += pEle[1] + 2;
4917 adev->cfgopt_domains.type = pEle[0];
4918 adev->cfgopt_domains.len = pEle[1];
4919 printk("DomainID:%02X Len:%02X Data:",
4920 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4921 for (i = 0; i < pEle[1]; i++) {
4922 adev->cfgopt_domains.list[i] = pEle[i + 2];
4923 printk("%02X ", pEle[i + 2]);
4925 printk("\n");
4927 pEle += pEle[1] + 2;
4928 adev->cfgopt_product_id.type = pEle[0];
4929 adev->cfgopt_product_id.len = pEle[1];
4930 for (i = 0; i < pEle[1]; i++) {
4931 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4933 printk("ProductID:%02X Len:%02X Data:%.*s\n",
4934 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4935 adev->cfgopt_product_id.len,
4936 (char *)adev->cfgopt_product_id.list);
4938 pEle += pEle[1] + 2;
4939 adev->cfgopt_manufacturer.type = pEle[0];
4940 adev->cfgopt_manufacturer.len = pEle[1];
4941 for (i = 0; i < pEle[1]; i++) {
4942 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4944 printk("ManufacturerID:%02X Len:%02X Data:%.*s\n",
4945 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4946 adev->cfgopt_manufacturer.len,
4947 (char *)adev->cfgopt_manufacturer.list);
4949 printk("EEPROM part:\n");
4950 for (i=0; i<58; i++) {
4951 printk("%02X =======> 0x%02X\n",
4952 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4958 /***********************************************************************
4959 ** Linux Kernel Specific
4961 static int __init acx_e_init_module(void)
4963 int r1, r2;
4965 acx_struct_size_check();
4967 printk("acx: this driver is still EXPERIMENTAL\n"
4968 "acx: reading README file and/or Craig's HOWTO is "
4969 "recommended, visit http://acx100.sourceforge.net/wiki in case "
4970 "of further questions/discussion\n");
4972 #if defined(CONFIG_ACX_MAC80211_PCI)
4973 r1 = acxpci_e_init_module();
4974 #else
4975 r1 = -EINVAL;
4976 #endif
4977 #if defined(CONFIG_ACX_MAC80211_USB)
4978 r2 = acxusb_e_init_module();
4979 #else
4980 r2 = -EINVAL;
4981 #endif
4982 if (r2 && r1) /* both failed! */
4983 return r2 ? r2 : r1;
4984 /* return success if at least one succeeded */
4985 return 0;
4988 static void __exit acx_e_cleanup_module(void)
4990 #if defined(CONFIG_ACX_MAC80211_PCI)
4991 acxpci_e_cleanup_module();
4992 #endif
4993 #if defined(CONFIG_ACX_MAC80211_USB)
4994 acxusb_e_cleanup_module();
4995 #endif
4998 module_init(acx_e_init_module)
4999 module_exit(acx_e_cleanup_module)