Merge branch 'master' of git://acx100.dyn-o-saur.com/acx-mac80211/
[acx-mac80211.git] / common.c
blobbe7b29e31e4e8c2943a9a67287294b155d807751
1 /**** (legal) claimer in README
2 ** Copyright (C) 2003 ACX100 Open Source Project
3 */
5 #include <linux/version.h>
6 #include <linux/module.h>
7 #include <linux/kernel.h>
8 #include <linux/sched.h>
9 #include <linux/types.h>
10 #include <linux/slab.h>
11 #include <linux/delay.h>
12 #include <linux/proc_fs.h>
13 #include <linux/if_arp.h>
14 #include <linux/rtnetlink.h>
15 #include <linux/netdevice.h>
16 #include <linux/etherdevice.h>
17 #include <linux/wireless.h>
18 #include <linux/pm.h>
19 #include <linux/vmalloc.h>
20 #include <linux/firmware.h>
21 //#include <net/iw_handler.h>
22 #include <linux/ethtool.h>
23 //#include <linux/utsrelease.h>
25 #include "acx.h"
26 #include "acx_debug.h"
27 #include "acx_log.h"
28 #include "acx_irq.h"
29 #include "acx_mmio.h"
32 /***********************************************************************
35 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf);
39 MODULE_LICENSE("GPL");
40 /* USB had this: MODULE_AUTHOR("Martin Wawro <martin.wawro AT uni-dortmund.de>"); */
41 MODULE_AUTHOR("ACX100 Open Source Driver development team");
42 MODULE_DESCRIPTION
43 ("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)");
45 MODULE_VERSION(ACX_RELEASE);
47 /***********************************************************************
49 /* Probably a number of acx's intermediate buffers for USB transfers,
50 ** not to be confused with number of descriptors in tx/rx rings
51 ** (which are not directly accessible to host in USB devices) */
52 #define USB_RX_CNT 10
53 #define USB_TX_CNT 10
56 /***********************************************************************
59 /* minutes to wait until next radio recalibration: */
60 #define RECALIB_PAUSE 5
62 /* Please keep acx_reg_domain_ids_len in sync... */
63 const u8 acx_reg_domain_ids[acx_reg_domain_ids_len] =
64 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 };
65 static const u16 reg_domain_channel_masks[acx_reg_domain_ids_len] =
66 { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc };
67 const char *const
68 acx_reg_domain_strings[] = {
69 /* 0 */ " 1-11 FCC (USA)",
70 /* 1 */ " 1-11 DOC/IC (Canada)",
71 /* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */
72 /* 2 */ " 1-13 ETSI (Europe)",
73 /* 3 */ "10-11 Spain",
74 /* 4 */ "10-13 France",
75 /* 5 */ " 14 MKK (Japan)",
76 /* 6 */ " 1-14 MKK1",
77 /* 7 */ " 3-9 Israel (not all firmware versions)",
78 NULL /* needs to remain as last entry */
83 /***********************************************************************
84 ** Debugging support
86 #ifdef PARANOID_LOCKING
87 static unsigned max_lock_time;
88 static unsigned max_sem_time;
90 /* Obvious or linux kernel specific derived code follows: */
92 void acx_lock_unhold()
94 max_lock_time = 0;
97 void acx_sem_unhold()
99 max_sem_time = 0;
102 static inline const char *sanitize_str(const char *s)
104 const char *t = strrchr(s, '/');
105 if (t)
106 return t + 1;
107 return s;
110 void acx_lock_debug(acx_device_t * adev, const char *where)
112 unsigned int count = 100 * 1000 * 1000;
113 where = sanitize_str(where);
114 while (--count) {
115 if (!spin_is_locked(&adev->spinlock))
116 break;
117 cpu_relax();
119 if (!count) {
120 printk(KERN_EMERG "LOCKUP: already taken at %s!\n",
121 adev->last_lock);
122 BUG();
124 adev->last_lock = where;
125 rdtscl(adev->lock_time);
128 void acx_unlock_debug(acx_device_t * adev, const char *where)
130 #ifdef SMP
131 if (!spin_is_locked(&adev->spinlock)) {
132 where = sanitize_str(where);
133 printk(KERN_EMERG "STRAY UNLOCK at %s!\n", where);
134 BUG();
136 #endif
137 if (acx_debug & L_LOCK) {
138 unsigned long diff;
139 rdtscl(diff);
140 diff -= adev->lock_time;
141 if (diff > max_lock_time) {
142 where = sanitize_str(where);
143 acx_log(LOG_DEBUG, L_LOCK, "max lock hold time "
144 "%ld CPU ticks from %s to %s\n", diff,
145 adev->last_lock, where);
146 max_lock_time = diff;
150 #endif /* PARANOID_LOCKING */
154 /***********************************************************************
155 ** Basically a mdelay/msleep with logging
157 void acx_s_mwait(int ms)
159 FN_ENTER;
160 msleep(ms);
161 FN_EXIT0;
165 /***********************************************************************
166 ** acx_cmd_status_str
168 const char *acx_cmd_status_str(unsigned int state)
170 static const char *const cmd_error_strings[] = {
171 "Idle",
172 "Success",
173 "Unknown Command",
174 "Invalid Information Element",
175 "Channel rejected",
176 "Channel invalid in current regulatory domain",
177 "MAC invalid",
178 "Command rejected (read-only information element)",
179 "Command rejected",
180 "Already asleep",
181 "TX in progress",
182 "Already awake",
183 "Write only",
184 "RX in progress",
185 "Invalid parameter",
186 "Scan in progress",
187 "Failed"
189 return state < ARRAY_SIZE(cmd_error_strings) ?
190 cmd_error_strings[state] : "?";
193 /***********************************************************************
194 ** acx_s_get_firmware_version
196 ** Obvious
198 void acx_s_get_firmware_version(acx_device_t * adev)
200 fw_ver_t fw;
201 u8 hexarr[4] = { 0, 0, 0, 0 };
202 int hexidx = 0, val = 0;
203 const char *num;
204 char c;
206 FN_ENTER;
208 memset(fw.fw_id, 'E', FW_ID_SIZE);
209 acx_s_query(adev, &fw, ACX1xx_REG_FWREV);
210 memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE);
211 adev->firmware_version[FW_ID_SIZE] = '\0';
213 acx_log(LOG_DEBUG, L_ANY, "fw_ver: fw_id='%s' hw_id=%08X\n",
214 adev->firmware_version, fw.hw_id);
216 if (strncmp(fw.fw_id, "Rev ", 4) != 0) {
217 acx_log(LOG_WARNING, L_ANY, "acx: strange firmware version string "
218 "'%s', please report\n", adev->firmware_version);
219 adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */
220 } else {
221 num = &fw.fw_id[4];
222 while (1) {
223 c = *num++;
224 if ((c == '.') || (c == '\0')) {
225 hexarr[hexidx++] = val;
226 if ((hexidx > 3) || (c == '\0')) /* end? */
227 break;
228 val = 0;
229 continue;
231 if ((c >= '0') && (c <= '9'))
232 c -= '0';
233 else
234 c = c - 'a' + (char)10;
235 val = val * 16 + c;
238 adev->firmware_numver = (u32) ((hexarr[0] << 24) |
239 (hexarr[1] << 16)
240 | (hexarr[2] << 8) | hexarr[3]);
241 acx_log(LOG_DEBUG, L_ANY, "firmware_numver 0x%08X\n",
242 adev->firmware_numver);
245 adev->firmware_id = le32_to_cpu(fw.hw_id);
247 /* we're able to find out more detailed chip names now */
248 switch (adev->firmware_id & 0xffff0000) {
249 case 0x01010000:
250 case 0x01020000:
251 adev->chip_name = "TNETW1100A";
252 break;
253 case 0x01030000:
254 adev->chip_name = "TNETW1100B";
255 break;
256 case 0x03000000:
257 case 0x03010000:
258 adev->chip_name = "TNETW1130";
259 break;
260 case 0x04030000: /* 0x04030101 is TNETW1450 */
261 adev->chip_name = "TNETW1450";
262 break;
263 default:
264 acx_log(LOG_WARNING, L_ANY,"unknown chip ID 0x%08X, "
265 "please report\n", adev->firmware_id);
266 break;
269 FN_EXIT0;
273 /***********************************************************************
274 ** acx_display_hardware_details
276 ** Displays hw/fw version, radio type etc...
278 ** Obvious
280 void acx_display_hardware_details(acx_device_t * adev)
282 const char *radio_str, *form_str;
284 FN_ENTER;
286 switch (adev->radio_type) {
287 case RADIO_MAXIM_0D:
288 radio_str = "Maxim";
289 break;
290 case RADIO_RFMD_11:
291 radio_str = "RFMD";
292 break;
293 case RADIO_RALINK_15:
294 radio_str = "Ralink";
295 break;
296 case RADIO_RADIA_16:
297 radio_str = "Radia";
298 break;
299 case RADIO_UNKNOWN_17:
300 /* TI seems to have a radio which is
301 * additionally 802.11a capable, too */
302 radio_str = "802.11a/b/g radio?! Please report";
303 break;
304 case RADIO_UNKNOWN_19:
305 radio_str = "A radio used by Safecom cards?! Please report";
306 break;
307 case RADIO_UNKNOWN_1B:
308 radio_str = "An unknown radio used by TNETW1450 USB adapters";
309 break;
310 default:
311 radio_str = "UNKNOWN, please report radio type name!";
312 break;
315 switch (adev->form_factor) {
316 case 0x00:
317 form_str = "unspecified";
318 break;
319 case 0x01:
320 form_str = "(mini-)PCI / CardBus";
321 break;
322 case 0x02:
323 form_str = "USB";
324 break;
325 case 0x03:
326 form_str = "Compact Flash";
327 break;
328 default:
329 form_str = "UNKNOWN, please report";
330 break;
333 acx_log(LOG_INFO, L_ANY, "acx: chipset %s, radio type 0x%02X (%s), "
334 "form factor 0x%02X (%s), EEPROM version 0x%02X, "
335 "uploaded firmware '%s'\n",
336 adev->chip_name, adev->radio_type, radio_str,
337 adev->form_factor, form_str, adev->eeprom_version,
338 adev->firmware_version);
340 FN_EXIT0;
344 /***********************************************************************
345 ** acx_e_get_stats, acx_e_get_wireless_stats
348 acx_e_get_stats(struct ieee80211_hw *hw,
349 struct ieee80211_low_level_stats *stats)
351 acx_device_t *adev = ieee2adev(hw);
352 unsigned long flags;
353 acx_lock(adev, flags);
354 memcpy(stats, &adev->ieee_stats, sizeof(*stats));
355 acx_unlock(adev, flags);
356 return 0;
360 /***********************************************************************
361 ** maps acx111 tx descr rate field to acx100 one
363 const u8 acx_bitpos2rate100[] = {
364 RATE100_1, /* 0 */
365 RATE100_2, /* 1 */
366 RATE100_5, /* 2 */
367 RATE100_2, /* 3, should not happen */
368 RATE100_2, /* 4, should not happen */
369 RATE100_11, /* 5 */
370 RATE100_2, /* 6, should not happen */
371 RATE100_2, /* 7, should not happen */
372 RATE100_22, /* 8 */
373 RATE100_2, /* 9, should not happen */
374 RATE100_2, /* 10, should not happen */
375 RATE100_2, /* 11, should not happen */
376 RATE100_2, /* 12, should not happen */
377 RATE100_2, /* 13, should not happen */
378 RATE100_2, /* 14, should not happen */
379 RATE100_2, /* 15, should not happen */
382 u8 acx_rate111to100(u16 r)
384 return acx_bitpos2rate100[highest_bit(r)];
388 /***********************************************************************
389 ** Calculate level like the feb 2003 windows driver seems to do
391 static u8 acx_signal_to_winlevel(u8 rawlevel)
393 /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
394 u8 winlevel = ((4 + (rawlevel * 5)) / 8);
396 if (winlevel > 100)
397 winlevel = 100;
398 return winlevel;
401 u8 acx_signal_determine_quality(u8 signal, u8 noise)
403 int qual;
405 qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2;
407 if (qual > 100)
408 return 100;
409 if (qual < 0)
410 return 0;
411 return qual;
415 /***********************************************************************
416 ** Interrogate/configure commands
419 /* FIXME: the lengths given here probably aren't always correct.
420 * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4",
421 * unless the firmware actually expects a different length than the struct length */
422 static const u16 acx100_ie_len[] = {
424 ACX100_REG_ACX_TIMER_LEN,
425 sizeof(acx100_ie_powersave_t) - 4, /* is that 6 or 8??? */
426 ACX1xx_REG_QUEUE_CONFIG_LEN,
427 ACX100_REG_BLOCK_SIZE_LEN,
428 ACX1xx_REG_MEMORY_CONFIG_OPTIONS_LEN,
429 ACX1xx_REG_RATE_FALLBACK_LEN,
430 ACX100_REG_WEP_OPTIONS_LEN,
431 ACX1xx_REG_MEMORY_MAP_LEN, /* ACX1xx_REG_SSID_LEN, */
433 ACX1xx_REG_ASSOC_ID_LEN,
435 ACX111_REG_CONFIG_OPTIONS_LEN,
436 ACX1xx_REG_FWREV_LEN,
437 ACX1xx_REG_FCS_ERROR_COUNT_LEN,
438 ACX1xx_REG_MEDIUM_USAGE_LEN,
439 ACX1xx_REG_RXCONFIG_LEN,
442 sizeof(fw_stats_t) - 4,
444 ACX1xx_REG_FEATURE_CONFIG_LEN,
445 ACX111_REG_KEY_CHOOSE_LEN,
446 ACX1FF_REG_MISC_CONFIG_TABLE_LEN,
447 ACX1FF_REG_WONE_CONFIG_LEN,
449 ACX1FF_REG_TID_CONFIG_LEN,
453 ACX1FF_REG_CALIB_ASSESSMENT_LEN,
454 ACX1FF_REG_BEACON_FILTER_OPTIONS_LEN,
455 ACX1FF_REG_LOW_RSSI_THRESH_OPT_LEN,
456 ACX1FF_REG_NOISE_HISTOGRAM_RESULTS_LEN,
458 ACX1FF_REG_PACKET_DETECT_THRESH_LEN,
459 ACX1FF_REG_TX_CONFIG_OPTIONS_LEN,
460 ACX1FF_REG_CCA_THRESHOLD_LEN,
461 ACX1FF_REG_EVENT_MASK_LEN,
462 ACX1FF_REG_DTIM_PERIOD_LEN,
464 ACX1FF_REG_ACI_CONFIG_SET_LEN,
471 ACX1FF_REG_EEPROM_VER_LEN,
474 static const u16 acx100_ie_len_dot11[] = {
476 ACX1xx_REG_DOT11_STATION_ID_LEN,
478 ACX100_REG_DOT11_BEACON_PERIOD_LEN,
479 ACX1xx_REG_DOT11_DTIM_PERIOD_LEN,
480 ACX1xx_REG_DOT11_SHORT_RETRY_LIMIT_LEN,
481 ACX1xx_REG_DOT11_LONG_RETRY_LIMIT_LEN,
482 ACX100_REG_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
483 ACX1xx_REG_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
485 ACX1xx_REG_DOT11_CURRENT_REG_DOMAIN_LEN,
486 ACX1xx_REG_DOT11_CURRENT_ANTENNA_LEN,
488 ACX1xx_REG_DOT11_TX_POWER_LEVEL_LEN,
489 ACX1xx_REG_DOT11_CURRENT_CCA_MODE_LEN,
490 ACX100_REG_DOT11_ED_THRESHOLD_LEN,
491 ACX1xx_REG_DOT11_WEP_DEFAULT_KEY_SET_LEN,
497 static const u16 acx111_ie_len[] = {
499 ACX100_REG_ACX_TIMER_LEN,
500 sizeof(acx111_ie_powersave_t) - 4,
501 ACX1xx_REG_QUEUE_CONFIG_LEN,
502 ACX100_REG_BLOCK_SIZE_LEN,
503 ACX1xx_REG_MEMORY_CONFIG_OPTIONS_LEN,
504 ACX1xx_REG_RATE_FALLBACK_LEN,
505 ACX100_REG_WEP_OPTIONS_LEN,
506 ACX1xx_REG_MEMORY_MAP_LEN, /* ACX1xx_REG_SSID_LEN, */
508 ACX1xx_REG_ASSOC_ID_LEN,
510 ACX111_REG_CONFIG_OPTIONS_LEN,
511 ACX1xx_REG_FWREV_LEN,
512 ACX1xx_REG_FCS_ERROR_COUNT_LEN,
513 ACX1xx_REG_MEDIUM_USAGE_LEN,
514 ACX1xx_REG_RXCONFIG_LEN,
517 sizeof(fw_stats_t) - 4,
519 ACX1xx_REG_FEATURE_CONFIG_LEN,
520 ACX111_REG_KEY_CHOOSE_LEN,
521 ACX1FF_REG_MISC_CONFIG_TABLE_LEN,
522 ACX1FF_REG_WONE_CONFIG_LEN,
524 ACX1FF_REG_TID_CONFIG_LEN,
528 ACX1FF_REG_CALIB_ASSESSMENT_LEN,
529 ACX1FF_REG_BEACON_FILTER_OPTIONS_LEN,
530 ACX1FF_REG_LOW_RSSI_THRESH_OPT_LEN,
531 ACX1FF_REG_NOISE_HISTOGRAM_RESULTS_LEN,
533 ACX1FF_REG_PACKET_DETECT_THRESH_LEN,
534 ACX1FF_REG_TX_CONFIG_OPTIONS_LEN,
535 ACX1FF_REG_CCA_THRESHOLD_LEN,
536 ACX1FF_REG_EVENT_MASK_LEN,
537 ACX1FF_REG_DTIM_PERIOD_LEN,
539 ACX1FF_REG_ACI_CONFIG_SET_LEN,
546 ACX1FF_REG_EEPROM_VER_LEN,
549 static const u16 acx111_ie_len_dot11[] = {
551 ACX1xx_REG_DOT11_STATION_ID_LEN,
553 ACX100_REG_DOT11_BEACON_PERIOD_LEN,
554 ACX1xx_REG_DOT11_DTIM_PERIOD_LEN,
555 ACX1xx_REG_DOT11_SHORT_RETRY_LIMIT_LEN,
556 ACX1xx_REG_DOT11_LONG_RETRY_LIMIT_LEN,
557 ACX100_REG_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
558 ACX1xx_REG_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
560 ACX1xx_REG_DOT11_CURRENT_REG_DOMAIN_LEN,
561 ACX1xx_REG_DOT11_CURRENT_ANTENNA_LEN,
563 ACX1xx_REG_DOT11_TX_POWER_LEVEL_LEN,
564 ACX1xx_REG_DOT11_CURRENT_CCA_MODE_LEN,
565 ACX100_REG_DOT11_ED_THRESHOLD_LEN,
566 ACX1xx_REG_DOT11_WEP_DEFAULT_KEY_SET_LEN,
573 #if !ACX_DEBUG
574 int acx_s_configure(acx_device_t * adev, void *pdr, int type)
576 #else
578 acx_s_configure_debug(acx_device_t * adev, void *pdr, int type,
579 const char *typestr)
581 #endif
582 u16 len;
583 int res;
585 if (type < 0x1000)
586 len = adev->ie_len[type];
587 else
588 len = adev->ie_len_dot11[type - 0x1000];
590 acx_log(LOG_DEBUG, L_CTL, "configure (type:%s,len:%u)\n", typestr, len);
591 if (unlikely(!len)) {
592 acx_log(LOG_DEBUG, L_ANY, "zero-length type %s?!\n", typestr);
595 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
596 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
597 res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4);
598 if (unlikely(OK != res)) {
599 #if ACX_DEBUG
600 acx_log(LOG_WARNING, L_ANY, "%s: configure (type:%s) FAILED\n",
601 wiphy_name(adev->ieee->wiphy), typestr);
602 #else
603 acx_log(LOG_WARNING, L_ANY,
604 "%s: configure (type:0x%X) FAILED\n",
605 wiphy_name(adev->ieee->wiphy), type);
606 #endif
607 /* dump_stack() is already done in issue_cmd() */
609 return res;
612 #if !ACX_DEBUG
613 int acx_s_query(acx_device_t * adev, void *pdr, int type)
615 #else
617 acx_s_query_debug(acx_device_t * adev, void *pdr, int type,
618 const char *typestr)
620 #endif
621 u16 len;
622 int res;
624 FN_ENTER;
626 /* FIXME: no check whether this exceeds the array yet.
627 * We should probably remember the number of entries... */
628 if (type < 0x1000)
629 len = adev->ie_len[type];
630 else
631 len = adev->ie_len_dot11[type - 0x1000];
633 acx_log(LOG_DEBUG, L_CTL, "query (type:%s,len:%u)\n",
634 typestr, len);
636 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
637 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
638 res = acx_s_issue_cmd(adev, ACX1xx_CMD_QUERY, pdr, len + 4);
639 if (unlikely(OK != res)) {
640 #if ACX_DEBUG
641 acx_log(LOG_WARNING, L_ANY,
642 "%s: query (type:%s) FAILED\n",
643 wiphy_name(adev->ieee->wiphy), typestr);
644 #else
645 acx_log(LOG_WARNING, L_ANY,
646 "%s: query (type:0x%X) FAILED\n",
647 wiphy_name(adev->ieee->wiphy), type);
648 #endif
649 /* dump_stack() is already done in issue_cmd() */
652 FN_EXIT1(res);
653 return res;
656 #if CMD_DISCOVERY
657 void great_inquisitor(acx_device_t * adev)
659 static struct {
660 u16 type;
661 u16 len;
662 /* 0x200 was too large here: */
663 u8 data[0x100 - 4];
664 } __attribute__ ((packed)) ie;
665 u16 type;
667 FN_ENTER;
669 /* 0..0x20, 0x1000..0x1020 */
670 for (type = 0; type <= 0x1020; type++) {
671 if (type == 0x21)
672 type = 0x1000;
673 ie.type = cpu_to_le16(type);
674 ie.len = cpu_to_le16(sizeof(ie) - 4);
675 acx_s_issue_cmd(adev, ACX1xx_CMD_QUERY, &ie, sizeof(ie));
677 FN_EXIT0;
679 #endif
682 #ifdef CONFIG_PROC_FS
683 /***********************************************************************
684 ** /proc files
686 /***********************************************************************
687 ** acx_l_proc_output
688 ** Generate content for our /proc entry
690 ** Arguments:
691 ** buf is a pointer to write output to
692 ** adev is the usual pointer to our private struct acx_device
693 ** Returns:
694 ** number of bytes actually written to buf
695 ** Side effects:
696 ** none
698 static int acx_l_proc_output(char *buf, acx_device_t * adev)
700 char *p = buf;
702 FN_ENTER;
704 p += sprintf(p,
705 "acx driver version:\t\t" ACX_RELEASE "\n"
706 "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n"
707 "chip name:\t\t\t%s (0x%08X)\n"
708 "radio type:\t\t\t0x%02X\n"
709 "form factor:\t\t\t0x%02X\n"
710 "EEPROM version:\t\t\t0x%02X\n"
711 "firmware version:\t\t%s (0x%08X)\n",
712 adev->chip_name, adev->firmware_id,
713 adev->radio_type,
714 adev->form_factor,
715 adev->eeprom_version,
716 adev->firmware_version, adev->firmware_numver);
718 FN_EXIT1(p - buf);
719 return p - buf;
723 /***********************************************************************
725 static int acx_s_proc_diag_output(char *buf, acx_device_t * adev)
727 char *p = buf;
728 unsigned long flags;
729 ssize_t len = 0, partlen;
730 u32 temp1, temp2;
731 u8 *st, *st_end;
732 #ifdef __BIG_ENDIAN
733 u8 *st2;
734 #endif
735 fw_stats_t *fw_stats;
736 char *part_str = NULL;
737 fw_stats_tx_t *tx = NULL;
738 fw_stats_rx_t *rx = NULL;
739 fw_stats_dma_t *dma = NULL;
740 fw_stats_irq_t *irq = NULL;
741 fw_stats_wep_t *wep = NULL;
742 fw_stats_pwr_t *pwr = NULL;
743 fw_stats_mic_t *mic = NULL;
744 fw_stats_aes_t *aes = NULL;
745 fw_stats_event_t *evt = NULL;
747 FN_ENTER;
749 acx_lock(adev, flags);
751 if (IS_PCI(adev))
752 p = acxpci_s_proc_diag_output(p, adev);
754 p += sprintf(p,
755 "\n"
756 "** network status **\n"
757 "dev_state_mask 0x%04X\n"
758 "mode %u, channel %u, "
759 "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
760 adev->dev_state_mask,
761 adev->mode, adev->channel,
762 adev->reg_dom_id, adev->reg_dom_chanmask);
763 p += sprintf(p,
764 "ESSID \"%s\", essid_active %d, essid_len %d, "
765 "essid_for_assoc \"%s\", nick \"%s\"\n"
766 "WEP ena %d, restricted %d, idx %d\n",
767 adev->essid, adev->essid_active, (int)adev->essid_len,
768 adev->essid_for_assoc, adev->nick,
769 adev->wep_enabled, adev->wep_restricted,
770 adev->wep_current_index);
771 p += sprintf(p, "dev_addr " MACSTR "\n", MAC(adev->dev_addr));
772 p += sprintf(p, "bssid " MACSTR "\n", MAC(adev->bssid));
773 p += sprintf(p, "ap_filter " MACSTR "\n", MAC(adev->ap));
775 p += sprintf(p, "\n" "** PHY status **\n"
776 "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
777 "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
778 "rate_basic 0x%04X, rate_oper 0x%04X\n"
779 "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
780 "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
781 adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */
782 adev->sensitivity, adev->antenna, adev->ed_threshold,
783 adev->cca, adev->preamble_mode, adev->rate_basic, adev->rate_oper, adev->rts_threshold,
784 adev->frag_threshold, adev->short_retry, adev->long_retry,
785 adev->msdu_lifetime, adev->listen_interval,
786 adev->beacon_interval);
788 acx_unlock(adev, flags);
790 p += sprintf(p,
791 "\n"
792 "** Firmware **\n"
793 "NOTE: version dependent statistics layout, "
794 "please report if you suspect wrong parsing!\n"
795 "\n" "version \"%s\"\n", adev->firmware_version);
797 /* TODO: may replace kmalloc/memset with kzalloc once
798 * Linux 2.6.14 is widespread */
799 fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL);
800 if (!fw_stats) {
801 FN_EXIT1(0);
802 return 0;
804 memset(fw_stats, 0, sizeof(*fw_stats));
806 st = (u8 *) fw_stats;
808 part_str = "statistics query command";
810 if (OK != acx_s_query(adev, st, ACX1xx_REG_FIRMWARE_STATISTICS))
811 goto fw_stats_end;
813 st += sizeof(u16);
814 len = *(u16 *) st;
816 if (len > sizeof(*fw_stats)) {
817 p += sprintf(p,
818 "firmware version with bigger fw_stats struct detected\n"
819 "(%zu vs. %zu), please report\n", len, sizeof(fw_stats_t));
820 if (len > sizeof(*fw_stats)) {
821 p += sprintf(p, "struct size exceeded allocation!\n");
822 len = sizeof(*fw_stats);
825 st += sizeof(u16);
826 st_end = st - 2 * sizeof(u16) + len;
828 #ifdef __BIG_ENDIAN
829 /* let's make one bold assumption here:
830 * (hopefully!) *all* statistics fields are u32 only,
831 * thus if we need to make endianness corrections
832 * we can simply do them in one go, in advance */
833 st2 = (u8 *) fw_stats;
834 for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4)
835 *(u32 *) st2 = le32_to_cpu(*(u32 *) st2);
836 #endif
838 part_str = "Rx/Tx";
840 /* directly at end of a struct part? --> no error! */
841 if (st == st_end)
842 goto fw_stats_end;
844 tx = (fw_stats_tx_t *) st;
845 st += sizeof(fw_stats_tx_t);
846 rx = (fw_stats_rx_t *) st;
847 st += sizeof(fw_stats_rx_t);
848 partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t);
850 if (IS_ACX100(adev)) {
851 /* at least ACX100 PCI F/W 1.9.8.b
852 * and ACX100 USB F/W 1.0.7-USB
853 * don't have those two fields... */
854 st -= 2 * sizeof(u32);
856 /* our parsing doesn't quite match this firmware yet,
857 * log failure */
858 if (st > st_end)
859 goto fw_stats_fail;
860 temp1 = temp2 = 999999999;
861 } else {
862 if (st > st_end)
863 goto fw_stats_fail;
864 temp1 = rx->rx_aci_events;
865 temp2 = rx->rx_aci_resets;
868 p += sprintf(p,
869 "%s:\n"
870 " tx_desc_overfl %u\n"
871 " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
872 " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n"
873 " rx_aci_events %u, rx_aci_resets %u\n",
874 part_str,
875 tx->tx_desc_of,
876 rx->rx_oom,
877 rx->rx_hdr_of,
878 rx->rx_hw_stuck,
879 rx->rx_dropped_frame,
880 rx->rx_frame_ptr_err, rx->rx_xfr_hint_trig, temp1, temp2);
882 part_str = "DMA";
884 if (st == st_end)
885 goto fw_stats_end;
887 dma = (fw_stats_dma_t *) st;
888 partlen = sizeof(fw_stats_dma_t);
889 st += partlen;
891 if (st > st_end)
892 goto fw_stats_fail;
894 p += sprintf(p,
895 "%s:\n"
896 " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n",
897 part_str,
898 dma->rx_dma_req,
899 dma->rx_dma_err, dma->tx_dma_req, dma->tx_dma_err);
901 part_str = "IRQ";
903 if (st == st_end)
904 goto fw_stats_end;
906 irq = (fw_stats_irq_t *) st;
907 partlen = sizeof(fw_stats_irq_t);
908 st += partlen;
910 if (st > st_end)
911 goto fw_stats_fail;
913 p += sprintf(p,
914 "%s:\n"
915 " cmd_cplt %u, fiq %u\n"
916 " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
917 " irqs %u, tx_procs %u, decrypt_done %u\n"
918 " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
919 " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
920 " host_acks %u, pci_pm %u, acm_wakeups %u\n",
921 part_str,
922 irq->cmd_cplt,
923 irq->fiq,
924 irq->rx_hdrs,
925 irq->rx_cmplt,
926 irq->rx_mem_of,
927 irq->rx_rdys,
928 irq->irqs,
929 irq->tx_procs,
930 irq->decrypt_done,
931 irq->dma_0_done,
932 irq->dma_1_done,
933 irq->tx_exch_complet,
934 irq->commands,
935 irq->rx_procs,
936 irq->hw_pm_mode_changes,
937 irq->host_acks, irq->pci_pm, irq->acm_wakeups);
939 part_str = "WEP";
941 if (st == st_end)
942 goto fw_stats_end;
944 wep = (fw_stats_wep_t *) st;
945 partlen = sizeof(fw_stats_wep_t);
946 st += partlen;
948 if (IS_ACX100(adev)) {
949 /* at least ACX100 PCI F/W 1.9.8.b
950 * and ACX100 USB F/W 1.0.7-USB
951 * don't have those two fields... */
952 st -= 2 * sizeof(u32);
953 if (st > st_end)
954 goto fw_stats_fail;
955 temp1 = temp2 = 999999999;
956 } else {
957 if (st > st_end)
958 goto fw_stats_fail;
959 temp1 = wep->wep_pkt_decrypt;
960 temp2 = wep->wep_decrypt_irqs;
963 p += sprintf(p,
964 "%s:\n"
965 " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
966 " wep_key_not_found %u, wep_decrypt_fail %u\n"
967 " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
968 part_str,
969 wep->wep_key_count,
970 wep->wep_default_key_count,
971 wep->dot11_def_key_mib,
972 wep->wep_key_not_found,
973 wep->wep_decrypt_fail, temp1, temp2);
975 part_str = "power";
977 if (st == st_end)
978 goto fw_stats_end;
980 pwr = (fw_stats_pwr_t *) st;
981 partlen = sizeof(fw_stats_pwr_t);
982 st += partlen;
984 if (st > st_end)
985 goto fw_stats_fail;
987 p += sprintf(p,
988 "%s:\n"
989 " tx_start_ctr %u, no_ps_tx_too_short %u\n"
990 " rx_start_ctr %u, no_ps_rx_too_short %u\n"
991 " lppd_started %u\n"
992 " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n",
993 part_str,
994 pwr->tx_start_ctr,
995 pwr->no_ps_tx_too_short,
996 pwr->rx_start_ctr,
997 pwr->no_ps_rx_too_short,
998 pwr->lppd_started,
999 pwr->no_lppd_too_noisy,
1000 pwr->no_lppd_too_short, pwr->no_lppd_matching_frame);
1002 part_str = "MIC";
1004 if (st == st_end)
1005 goto fw_stats_end;
1007 mic = (fw_stats_mic_t *) st;
1008 partlen = sizeof(fw_stats_mic_t);
1009 st += partlen;
1011 if (st > st_end)
1012 goto fw_stats_fail;
1014 p += sprintf(p,
1015 "%s:\n"
1016 " mic_rx_pkts %u, mic_calc_fail %u\n",
1017 part_str, mic->mic_rx_pkts, mic->mic_calc_fail);
1019 part_str = "AES";
1021 if (st == st_end)
1022 goto fw_stats_end;
1024 aes = (fw_stats_aes_t *) st;
1025 partlen = sizeof(fw_stats_aes_t);
1026 st += partlen;
1028 if (st > st_end)
1029 goto fw_stats_fail;
1031 p += sprintf(p,
1032 "%s:\n"
1033 " aes_enc_fail %u, aes_dec_fail %u\n"
1034 " aes_enc_pkts %u, aes_dec_pkts %u\n"
1035 " aes_enc_irq %u, aes_dec_irq %u\n",
1036 part_str,
1037 aes->aes_enc_fail,
1038 aes->aes_dec_fail,
1039 aes->aes_enc_pkts,
1040 aes->aes_dec_pkts, aes->aes_enc_irq, aes->aes_dec_irq);
1042 part_str = "event";
1044 if (st == st_end)
1045 goto fw_stats_end;
1047 evt = (fw_stats_event_t *) st;
1048 partlen = sizeof(fw_stats_event_t);
1049 st += partlen;
1051 if (st > st_end)
1052 goto fw_stats_fail;
1054 p += sprintf(p,
1055 "%s:\n"
1056 " heartbeat %u, calibration %u\n"
1057 " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
1058 " oom_late %u\n"
1059 " phy_tx_err %u, tx_stuck %u\n",
1060 part_str,
1061 evt->heartbeat,
1062 evt->calibration,
1063 evt->rx_mismatch,
1064 evt->rx_mem_empty,
1065 evt->rx_pool,
1066 evt->oom_late, evt->phy_tx_err, evt->tx_stuck);
1068 if (st < st_end)
1069 goto fw_stats_bigger;
1071 goto fw_stats_end;
1073 fw_stats_fail:
1074 st -= partlen;
1075 p += sprintf(p,
1076 "failed at %s part (size %zu), offset %zu (struct size %zu), "
1077 "please report\n", part_str, partlen,
1078 ((void *)st - (void *)fw_stats), len);
1080 fw_stats_bigger:
1081 for (; st < st_end; st += 4)
1082 p += sprintf(p,
1083 "UNKN%3d: %u\n",
1084 (int)((void *)st - (void *)fw_stats), *(u32 *) st);
1086 fw_stats_end:
1087 kfree(fw_stats);
1089 FN_EXIT1(p - buf);
1090 return p - buf;
1094 /***********************************************************************
1096 static int acx_s_proc_phy_output(char *buf, acx_device_t * adev)
1098 char *p = buf;
1099 int i;
1101 FN_ENTER;
1104 if (RADIO_RFMD_11 != adev->radio_type) {
1105 printk("sorry, not yet adapted for radio types "
1106 "other than RFMD, please verify "
1107 "PHY size etc. first!\n");
1108 goto end;
1112 /* The PHY area is only 0x80 bytes long; further pages after that
1113 * only have some page number registers with altered value,
1114 * all other registers remain the same. */
1115 for (i = 0; i < 0x80; i++) {
1116 acx_s_read_phy_reg(adev, i, p++);
1119 FN_EXIT1(p - buf);
1120 return p - buf;
1124 /***********************************************************************
1125 ** acx_e_read_proc_XXXX
1126 ** Handle our /proc entry
1128 ** Arguments:
1129 ** standard kernel read_proc interface
1130 ** Returns:
1131 ** number of bytes written to buf
1132 ** Side effects:
1133 ** none
1135 static int
1136 acx_e_read_proc(char *buf, char **start, off_t offset, int count,
1137 int *eof, void *data)
1139 acx_device_t *adev = (acx_device_t *) data;
1140 unsigned long flags;
1141 int length;
1143 FN_ENTER;
1145 acx_sem_lock(adev);
1146 acx_lock(adev, flags);
1147 /* fill buf */
1148 length = acx_l_proc_output(buf, adev);
1149 acx_unlock(adev, flags);
1150 acx_sem_unlock(adev);
1152 /* housekeeping */
1153 if (length <= offset + count)
1154 *eof = 1;
1155 *start = buf + offset;
1156 length -= offset;
1157 if (length > count)
1158 length = count;
1159 if (length < 0)
1160 length = 0;
1161 FN_EXIT1(length);
1162 return length;
1165 static int
1166 acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count,
1167 int *eof, void *data)
1169 acx_device_t *adev = (acx_device_t *) data;
1170 int length;
1172 FN_ENTER;
1174 acx_sem_lock(adev);
1175 /* fill buf */
1176 length = acx_s_proc_diag_output(buf, adev);
1177 acx_sem_unlock(adev);
1179 /* housekeeping */
1180 if (length <= offset + count)
1181 *eof = 1;
1182 *start = buf + offset;
1183 length -= offset;
1184 if (length > count)
1185 length = count;
1186 if (length < 0)
1187 length = 0;
1188 FN_EXIT1(length);
1189 return length;
1192 static int
1193 acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count,
1194 int *eof, void *data)
1196 acx_device_t *adev = (acx_device_t *) data;
1197 int length;
1199 FN_ENTER;
1201 /* fill buf */
1202 length = 0;
1203 if (IS_PCI(adev)) {
1204 acx_sem_lock(adev);
1205 length = acxpci_proc_eeprom_output(buf, adev);
1206 acx_sem_unlock(adev);
1209 /* housekeeping */
1210 if (length <= offset + count)
1211 *eof = 1;
1212 *start = buf + offset;
1213 length -= offset;
1214 if (length > count)
1215 length = count;
1216 if (length < 0)
1217 length = 0;
1218 FN_EXIT1(length);
1219 return length;
1222 static int
1223 acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count,
1224 int *eof, void *data)
1226 acx_device_t *adev = (acx_device_t *) data;
1227 int length;
1229 FN_ENTER;
1231 acx_sem_lock(adev);
1232 /* fill buf */
1233 length = acx_s_proc_phy_output(buf, adev);
1234 acx_sem_unlock(adev);
1236 /* housekeeping */
1237 if (length <= offset + count)
1238 *eof = 1;
1239 *start = buf + offset;
1240 length -= offset;
1241 if (length > count)
1242 length = count;
1243 if (length < 0)
1244 length = 0;
1245 FN_EXIT1(length);
1246 return length;
1250 /***********************************************************************
1251 ** /proc files registration
1253 static const char *const
1254 proc_files[] = { "", "_diag", "_eeprom", "_phy" };
1256 static read_proc_t *const
1257 proc_funcs[] = {
1258 acx_e_read_proc,
1259 acx_e_read_proc_diag,
1260 acx_e_read_proc_eeprom,
1261 acx_e_read_proc_phy
1264 static int manage_proc_entries(struct ieee80211_hw *hw, int remove)
1266 acx_device_t *adev = ieee2adev(hw);
1267 char procbuf[80];
1268 int i;
1270 FN_ENTER;
1272 for (i = 0; i < ARRAY_SIZE(proc_files); i++) {
1273 snprintf(procbuf, sizeof(procbuf),
1274 "driver/acx%s", proc_files[i]);
1275 acx_log(LOG_INFO, L_INIT, "%sing /proc entry %s\n",
1276 remove ? "remov" : "creat", procbuf);
1277 if (!remove) {
1278 if (!create_proc_read_entry
1279 (procbuf, 0, NULL, proc_funcs[i], adev)) {
1280 acx_log(LOG_WARNING, L_ANY,
1281 "cannot register /proc entry %s\n", procbuf);
1282 FN_EXIT1(NOT_OK);
1283 return NOT_OK;
1285 } else {
1286 remove_proc_entry(procbuf, NULL);
1289 FN_EXIT0;
1290 return OK;
1293 int acx_proc_register_entries(struct ieee80211_hw *ieee)
1295 return manage_proc_entries(ieee, 0);
1298 int acx_proc_unregister_entries(struct ieee80211_hw *ieee)
1300 return manage_proc_entries(ieee, 1);
1302 #endif /* CONFIG_PROC_FS */
1304 /****
1305 ** Gathered From rt2x00 and bcm43xx_mac80211 projects
1307 void acx_free_modes(acx_device_t * adev)
1310 // kfree(adev->modes);
1311 // adev->modes = NULL;
1315 #define RATETAB_ENT(_rate, _rateid, _flags) \
1317 .rate = (_rate), \
1318 .val = (_rateid), \
1319 .val2 = (_rateid), \
1320 .flags = (_flags), \
1324 static struct ieee80211_rate __acx_rates[] = {
1325 { .rate = 10,
1326 .val = RATE111_1,
1327 .flags = IEEE80211_RATE_CCK },
1328 { .rate = 20,
1329 .val = RATE111_2,
1330 .flags = IEEE80211_RATE_CCK },
1331 { .rate = 55,
1332 .val = RATE111_5,
1333 .flags = IEEE80211_RATE_CCK },
1334 { .rate = 110,
1335 .val = RATE111_11,
1336 .flags = IEEE80211_RATE_CCK },
1337 { .rate = 60,
1338 .val = RATE111_6,
1339 .flags = IEEE80211_RATE_OFDM },
1340 { .rate = 90,
1341 .val = RATE111_9,
1342 .flags = IEEE80211_RATE_OFDM },
1343 { .rate = 120,
1344 .val = RATE111_12,
1345 .flags = IEEE80211_RATE_OFDM },
1346 { .rate = 180,
1347 .val = RATE111_18,
1348 .flags = IEEE80211_RATE_OFDM },
1349 { .rate = 240,
1350 .val = RATE111_24,
1351 .flags = IEEE80211_RATE_OFDM },
1352 { .rate = 360,
1353 .val = RATE111_36,
1354 .flags = IEEE80211_RATE_OFDM },
1355 { .rate = 480,
1356 .val = RATE111_48,
1357 .flags = IEEE80211_RATE_OFDM },
1358 { .rate = 540,
1359 .val = RATE111_54,
1360 .flags = IEEE80211_RATE_OFDM },
1363 static struct ieee80211_channel channels[] = {
1364 { .chan = 1,
1365 .freq = 2412},
1366 { .chan = 2,
1367 .freq = 2417},
1368 { .chan = 3,
1369 .freq = 2422},
1370 { .chan = 4,
1371 .freq = 2427},
1372 { .chan = 5,
1373 .freq = 2432},
1374 { .chan = 6,
1375 .freq = 2437},
1376 { .chan = 7,
1377 .freq = 2442},
1378 { .chan = 8,
1379 .freq = 2447},
1380 { .chan = 9,
1381 .freq = 2452},
1382 { .chan = 10,
1383 .freq = 2457},
1384 { .chan = 11,
1385 .freq = 2462},
1386 { .chan = 12,
1387 .freq = 2467},
1388 { .chan = 13,
1389 .freq = 2472},
1392 int acx_setup_modes(acx_device_t * adev)
1394 struct ieee80211_hw *hw = adev->ieee;
1395 struct ieee80211_hw_mode *mode;
1396 int err = -ENOMEM;
1398 FN_ENTER;
1400 if (IS_ACX111(adev)) {
1402 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);
1403 err = acx_setup_modes_gphy(adev);
1405 mode = &adev->modes[0];
1407 /* from the zd1211rw driver: - do we need to do the same? */
1409 memcpy(mode->channels, channels, sizeof(channels));
1410 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1413 mode->mode = MODE_IEEE80211G;
1414 mode->num_channels = ARRAY_SIZE(channels);
1415 mode->num_rates = 12;
1416 mode->rates = __acx_rates;
1417 } else {
1419 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1420 err = acx_setup_modes_bphy(adev);
1422 mode = &adev->modes[1];
1424 /* from the zd1211rw driver: - do we need to do the same? */
1426 memcpy(mode->channels, channels, sizeof(channels));
1427 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1430 mode->mode = MODE_IEEE80211B;
1431 mode->num_channels = ARRAY_SIZE(channels);
1432 mode->num_rates = 4;
1433 mode->rates = __acx_rates;
1436 /* if (err && adev->modes)
1437 kfree(adev->modes);*/
1439 mode->channels = channels;
1440 err = ieee80211_register_hwmode(hw, mode);
1442 FN_EXIT1(err);
1443 return err;
1447 /***********************************************************************
1448 ** acx_fill_beacon_or_proberesp_template
1450 ** Origin: derived from rt2x00 project
1452 static int
1453 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1454 struct acx_template_beacon *templ,
1455 struct sk_buff* skb /* in host order! */)
1457 FN_ENTER;
1459 memcpy(templ,skb->data, skb->len);
1460 FN_EXIT1(skb->len);
1461 return skb->len;
1464 /***********************************************************************
1465 ** acx_s_set_beacon_template
1469 static int
1470 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1472 struct acx_template_beacon bcn;
1473 int len, result;
1475 FN_ENTER;
1476 acx_log(LOG_INFO, L_ANY, "size of template: %08zX, "
1477 "size of beacon: %08X\n",
1478 sizeof(struct acx_template_beacon),skb->len);
1479 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1480 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1482 FN_EXIT1(result);
1483 return result;
1486 /***********************************************************************
1487 ** acx_cmd_join_bssid
1489 ** Common code for both acx100 and acx111.
1491 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1492 static const u8 bitpos2genframe_txrate[] = {
1493 10, /* 0. 1 Mbit/s */
1494 20, /* 1. 2 Mbit/s */
1495 55, /* 2. 5.5 Mbit/s */
1496 0x0B, /* 3. 6 Mbit/s */
1497 0x0F, /* 4. 9 Mbit/s */
1498 110, /* 5. 11 Mbit/s */
1499 0x0A, /* 6. 12 Mbit/s */
1500 0x0E, /* 7. 18 Mbit/s */
1501 220, /* 8. 22 Mbit/s */
1502 0x09, /* 9. 24 Mbit/s */
1503 0x0D, /* 10. 36 Mbit/s */
1504 0x08, /* 11. 48 Mbit/s */
1505 0x0C, /* 12. 54 Mbit/s */
1506 10, /* 13. 1 Mbit/s, should never happen */
1507 10, /* 14. 1 Mbit/s, should never happen */
1508 10, /* 15. 1 Mbit/s, should never happen */
1511 /* Looks scary, eh?
1512 ** Actually, each one compiled into one AND and one SHIFT,
1513 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1514 static inline unsigned int rate111to5bits(unsigned int rate)
1516 return (rate & 0x7)
1517 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1518 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1522 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1524 acx_joinbss_t tmp;
1525 int dtim_interval;
1526 int i;
1528 if (mac_is_zero(bssid))
1529 return;
1531 FN_ENTER;
1533 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1534 1 : adev->dtim_interval;
1536 memset(&tmp, 0, sizeof(tmp));
1538 for (i = 0; i < ETH_ALEN; i++) {
1539 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1542 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1544 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1545 ** are sent with one of these rates */
1546 if (IS_ACX111(adev)) {
1547 /* It was experimentally determined that rates_basic
1548 ** can take 11g rates as well, not only rates
1549 ** defined with JOINBSS_RATES_BASIC111_nnn.
1550 ** Just use RATE111_nnn constants... */
1551 tmp.u.acx111.dtim_interval = dtim_interval;
1552 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1553 acx_log(LOG_INFO, L_ASSOC, "rates_basic:%04X, "
1554 "rates_supported:%04X\n",
1555 adev->rate_basic, adev->rate_oper);
1556 } else {
1557 tmp.u.acx100.dtim_interval = dtim_interval;
1558 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1559 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1560 acx_log(LOG_INFO, L_ASSOC, "rates_basic:%04X->%02X, "
1561 "rates_supported:%04X->%02X\n",
1562 adev->rate_basic, tmp.u.acx100.rates_basic,
1563 adev->rate_oper, tmp.u.acx100.rates_supported);
1566 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1567 ** will be sent (rate/modulation/preamble) */
1568 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1569 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1570 /* we can use short pre *if* all peers can understand it */
1571 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1573 /* we switch fw to STA mode in MONITOR mode, it seems to be
1574 ** the only mode where fw does not emit beacons by itself
1575 ** but allows us to send anything (we really want to retain
1576 ** ability to tx arbitrary frames in MONITOR mode)
1578 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1579 tmp.channel = adev->channel;
1580 tmp.essid_len = adev->essid_len;
1582 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1583 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1585 acx_log(LOG_DEBUG, L_ASSOC, "BSS_Type = %u\n", tmp.macmode);
1586 acx_log(LOG_DEBUG, L_ASSOC, "JoinBSSID MAC:" MACSTR "\n",
1587 adev->bssid, "\n");
1589 /* acx_update_capabilities(adev); */
1590 FN_EXIT0;
1593 /***********************************************************************
1594 ** acxpci_i_set_multicast_list
1595 ** FIXME: most likely needs refinement
1598 void acx_i_set_multicast_list(struct ieee80211_hw *hw,
1599 unsigned int changed_flags,
1600 unsigned int *total_flags,
1601 int mc_count, struct dev_addr_list *mc_list)
1603 acx_device_t *adev = ieee2adev(hw);
1604 unsigned long flags;
1606 FN_ENTER;
1608 acx_lock(adev, flags);
1610 changed_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1611 FIF_CONTROL | FIF_OTHER_BSS);
1612 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1613 FIF_CONTROL | FIF_OTHER_BSS);
1614 /* if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1615 return; */
1617 if (*total_flags) {
1618 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1619 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1620 SET_BIT(adev->set_mask, SET_RXCONFIG);
1621 /* let kernel know in case *we* needed to set promiscuous */
1622 } else {
1623 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1624 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1625 SET_BIT(adev->set_mask, SET_RXCONFIG);
1628 /* cannot update card settings directly here, atomic context */
1629 acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
1631 acx_unlock(adev, flags);
1633 FN_EXIT0;
1636 /***********************************************************************
1637 ** acx111 feature config
1639 ** Obvious
1641 static int
1642 acx111_s_get_feature_config(acx_device_t * adev,
1643 u32 * feature_options, u32 * data_flow_options)
1645 struct acx111_ie_feature_config feat;
1647 FN_ENTER;
1649 if (!IS_ACX111(adev)) {
1650 return NOT_OK;
1653 memset(&feat, 0, sizeof(feat));
1655 if (OK != acx_s_query(adev, &feat, ACX1xx_REG_FEATURE_CONFIG)) {
1656 FN_EXIT1(NOT_OK);
1657 return NOT_OK;
1659 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
1660 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1661 feat.feature_options, feat.data_flow_options);
1663 if (feature_options)
1664 *feature_options = le32_to_cpu(feat.feature_options);
1665 if (data_flow_options)
1666 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1668 FN_EXIT0;
1669 return OK;
1673 static int
1674 acx111_s_set_feature_config(acx_device_t * adev,
1675 u32 feature_options, u32 data_flow_options,
1676 unsigned int mode
1677 /* 0 == remove, 1 == add, 2 == set */ )
1679 struct acx111_ie_feature_config feat;
1681 FN_ENTER;
1683 if (!IS_ACX111(adev)) {
1684 FN_EXIT1(NOT_OK);
1685 return NOT_OK;
1688 if ((mode < 0) || (mode > 2)) {
1689 FN_EXIT1(NOT_OK);
1690 return NOT_OK;
1693 if (mode != 2)
1694 /* need to modify old data */
1695 acx111_s_get_feature_config(adev, &feat.feature_options,
1696 &feat.data_flow_options);
1697 else {
1698 /* need to set a completely new value */
1699 feat.feature_options = 0;
1700 feat.data_flow_options = 0;
1703 if (mode == 0) { /* remove */
1704 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1705 CLEAR_BIT(feat.data_flow_options,
1706 cpu_to_le32(data_flow_options));
1707 } else { /* add or set */
1708 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1709 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1712 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
1713 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1714 "new: feature 0x%08X dataflow 0x%08X\n",
1715 feature_options, data_flow_options, mode,
1716 le32_to_cpu(feat.feature_options),
1717 le32_to_cpu(feat.data_flow_options));
1719 if (OK != acx_s_configure(adev, &feat, ACX1xx_REG_FEATURE_CONFIG)) {
1720 FN_EXIT1(NOT_OK);
1721 return NOT_OK;
1724 FN_EXIT0;
1725 return OK;
1728 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1730 return acx111_s_set_feature_config(adev, f, d, 0);
1732 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1734 return acx111_s_set_feature_config(adev, f, d, 1);
1736 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1738 return acx111_s_set_feature_config(adev, f, d, 2);
1742 /***********************************************************************
1743 ** acx100_s_init_memory_pools
1745 static int
1746 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1748 acx100_ie_memblocksize_t MemoryBlockSize;
1749 acx100_ie_memconfigoption_t MemoryConfigOption;
1750 int TotalMemoryBlocks;
1751 int RxBlockNum;
1752 int TotalRxBlockSize;
1753 int TxBlockNum;
1754 int TotalTxBlockSize;
1756 FN_ENTER;
1758 /* Let's see if we can follow this:
1759 first we select our memory block size (which I think is
1760 completely arbitrary) */
1761 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1763 /* Then we alert the card to our decision of block size */
1764 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_REG_BLOCK_SIZE)) {
1765 goto bad;
1768 /* We figure out how many total blocks we can create, using
1769 the block size we chose, and the beginning and ending
1770 memory pointers, i.e.: end-start/size */
1771 TotalMemoryBlocks =
1772 (le32_to_cpu(mmt->PoolEnd) -
1773 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1775 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "TotalMemoryBlocks=%u (%u bytes)\n",
1776 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1778 /* MemoryConfigOption.DMA_config bitmask:
1779 access to ACX memory is to be done:
1780 0x00080000 using PCI conf space?!
1781 0x00040000 using IO instructions?
1782 0x00000000 using memory access instructions
1783 0x00020000 using local memory block linked list (else what?)
1784 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1786 if (IS_PCI(adev)) {
1787 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1788 /* Declare start of the Rx host pool */
1789 MemoryConfigOption.pRxHostDesc =
1790 cpu2acx(adev->rxhostdesc_startphy);
1791 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "pRxHostDesc 0x%08X, "
1792 "rxhostdesc_startphy 0x%lX\n",
1793 acx2cpu(MemoryConfigOption.pRxHostDesc),
1794 (long)adev->rxhostdesc_startphy);
1795 } else {
1796 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1799 /* 50% of the allotment of memory blocks go to tx descriptors */
1800 TxBlockNum = TotalMemoryBlocks / 2;
1801 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1803 /* and 50% go to the rx descriptors */
1804 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1805 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1807 /* size of the tx and rx descriptor queues */
1808 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1809 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1810 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "TxBlockNum %u RxBlockNum %u "
1811 "TotalTxBlockSize %u TotalTxBlockSize %u\n",
1812 TxBlockNum, RxBlockNum, TotalTxBlockSize, TotalRxBlockSize);
1815 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1816 MemoryConfigOption.rx_mem =
1817 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1819 /* align the rx descriptor queue to units of 0x20
1820 * and offset it by the tx descriptor queue */
1821 MemoryConfigOption.tx_mem =
1822 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
1823 0x1f) & ~0x1f);
1824 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "rx_mem %08X rx_mem %08X\n",
1825 MemoryConfigOption.tx_mem, MemoryConfigOption.rx_mem);
1827 /* alert the device to our decision */
1828 if (OK !=
1829 acx_s_configure(adev, &MemoryConfigOption,
1830 ACX1xx_REG_MEMORY_CONFIG_OPTIONS)) {
1831 goto bad;
1834 /* and tell the device to kick it into gear */
1835 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
1836 goto bad;
1838 FN_EXIT1(OK);
1839 return OK;
1840 bad:
1841 FN_EXIT1(NOT_OK);
1842 return NOT_OK;
1846 /***********************************************************************
1847 ** acx100_s_create_dma_regions
1849 ** Note that this fn messes up heavily with hardware, but we cannot
1850 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1852 /* OLD CODE? - let's rewrite it! */
1853 static int acx100_s_create_dma_regions(acx_device_t * adev)
1855 acx100_ie_queueconfig_t queueconf;
1856 acx_ie_memmap_t memmap;
1857 int res = NOT_OK;
1858 u32 tx_queue_start, rx_queue_start;
1860 FN_ENTER;
1862 /* read out the acx100 physical start address for the queues */
1863 if (OK != acx_s_query(adev, &memmap, ACX1xx_REG_MEMORY_MAP)) {
1864 goto fail;
1867 tx_queue_start = le32_to_cpu(memmap.QueueStart);
1868 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
1870 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "initializing Queue Indicator\n");
1872 memset(&queueconf, 0, sizeof(queueconf));
1874 /* Not needed for PCI, so we can avoid setting them altogether */
1875 if (IS_USB(adev)) {
1876 queueconf.NumTxDesc = USB_TX_CNT;
1877 queueconf.NumRxDesc = USB_RX_CNT;
1880 /* calculate size of queues */
1881 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
1882 RX_CNT * sizeof(rxdesc_t) + 8);
1883 queueconf.NumTxQueues = 1; /* number of tx queues */
1884 /* sets the beginning of the tx descriptor queue */
1885 queueconf.TxQueueStart = memmap.QueueStart;
1886 /* done by memset: queueconf.TxQueuePri = 0; */
1887 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
1888 queueconf.QueueOptions = 1; /* auto reset descriptor */
1889 /* sets the end of the rx descriptor queue */
1890 queueconf.QueueEnd =
1891 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
1893 /* sets the beginning of the next queue */
1894 queueconf.HostQueueEnd =
1895 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
1896 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_REG_QUEUE_CONFIG)) {
1897 goto fail;
1900 if (IS_PCI(adev)) {
1901 /* sets the beginning of the rx descriptor queue, after the tx descrs */
1902 if (OK != acxpci_s_create_hostdesc_queues(adev))
1903 goto fail;
1904 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
1907 if (OK != acx_s_query(adev, &memmap, ACX1xx_REG_MEMORY_MAP)) {
1908 goto fail;
1911 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
1912 0x1f) & ~0x1f);
1914 if (OK != acx_s_configure(adev, &memmap, ACX1xx_REG_MEMORY_MAP)) {
1915 goto fail;
1918 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
1919 goto fail;
1922 res = OK;
1923 goto end;
1925 fail:
1926 acx_s_mwait(1000); /* ? */
1927 if (IS_PCI(adev))
1928 acxpci_free_desc_queues(adev);
1929 end:
1930 FN_EXIT1(res);
1931 return res;
1935 /***********************************************************************
1936 ** acx111_s_create_dma_regions
1938 ** Note that this fn messes heavily with hardware, but we cannot
1939 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1941 #define ACX111_PERCENT(percent) ((percent)/5)
1943 static int acx111_s_create_dma_regions(acx_device_t * adev)
1945 struct acx111_ie_memoryconfig memconf;
1946 struct acx111_ie_queueconfig queueconf;
1947 u32 tx_queue_start, rx_queue_start;
1949 FN_ENTER;
1951 /* Calculate memory positions and queue sizes */
1953 /* Set up our host descriptor pool + data pool */
1954 if (IS_PCI(adev)) {
1955 if (OK != acxpci_s_create_hostdesc_queues(adev))
1956 goto fail;
1959 memset(&memconf, 0, sizeof(memconf));
1960 /* the number of STAs (STA contexts) to support
1961 ** NB: was set to 1 and everything seemed to work nevertheless... */
1962 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
1963 /* specify the memory block size. Default is 256 */
1964 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
1965 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
1966 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
1967 /* set the count of our queues
1968 ** NB: struct acx111_ie_memoryconfig shall be modified
1969 ** if we ever will switch to more than one rx and/or tx queue */
1970 memconf.count_rx_queues = 1;
1971 memconf.count_tx_queues = 1;
1972 /* 0 == Busmaster Indirect Memory Organization, which is what we want
1973 * (using linked host descs with their allocated mem).
1974 * 2 == Generic Bus Slave */
1975 /* done by memset: memconf.options = 0; */
1976 /* let's use 25% for fragmentations and 75% for frame transfers
1977 * (specified in units of 5%) */
1978 memconf.fragmentation = ACX111_PERCENT(75);
1979 /* Rx descriptor queue config */
1980 memconf.rx_queue1_count_descs = RX_CNT;
1981 memconf.rx_queue1_type = 7; /* must be set to 7 */
1982 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
1983 if (IS_PCI(adev)) {
1984 memconf.rx_queue1_host_rx_start =
1985 cpu2acx(adev->rxhostdesc_startphy);
1987 /* Tx descriptor queue config */
1988 memconf.tx_queue1_count_descs = TX_CNT;
1989 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
1991 /* NB1: this looks wrong: (memconf,ACX1xx_REG_QUEUE_CONFIG),
1992 ** (queueconf,ACX1xx_REG_MEMORY_CONFIG_OPTIONS) look swapped, eh?
1993 ** But it is actually correct wrt IE numbers.
1994 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_REG_QUEUE_CONFIG)
1995 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
1996 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
1997 if (OK != acx_s_configure(adev, &memconf, ACX1xx_REG_QUEUE_CONFIG)) {
1998 goto fail;
2001 acx_s_query(adev, &queueconf, ACX1xx_REG_MEMORY_CONFIG_OPTIONS);
2003 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2004 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2006 acx_log(LOG_DEBUG, L_INIT, "dump queue head (from card):\n"
2007 "len: %u\n"
2008 "tx_memory_block_address: %X\n"
2009 "rx_memory_block_address: %X\n"
2010 "tx1_queue address: %X\n"
2011 "rx1_queue address: %X\n",
2012 le16_to_cpu(queueconf.len),
2013 le32_to_cpu(queueconf.tx_memory_block_address),
2014 le32_to_cpu(queueconf.rx_memory_block_address),
2015 tx_queue_start, rx_queue_start);
2017 if (IS_PCI(adev))
2018 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2020 FN_EXIT1(OK);
2021 return OK;
2022 fail:
2023 if (IS_PCI(adev))
2024 acxpci_free_desc_queues(adev);
2026 FN_EXIT1(NOT_OK);
2027 return NOT_OK;
2031 /***********************************************************************
2033 static void acx_s_initialize_rx_config(acx_device_t * adev)
2035 struct {
2036 u16 id;
2037 u16 len;
2038 u16 rx_cfg1;
2039 u16 rx_cfg2;
2040 } __attribute__ ((packed)) cfg;
2041 switch (adev->mode) {
2042 case ACX_MODE_MONITOR:
2043 adev->rx_config_1 = (u16) (0
2044 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2045 /* | RX_CFG1_FILTER_SSID */
2046 /* | RX_CFG1_FILTER_BCAST */
2047 /* | RX_CFG1_RCV_MC_ADDR1 */
2048 /* | RX_CFG1_RCV_MC_ADDR0 */
2049 /* | RX_CFG1_FILTER_ALL_MULTI */
2050 /* | RX_CFG1_FILTER_BSSID */
2051 /* | RX_CFG1_FILTER_MAC */
2052 | RX_CFG1_RCV_PROMISCUOUS
2053 | RX_CFG1_INCLUDE_FCS
2054 /* | RX_CFG1_INCLUDE_PHY_HDR */
2056 adev->rx_config_2 = (u16) (0
2057 | RX_CFG2_RCV_ASSOC_REQ
2058 | RX_CFG2_RCV_AUTH_FRAMES
2059 | RX_CFG2_RCV_BEACON_FRAMES
2060 | RX_CFG2_RCV_CONTENTION_FREE
2061 | RX_CFG2_RCV_CTRL_FRAMES
2062 | RX_CFG2_RCV_DATA_FRAMES
2063 | RX_CFG2_RCV_BROKEN_FRAMES
2064 | RX_CFG2_RCV_MGMT_FRAMES
2065 | RX_CFG2_RCV_PROBE_REQ
2066 | RX_CFG2_RCV_PROBE_RESP
2067 | RX_CFG2_RCV_ACK_FRAMES
2068 | RX_CFG2_RCV_OTHER);
2069 break;
2070 default:
2071 adev->rx_config_1 = (u16) (0
2072 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2073 /* | RX_CFG1_FILTER_SSID */
2074 /* | RX_CFG1_FILTER_BCAST */
2075 /* | RX_CFG1_RCV_MC_ADDR1 */
2076 /* | RX_CFG1_RCV_MC_ADDR0 */
2077 /* | RX_CFG1_FILTER_ALL_MULTI */
2078 /* | RX_CFG1_FILTER_BSSID */
2079 /* | RX_CFG1_FILTER_MAC */
2080 | RX_CFG1_RCV_PROMISCUOUS
2081 /* | RX_CFG1_INCLUDE_FCS */
2082 /* | RX_CFG1_INCLUDE_PHY_HDR */
2084 adev->rx_config_2 = (u16) (0
2085 | RX_CFG2_RCV_ASSOC_REQ
2086 | RX_CFG2_RCV_AUTH_FRAMES
2087 | RX_CFG2_RCV_BEACON_FRAMES
2088 | RX_CFG2_RCV_CONTENTION_FREE
2089 | RX_CFG2_RCV_CTRL_FRAMES
2090 | RX_CFG2_RCV_DATA_FRAMES
2091 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2092 | RX_CFG2_RCV_MGMT_FRAMES
2093 | RX_CFG2_RCV_PROBE_REQ
2094 | RX_CFG2_RCV_PROBE_RESP
2095 | RX_CFG2_RCV_ACK_FRAMES
2096 | RX_CFG2_RCV_OTHER);
2097 break;
2099 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2101 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2102 || (adev->firmware_numver >= 0x02000000))
2103 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2104 else
2105 adev->phy_header_len = 0;
2107 acx_log(LOG_DEBUG, L_INIT, "setting RXconfig to %04X:%04X\n",
2108 adev->rx_config_1, adev->rx_config_2);
2110 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2111 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2112 acx_s_configure(adev, &cfg, ACX1xx_REG_RXCONFIG);
2116 /***********************************************************************
2117 ** FIXME: this should be solved in a general way for all radio types
2118 ** by decoding the radio firmware module,
2119 ** since it probably has some standard structure describing how to
2120 ** set the power level of the radio module which it controls.
2121 ** Or maybe not, since the radio module probably has a function interface
2122 ** instead which then manages Tx level programming :-\
2124 ** Obvious
2126 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2128 struct acx111_ie_tx_level tx_level;
2130 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2131 * 1 (30mW) [15dBm]
2132 * 2 (10mW) [10dBm]
2133 * For now, just assume all other acx111 cards have the same.
2134 * FIXME: Ideally we would query it here, but we first need a
2135 * standard way to query individual configoptions easily.
2136 * Well, now we have proper cfgopt txpower variables, but this still
2137 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2138 if (level_dbm <= 12) {
2139 tx_level.level = 2; /* 10 dBm */
2140 adev->tx_level_dbm = 10;
2141 } else {
2142 tx_level.level = 1; /* 15 dBm */
2143 adev->tx_level_dbm = 15;
2145 if (level_dbm != adev->tx_level_dbm)
2146 acx_log(LOG_WARNING, L_INIT, "acx111 firmware has specific "
2147 "power levels only: adjusted %d dBm to %d dBm!\n",
2148 level_dbm, adev->tx_level_dbm);
2150 return acx_s_configure(adev, &tx_level, ACX1xx_REG_DOT11_TX_POWER_LEVEL);
2153 static int acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
2155 if (IS_ACX111(adev)) {
2156 return acx111_s_set_tx_level(adev, level_dbm);
2158 if (IS_PCI(adev)) {
2159 return acx100pci_s_set_tx_level(adev, level_dbm);
2162 return OK;
2166 /***********************************************************************
2167 ** acx_s_set_defaults
2169 void acx_s_set_defaults(acx_device_t * adev)
2171 struct ieee80211_conf *conf = &adev->ieee->conf;
2172 unsigned long flags;
2173 u16 default_irq_mask = (IS_ACX111(adev)) ?
2174 ACX111_DEFAULT_IRQ_MASK :
2175 ACX100_DEFAULT_IRQ_MASK;
2177 FN_ENTER;
2179 acx_lock(adev, flags);
2180 /* do it before getting settings, prevent bogus channel 0 warning */
2181 adev->channel = 1;
2183 /* query some settings from the card.
2184 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2185 * query is REQUIRED, otherwise the card won't work correctly! */
2186 adev->get_mask =
2187 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2188 GETSET_REG_DOMAIN;
2189 /* Only ACX100 supports ED and CCA */
2190 if (IS_ACX100(adev))
2191 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2193 acx_unlock(adev, flags);
2195 acx_s_update_card_settings(adev);
2197 acx_lock(adev, flags);
2199 /* set our global interrupt mask */
2200 if (IS_PCI(adev))
2201 adev->irq_mask = default_irq_mask;
2203 adev->led_power = 1; /* LED is active on startup */
2204 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2205 adev->brange_time_last_state_change = jiffies;
2207 /* copy the MAC address we just got from the card
2208 * into our MAC address used during current 802.11 session */
2209 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
2210 MAC_BCAST(adev->ap);
2212 adev->essid_len =
2213 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2214 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2215 adev->essid_active = 1;
2217 /* we have a nick field to waste, so why not abuse it
2218 * to announce the driver version? ;-) */
2219 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2221 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2222 /* first regulatory domain entry in EEPROM == default reg. domain */
2223 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2226 /* 0xffff would be better, but then we won't get a "scan complete"
2227 * interrupt, so our current infrastructure will fail: */
2228 adev->scan_count = 1;
2229 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2230 adev->scan_duration = 100;
2231 adev->scan_probe_delay = 200;
2232 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2233 adev->scan_rate = ACX_SCAN_RATE_1;
2236 adev->mode = ACX_MODE_2_STA;
2237 adev->listen_interval = 100;
2238 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2239 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2241 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2243 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2244 adev->frag_threshold = 2346;
2246 /* use standard default values for retry limits */
2247 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2248 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2250 adev->preamble_mode = 2; /* auto */
2251 adev->fallback_threshold = 3;
2252 adev->stepup_threshold = 10;
2253 adev->rate_bcast = RATE111_1;
2254 adev->rate_bcast100 = RATE100_1;
2255 adev->rate_basic = RATE111_1 | RATE111_2;
2256 adev->rate_auto = 1;
2257 if (IS_ACX111(adev)) {
2258 adev->rate_oper = RATE111_ALL;
2259 } else {
2260 adev->rate_oper = RATE111_ACX100_COMPAT;
2263 /* Supported Rates element - the rates here are given in units of
2264 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2265 acx_l_update_ratevector(adev);
2267 /* set some more defaults */
2268 if (IS_ACX111(adev)) {
2269 /* 30mW (15dBm) is default, at least in my acx111 card: */
2270 adev->tx_level_dbm = 15;
2271 conf->power_level = adev->tx_level_dbm;
2272 acx_unlock(adev, flags);
2273 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2274 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2275 acx_lock(adev, flags);
2276 } else {
2277 /* don't use max. level, since it might be dangerous
2278 * (e.g. WRT54G people experience
2279 * excessive Tx power damage!) */
2280 adev->tx_level_dbm = 18;
2281 conf->power_level = adev->tx_level_dbm;
2282 acx_unlock(adev, flags);
2283 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2284 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2285 acx_lock(adev, flags);
2288 /* adev->tx_level_auto = 1; */
2289 if (IS_ACX111(adev)) {
2290 /* start with sensitivity level 1 out of 3: */
2291 adev->sensitivity = 1;
2294 /* #define ENABLE_POWER_SAVE */
2295 #ifdef ENABLE_POWER_SAVE
2296 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2297 adev->ps_listen_interval = 1;
2298 adev->ps_options =
2299 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2300 adev->ps_hangover_period = 30;
2301 adev->ps_enhanced_transition_time = 0;
2302 #else
2303 adev->ps_wakeup_cfg = 0;
2304 adev->ps_listen_interval = 0;
2305 adev->ps_options = 0;
2306 adev->ps_hangover_period = 0;
2307 adev->ps_enhanced_transition_time = 0;
2308 #endif
2310 /* These settings will be set in fw on ifup */
2311 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2312 /* configure card to do rate fallback when in auto rate mode */
2313 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2314 /* better re-init the antenna value we got above */
2315 | GETSET_ANTENNA
2316 #if POWER_SAVE_80211
2317 | GETSET_POWER_80211
2318 #endif
2321 acx_unlock(adev, flags);
2322 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2324 acx_s_initialize_rx_config(adev);
2326 FN_EXIT0;
2330 /***********************************************************************
2331 ** acx_l_process_rxbuf
2333 ** NB: used by USB code also
2335 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2337 struct ieee80211_hdr *hdr;
2338 u16 fc, buf_len;
2340 FN_ENTER;
2342 hdr = acx_get_wlan_hdr(adev, rxbuf);
2343 fc = le16_to_cpu(hdr->frame_control);
2344 /* length of frame from control field to first byte of FCS */
2345 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2347 acx_log_dump(LOG_DEBUG, L_DATA, hdr, buf_len, "RX: 802.11 buffer:\n");
2349 acx_l_rx(adev, rxbuf);
2350 /* Now check Rx quality level, AFTER processing packet.
2351 * I tried to figure out how to map these levels to dBm
2352 * values, but for the life of me I really didn't
2353 * manage to get it. Either these values are not meant to
2354 * be expressed in dBm, or it's some pretty complicated
2355 * calculation. */
2357 #ifdef FROM_SCAN_SOURCE_ONLY
2358 /* only consider packets originating from the MAC
2359 * address of the device that's managing our BSSID.
2360 * Disable it for now, since it removes information (levels
2361 * from different peers) and slows the Rx path. *//*
2362 if (adev->ap_client && mac_is_equal(hdr->a2, adev->ap_client->address)) {
2364 #endif
2366 FN_EXIT0;
2370 /***********************************************************************
2371 ** acx_l_handle_txrate_auto
2373 ** Theory of operation:
2374 ** client->rate_cap is a bitmask of rates client is capable of.
2375 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2376 ** It is set as a result of iwconfig rate N [auto]
2377 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2378 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2379 ** auto (0x00ff == 18Mbit or any lower value),
2380 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2382 ** client->rate_cur is a value for rate111 field in tx descriptor.
2383 ** It is always set to txrate_cfg sans zero or more most significant
2384 ** bits. This routine handles selection of new rate_cur value depending on
2385 ** outcome of last tx event.
2387 ** client->rate_100 is a precalculated rate value for acx100
2388 ** (we can do without it, but will need to calculate it on each tx).
2390 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2391 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2392 ** In theory you can implement it, but so far it is considered not worth doing.
2394 ** 22Mbit, of course, is PBCC always. */
2396 /* maps acx100 tx descr rate field to acx111 one */
2398 static u16 rate100to111(u8 r)
2400 switch (r) {
2401 case RATE100_1:
2402 return RATE111_1;
2403 case RATE100_2:
2404 return RATE111_2;
2405 case RATE100_5:
2406 case (RATE100_5 | RATE100_PBCC511):
2407 return RATE111_5;
2408 case RATE100_11:
2409 case (RATE100_11 | RATE100_PBCC511):
2410 return RATE111_11;
2411 case RATE100_22:
2412 return RATE111_22;
2413 default:
2414 printk("acx: unexpected acx100 txrate: %u! "
2415 "Please report\n", r);
2416 return RATE111_1;
2423 acx_i_start_xmit(struct ieee80211_hw *hw,
2424 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2426 acx_device_t *adev = ieee2adev(hw);
2427 tx_t *tx;
2428 void *txbuf;
2429 unsigned long flags;
2431 int txresult = NOT_OK;
2433 FN_ENTER;
2435 if (unlikely(!skb)) {
2436 /* indicate success */
2437 txresult = OK;
2438 goto out;
2441 if (unlikely(!adev)) {
2442 goto out;
2445 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2446 goto out;
2448 if (unlikely(!adev->initialized)) {
2449 goto out;
2452 acx_lock(adev, flags);
2454 tx = acx_l_alloc_tx(adev);
2456 if (unlikely(!tx)) {
2457 acx_log_ratelimited(LOG_WARNING, L_ANY, "%s: start_xmit: "
2458 "txdesc ring is full, dropping tx\n",
2459 wiphy_name(adev->ieee->wiphy));
2460 txresult = NOT_OK;
2461 goto out_unlock;
2464 txbuf = acx_l_get_txbuf(adev, tx);
2466 if (unlikely(!txbuf)) {
2467 /* Card was removed */
2468 txresult = NOT_OK;
2469 acx_l_dealloc_tx(adev, tx);
2470 goto out_unlock;
2472 memcpy(txbuf, skb->data, skb->len);
2474 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2476 txresult = OK;
2477 adev->stats.tx_packets++;
2478 adev->stats.tx_bytes += skb->len;
2480 out_unlock:
2481 acx_unlock(adev, flags);
2483 out:
2484 FN_EXIT1(txresult);
2485 return txresult;
2487 /***********************************************************************
2488 ** acx_l_update_ratevector
2490 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2492 const u8 acx_bitpos2ratebyte[] = {
2493 DOT11RATEBYTE_1,
2494 DOT11RATEBYTE_2,
2495 DOT11RATEBYTE_5_5,
2496 DOT11RATEBYTE_6_G,
2497 DOT11RATEBYTE_9_G,
2498 DOT11RATEBYTE_11,
2499 DOT11RATEBYTE_12_G,
2500 DOT11RATEBYTE_18_G,
2501 DOT11RATEBYTE_22,
2502 DOT11RATEBYTE_24_G,
2503 DOT11RATEBYTE_36_G,
2504 DOT11RATEBYTE_48_G,
2505 DOT11RATEBYTE_54_G,
2508 void acx_l_update_ratevector(acx_device_t * adev)
2510 u16 bcfg = adev->rate_basic;
2511 u16 ocfg = adev->rate_oper;
2512 u8 *supp = adev->rate_supported;
2513 const u8 *dot11 = acx_bitpos2ratebyte;
2515 FN_ENTER;
2517 while (ocfg) {
2518 if (ocfg & 1) {
2519 *supp = *dot11;
2520 if (bcfg & 1) {
2521 *supp |= 0x80;
2523 supp++;
2525 dot11++;
2526 ocfg >>= 1;
2527 bcfg >>= 1;
2529 adev->rate_supported_len = supp - adev->rate_supported;
2531 acx_log_dump(LOG_DEBUG, L_ASSOC, adev->rate_supported,
2532 adev->rate_supported_len, "new ratevector:\n");
2534 FN_EXIT0;
2537 /***********************************************************************
2538 ** acx_i_timer
2540 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2542 ** Obvious
2544 void acx_i_timer(unsigned long address)
2546 unsigned long flags;
2547 acx_device_t *adev = (acx_device_t *) address;
2549 FN_ENTER;
2551 acx_lock(adev, flags);
2553 FIXME();
2554 /* We need calibration and stats gather tasks to perform here */
2556 acx_unlock(adev, flags);
2558 FN_EXIT0;
2562 /***********************************************************************
2563 ** acx_set_timer
2565 ** Sets the 802.11 state management timer's timeout.
2567 ** Linux derived
2569 void acx_set_timer(acx_device_t * adev, int timeout_us)
2571 FN_ENTER;
2573 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_IRQ,
2574 "%s(%u ms)\n", __func__, timeout_us / 1000);
2576 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2577 acx_log(LOG_WARNING, L_ANY, "attempt to set the timer "
2578 "when the card interface is not up!\n");
2579 goto end;
2582 /* first check if the timer was already initialized, THEN modify it */
2583 if (adev->mgmt_timer.function) {
2584 mod_timer(&adev->mgmt_timer,
2585 jiffies + (timeout_us * HZ / 1000000));
2587 end:
2588 FN_EXIT0;
2591 /** acx_plcp_get_bitrate_cck
2593 ** Obvious
2595 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2597 switch (plcp) {
2598 case 0x0A:
2599 return ACX_CCK_RATE_1MB;
2600 case 0x14:
2601 return ACX_CCK_RATE_2MB;
2602 case 0x37:
2603 return ACX_CCK_RATE_5MB;
2604 case 0x6E:
2605 return ACX_CCK_RATE_11MB;
2607 return 0;
2610 /* Extract the bitrate out of an OFDM PLCP header. */
2611 /** Obvious **/
2612 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2614 switch (plcp & 0xF) {
2615 case 0xB:
2616 return ACX_OFDM_RATE_6MB;
2617 case 0xF:
2618 return ACX_OFDM_RATE_9MB;
2619 case 0xA:
2620 return ACX_OFDM_RATE_12MB;
2621 case 0xE:
2622 return ACX_OFDM_RATE_18MB;
2623 case 0x9:
2624 return ACX_OFDM_RATE_24MB;
2625 case 0xD:
2626 return ACX_OFDM_RATE_36MB;
2627 case 0x8:
2628 return ACX_OFDM_RATE_48MB;
2629 case 0xC:
2630 return ACX_OFDM_RATE_54MB;
2632 return 0;
2636 /***********************************************************************
2637 ** acx_l_rx
2639 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2640 ** buffer and feeds it to the network stack via netif_rx().
2642 ** Look to bcm43xx or p54
2644 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2647 struct ieee80211_rx_status* status = &adev->rx_status;
2648 struct ieee80211_hdr *w_hdr;
2649 struct sk_buff *skb;
2650 int buflen;
2651 FN_ENTER;
2653 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2654 acx_log_ratelimited(LOG_WARNING, L_ANY,
2655 "asked to receive a packet but interface is down??\n");
2656 goto out;
2659 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2660 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2662 * Allocate our skb
2664 skb = dev_alloc_skb(buflen + 2);
2666 if (!skb) {
2667 acx_log_ratelimited(LOG_WARNING, L_ANY,
2668 "skb allocation FAILED\n");
2669 goto out;
2672 skb_reserve(skb, 2);
2673 skb_put(skb, buflen);
2674 memcpy(skb->data, w_hdr, buflen);
2676 // memset(&status, 0, sizeof(status));
2678 status->mactime = rxbuf->time;
2679 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2680 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr);
2681 status->flag = 0;
2682 status->rate = rxbuf->phy_plcp_signal;
2683 status->antenna = 1;
2684 if (rxbuf->phy_stat_baseband & (1 << 3)) { /* Uses OFDM */
2685 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2686 } else {
2687 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2691 * FIXME: should it really be done here??
2693 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2694 adev->stats.rx_packets++;
2695 adev->stats.rx_bytes += skb->len;
2696 out:
2697 FN_EXIT0;
2702 /***********************************************************************
2703 ** acx_s_read_fw
2705 ** Loads a firmware image
2707 ** Returns:
2708 ** 0 unable to load file
2709 ** pointer to firmware success
2711 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2712 u32 * size)
2714 firmware_image_t *res;
2715 const struct firmware *fw_entry;
2717 res = NULL;
2718 acx_log(LOG_INFO, L_INIT, "requesting firmware image '%s'\n", file);
2719 if (!request_firmware(&fw_entry, file, dev)) {
2720 *size = 8;
2721 if (fw_entry->size >= 8)
2722 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2723 if (fw_entry->size != *size) {
2724 acx_log(LOG_WARNING, L_ANY,
2725 "acx: firmware size does not match "
2726 "firmware header: %d != %d, "
2727 "aborting fw upload\n",
2728 (int)fw_entry->size, (int)*size);
2729 goto release_ret;
2731 res = vmalloc(*size);
2732 if (!res) {
2733 acx_log(LOG_INFO, L_ANY, "acx: no memory for firmware "
2734 "(%u bytes)\n", *size);
2735 goto release_ret;
2737 memcpy(res, fw_entry->data, fw_entry->size);
2738 release_ret:
2739 release_firmware(fw_entry);
2740 return res;
2742 acx_log(LOG_WARNING, L_ANY, "acx: firmware image '%s' was not provided. "
2743 "Check your hotplug scripts\n", file);
2745 /* checksum will be verified in write_fw, so don't bother here */
2746 return res;
2750 /***********************************************************************
2751 ** acx_s_set_wepkey
2753 static void acx100_s_set_wepkey(acx_device_t * adev)
2755 ie_dot11WEPDefaultKey_t dk;
2756 int i;
2758 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2759 if (adev->wep_keys[i].size != 0) {
2760 acx_log(LOG_DEBUG, L_INIT, "setting WEP key: %d with "
2761 "total size: %d\n",
2762 i, (int)adev->wep_keys[i].size);
2763 dk.action = 1;
2764 dk.keySize = adev->wep_keys[i].size;
2765 dk.defaultKeyNum = i;
2766 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2767 acx_s_configure(adev, &dk,
2768 ACX100_REG_DOT11_WEP_DEFAULT_KEY_WRITE);
2773 static void acx111_s_set_wepkey(acx_device_t * adev)
2775 acx111WEPDefaultKey_t dk;
2776 int i;
2778 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2779 if (adev->wep_keys[i].size != 0) {
2780 acx_log(LOG_DEBUG, L_INIT, "setting WEP key: %d with "
2781 "total size: %d\n", i,
2782 (int)adev->wep_keys[i].size);
2783 memset(&dk, 0, sizeof(dk));
2784 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2785 dk.keySize = adev->wep_keys[i].size;
2787 /* are these two lines necessary? */
2788 dk.type = 0; /* default WEP key */
2789 dk.index = 0; /* ignored when setting default key */
2791 dk.defaultKeyNum = i;
2792 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2793 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2794 sizeof(dk));
2798 /* Obvious */
2799 static void acx_s_set_wepkey(acx_device_t * adev)
2801 if (IS_ACX111(adev))
2802 acx111_s_set_wepkey(adev);
2803 else
2804 acx100_s_set_wepkey(adev);
2808 /***********************************************************************
2809 ** acx100_s_init_wep
2811 ** FIXME: this should probably be moved into the new card settings
2812 ** management, but since we're also modifying the memory map layout here
2813 ** due to the WEP key space we want, we should take care...
2815 static int acx100_s_init_wep(acx_device_t * adev)
2817 acx100_ie_wep_options_t options;
2818 ie_dot11WEPDefaultKeyID_t dk;
2819 acx_ie_memmap_t pt;
2820 int res = NOT_OK;
2822 FN_ENTER;
2824 if (OK != acx_s_query(adev, &pt, ACX1xx_REG_MEMORY_MAP)) {
2825 goto fail;
2828 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "CodeEnd:%X\n", pt.CodeEnd);
2830 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2831 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2833 if (OK != acx_s_configure(adev, &pt, ACX1xx_REG_MEMORY_MAP)) {
2834 goto fail;
2837 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2838 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2839 options.WEPOption = 0x00;
2841 acx_log(LOG_DEBUG, L_ASSOC, "writing WEP options\n");
2842 acx_s_configure(adev, &options, ACX100_REG_WEP_OPTIONS);
2844 acx100_s_set_wepkey(adev);
2846 if (adev->wep_keys[adev->wep_current_index].size != 0) {
2847 acx_log(LOG_DEBUG, L_ASSOC,
2848 "setting active default WEP key number: %d\n",
2849 adev->wep_current_index);
2850 dk.KeyID = adev->wep_current_index;
2851 acx_s_configure(adev, &dk, ACX1xx_REG_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
2853 /* FIXME!!! wep_key_struct is filled nowhere! But adev
2854 * is initialized to 0, and we don't REALLY need those keys either */
2855 /* for (i = 0; i < 10; i++) {
2856 if (adev->wep_key_struct[i].len != 0) {
2857 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
2858 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
2859 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
2860 wep_mgmt.Action = cpu_to_le16(1);
2861 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
2862 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
2863 adev->wep_key_struct[i].index = i;
2869 /* now retrieve the updated WEPCacheEnd pointer... */
2870 if (OK != acx_s_query(adev, &pt, ACX1xx_REG_MEMORY_MAP)) {
2871 acx_log(LOG_WARNING, L_ANY,
2872 "%s: ACX1xx_REG_MEMORY_MAP read #2 FAILED\n",
2873 wiphy_name(adev->ieee->wiphy));
2874 goto fail;
2876 /* ...and tell it to start allocating templates at that location */
2877 /* (no endianness conversion needed) */
2878 pt.PacketTemplateStart = pt.WEPCacheEnd;
2880 if (OK != acx_s_configure(adev, &pt, ACX1xx_REG_MEMORY_MAP)) {
2881 acx_log(LOG_WARNING, L_ANY,
2882 "%s: ACX1xx_REG_MEMORY_MAP write #2 FAILED\n",
2883 wiphy_name(adev->ieee->wiphy));
2884 goto fail;
2886 res = OK;
2888 fail:
2889 FN_EXIT1(res);
2890 return res;
2894 static int
2895 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
2896 unsigned int cmd)
2898 int res;
2899 union {
2900 acx_template_nullframe_t null;
2901 acx_template_beacon_t b;
2902 acx_template_tim_t tim;
2903 acx_template_probereq_t preq;
2904 acx_template_proberesp_t presp;
2905 } templ;
2907 memset(&templ, 0, len);
2908 templ.null.size = cpu_to_le16(len - 2);
2909 res = acx_s_issue_cmd(adev, cmd, &templ, len);
2910 return res;
2913 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
2915 return acx_s_init_max_template_generic(adev,
2916 sizeof(acx_template_nullframe_t),
2917 ACX1xx_CMD_CONFIG_NULL_DATA);
2920 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
2922 return acx_s_init_max_template_generic(adev,
2923 sizeof(acx_template_beacon_t),
2924 ACX1xx_CMD_CONFIG_BEACON);
2927 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
2929 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
2930 ACX1xx_CMD_CONFIG_TIM);
2933 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
2935 return acx_s_init_max_template_generic(adev,
2936 sizeof(acx_template_proberesp_t),
2937 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
2940 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
2942 return acx_s_init_max_template_generic(adev,
2943 sizeof(acx_template_probereq_t),
2944 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
2947 /***********************************************************************
2948 ** acx_s_set_tim_template
2950 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
2951 ** by calling this function
2952 ** (it can be done by irq handler on each DTIM irq or by timer...)
2954 [802.11 7.3.2.6] TIM information element:
2955 - 1 EID
2956 - 1 Length
2957 1 1 DTIM Count
2958 indicates how many beacons (including this) appear before next DTIM
2959 (0=this one is a DTIM)
2960 2 1 DTIM Period
2961 number of beacons between successive DTIMs
2962 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
2963 3 1 Bitmap Control
2964 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
2965 set to 1 in TIM elements with a value of 0 in the DTIM Count field
2966 when one or more broadcast or multicast frames are buffered at the AP.
2967 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
2968 4 n Partial Virtual Bitmap
2969 Visible part of traffic-indication bitmap.
2970 Full bitmap consists of 2008 bits (251 octets) such that bit number N
2971 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
2972 in octet number N/8 where the low-order bit of each octet is bit0,
2973 and the high order bit is bit7.
2974 Each set bit in virtual bitmap corresponds to traffic buffered by AP
2975 for a specific station (with corresponding AID?).
2976 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
2977 Bitmap Offset is a number of skipped zero octets (see above).
2978 'Missing' octets at the tail are also assumed to be zero.
2979 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
2980 This means that traffic-indication bitmap is:
2981 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
2982 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
2984 static int acx_s_set_tim_template(acx_device_t * adev)
2986 /* For now, configure smallish test bitmap, all zero ("no pending data") */
2987 enum { bitmap_size = 5 };
2989 acx_template_tim_t t;
2990 int result;
2992 FN_ENTER;
2994 memset(&t, 0, sizeof(t));
2995 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
2996 t.tim_eid = WLAN_EID_TIM;
2997 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
2998 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
2999 FN_EXIT1(result);
3000 return result;
3006 #if POWER_SAVE_80211
3007 /***********************************************************************
3008 ** acx_s_set_null_data_template
3010 static int acx_s_set_null_data_template(acx_device_t * adev)
3012 struct acx_template_nullframe b;
3013 int result;
3015 FN_ENTER;
3017 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3019 b.size = cpu_to_le16(sizeof(b) - 2);
3020 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3021 b.hdr.dur = 0;
3022 MAC_BCAST(b.hdr.a1);
3023 MAC_COPY(b.hdr.a2, adev->dev_addr);
3024 MAC_COPY(b.hdr.a3, adev->bssid);
3025 b.hdr.seq = 0;
3027 result =
3028 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3030 FN_EXIT1(result);
3031 return result;
3033 #endif
3040 /***********************************************************************
3041 ** acx_s_init_packet_templates()
3043 ** NOTE: order is very important here, to have a correct memory layout!
3044 ** init templates: max Probe Request (station mode), max NULL data,
3045 ** max Beacon, max TIM, max Probe Response.
3047 static int acx_s_init_packet_templates(acx_device_t * adev)
3049 acx_ie_memmap_t mm; /* ACX100 only */
3050 int result = NOT_OK;
3052 FN_ENTER;
3054 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_INIT,
3055 "initializing max packet templates\n");
3057 if (OK != acx_s_init_max_probe_request_template(adev))
3058 goto failed;
3060 if (OK != acx_s_init_max_null_data_template(adev))
3061 goto failed;
3063 if (OK != acx_s_init_max_beacon_template(adev))
3064 goto failed;
3066 if (OK != acx_s_init_max_tim_template(adev))
3067 goto failed;
3069 if (OK != acx_s_init_max_probe_response_template(adev))
3070 goto failed;
3072 if (IS_ACX111(adev)) {
3073 /* ACX111 doesn't need the memory map magic below,
3074 * and the other templates will be set later (acx_start) */
3075 result = OK;
3076 goto success;
3079 /* ACX100 will have its TIM template set,
3080 * and we also need to update the memory map */
3082 if (OK != acx_s_set_tim_template(adev))
3083 goto failed_acx100;
3085 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
3086 "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3088 if (OK != acx_s_query(adev, &mm, ACX1xx_REG_MEMORY_MAP))
3089 goto failed_acx100;
3091 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3092 if (OK != acx_s_configure(adev, &mm, ACX1xx_REG_MEMORY_MAP))
3093 goto failed_acx100;
3095 result = OK;
3096 goto success;
3098 failed_acx100:
3099 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_INIT,
3100 /* "cb=0x%X\n" */
3101 "ACXMemoryMap:\n"
3102 ".CodeStart=0x%X\n"
3103 ".CodeEnd=0x%X\n"
3104 ".WEPCacheStart=0x%X\n"
3105 ".WEPCacheEnd=0x%X\n"
3106 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3107 /* len, */
3108 le32_to_cpu(mm.CodeStart),
3109 le32_to_cpu(mm.CodeEnd),
3110 le32_to_cpu(mm.WEPCacheStart),
3111 le32_to_cpu(mm.WEPCacheEnd),
3112 le32_to_cpu(mm.PacketTemplateStart),
3113 le32_to_cpu(mm.PacketTemplateEnd));
3115 failed:
3116 acx_log(LOG_WARNING, L_ANY, "%s: %s() FAILED\n",
3117 wiphy_name(adev->ieee->wiphy), __func__);
3119 success:
3120 FN_EXIT1(result);
3121 return result;
3126 /***********************************************************************
3127 ** acx_s_init_mac
3129 int acx_s_init_mac(acx_device_t * adev)
3131 int result = NOT_OK;
3133 FN_ENTER;
3135 if (IS_ACX111(adev)) {
3136 adev->ie_len = acx111_ie_len;
3137 adev->ie_len_dot11 = acx111_ie_len_dot11;
3138 } else {
3139 adev->ie_len = acx100_ie_len;
3140 adev->ie_len_dot11 = acx100_ie_len_dot11;
3143 if (IS_PCI(adev)) {
3144 adev->memblocksize = 256; /* 256 is default */
3145 /* try to load radio for both ACX100 and ACX111, since both
3146 * chips have at least some firmware versions making use of an
3147 * external radio module */
3148 acxpci_s_upload_radio(adev);
3149 } else {
3150 adev->memblocksize = 128;
3153 if (IS_ACX111(adev)) {
3154 /* for ACX111, the order is different from ACX100
3155 1. init packet templates
3156 2. create station context and create dma regions
3157 3. init wep default keys
3159 if (OK != acx_s_init_packet_templates(adev))
3160 goto fail;
3161 if (OK != acx111_s_create_dma_regions(adev)) {
3162 acx_log(LOG_WARNING, L_ANY,
3163 "%s: acx111_create_dma_regions FAILED\n",
3164 wiphy_name(adev->ieee->wiphy));
3165 goto fail;
3167 } else {
3168 if (OK != acx100_s_init_wep(adev))
3169 goto fail;
3170 if (OK != acx_s_init_packet_templates(adev))
3171 goto fail;
3172 if (OK != acx100_s_create_dma_regions(adev)) {
3173 acx_log(LOG_WARNING, L_ANY,
3174 "%s: acx100_create_dma_regions FAILED\n",
3175 wiphy_name(adev->ieee->wiphy));
3176 goto fail;
3180 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3181 result = OK;
3183 fail:
3184 if (result)
3185 acx_log(LOG_WARNING, L_ANY, "init_mac() FAILED\n");
3186 FN_EXIT1(result);
3187 return result;
3192 #if POWER_SAVE_80211
3193 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3195 /* merge both structs in a union to be able to have common code */
3196 union {
3197 acx111_ie_powersave_t acx111;
3198 acx100_ie_powersave_t acx100;
3199 } pm;
3201 /* change 802.11 power save mode settings */
3202 acx_log(LOG_DEBUG, L_INIT, "updating 802.11 power save mode settings: "
3203 "wakeup_cfg 0x%02X, listen interval %u, "
3204 "options 0x%02X, hangover period %u, "
3205 "enhanced_ps_transition_time %u\n",
3206 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3207 adev->ps_options, adev->ps_hangover_period,
3208 adev->ps_enhanced_transition_time);
3209 acx_s_query(adev, &pm, ACX1xx_REG_POWER_MGMT);
3210 acx_log(LOG_DEBUG, L_INIT, "Previous PS mode settings: "
3211 "wakeup_cfg 0x%02X, "
3212 "listen interval %u, options 0x%02X, "
3213 "hangover period %u, "
3214 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3215 pm.acx111.wakeup_cfg,
3216 pm.acx111.listen_interval,
3217 pm.acx111.options,
3218 pm.acx111.hangover_period,
3219 IS_ACX111(adev) ?
3220 pm.acx111.enhanced_ps_transition_time
3221 : pm.acx100.enhanced_ps_transition_time,
3222 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3223 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3224 pm.acx111.listen_interval = adev->ps_listen_interval;
3225 pm.acx111.options = adev->ps_options;
3226 pm.acx111.hangover_period = adev->ps_hangover_period;
3227 if (IS_ACX111(adev)) {
3228 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3229 pm.acx111.enhanced_ps_transition_time =
3230 cpu_to_le32(adev->ps_enhanced_transition_time);
3231 } else {
3232 pm.acx100.enhanced_ps_transition_time =
3233 cpu_to_le16(adev->ps_enhanced_transition_time);
3235 acx_s_configure(adev, &pm, ACX1xx_REG_POWER_MGMT);
3236 acx_s_query(adev, &pm, ACX1xx_REG_POWER_MGMT);
3237 acx_log(LOG_DEBUG, L_INIT, "wakeup_cfg: 0x%02X\n",
3238 pm.acx111.wakeup_cfg);
3239 acx_s_mwait(40);
3240 acx_s_query(adev, &pm, ACX1xx_REG_POWER_MGMT);
3241 acx_log(LOG_DEBUG, L_INIT, "wakeup_cfg: 0x%02X\n",
3242 pm.acx111.wakeup_cfg);
3243 acx_log(LOG_DEBUG, L_INIT, "power save mode change %s\n",
3244 (pm.acx111.wakeup_cfg & PS_CFG_PENDING) ?
3245 "FAILED" : "was successful");
3246 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3247 * that power save mode change was successful. */
3248 /* FIXME: we shouldn't trigger a scan immediately after
3249 * fiddling with power save mode (since the firmware is sending
3250 * a NULL frame then). */
3252 #endif
3255 /***********************************************************************
3256 ** acx_s_update_card_settings
3258 ** Applies accumulated changes in various adev->xxxx members
3259 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3260 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3262 void acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
3264 unsigned mask;
3266 unsigned int i;
3268 for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
3269 if (acx_reg_domain_ids[i] == adev->reg_dom_id)
3270 break;
3272 if (sizeof(acx_reg_domain_ids) == i) {
3273 acx_log(LOG_WARNING, L_INIT,
3274 "Invalid or unsupported regulatory domain"
3275 " 0x%02X specified, falling back to FCC (USA)!"
3276 " Please report if this sounds fishy!\n",
3277 adev->reg_dom_id);
3278 i = 0;
3279 adev->reg_dom_id = acx_reg_domain_ids[i];
3281 /* since there was a mismatch, we need to force updating */
3282 do_set = 1;
3285 if (do_set) {
3286 acx_ie_generic_t dom;
3287 dom.m.bytes[0] = adev->reg_dom_id;
3288 acx_s_configure(adev, &dom, ACX1xx_REG_DOT11_CURRENT_REG_DOMAIN);
3291 adev->reg_dom_chanmask = reg_domain_channel_masks[i];
3293 mask = (1 << (adev->channel - 1));
3296 * Check our channels wrt the current regulatory domain
3298 if (adev->reg_dom_chanmask & mask)
3299 return;
3302 * Hmm nope, need to adjust channels!
3305 mask = 1;
3306 for (i = 1; i <= 14; i++) {
3307 if (!(adev->reg_dom_chanmask & mask)) {
3308 mask <<= 1;
3309 continue;
3311 acx_log(LOG_INFO, L_ANY, "%s: adjusting selected channel "
3312 "from %d to %d due to new regulatory domain\n",
3313 wiphy_name(adev->ieee->wiphy), adev->channel, i);
3314 adev->channel = i;
3315 break;
3319 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3321 u32 feature1, feature2;
3323 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3324 acx_log(LOG_WARNING, L_ANY,
3325 "%s: invalid sensitivity setting (1..3), "
3326 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3327 adev->sensitivity = 1;
3329 acx111_s_get_feature_config(adev, &feature1, &feature2);
3330 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3331 if (adev->sensitivity > 1)
3332 SET_BIT(feature1, FEATURE1_LOW_RX);
3333 if (adev->sensitivity > 2)
3334 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3335 acx111_s_feature_set(adev, feature1, feature2);
3339 void acx_s_update_card_settings(acx_device_t *adev)
3341 unsigned long flags;
3342 unsigned int start_scan = 0;
3343 int i;
3345 FN_ENTER;
3347 acx_log(LOG_DEBUG, L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3348 adev->get_mask, adev->set_mask);
3350 /* Track dependencies betweed various settings */
3352 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3353 acx_log(LOG_DEBUG, L_INIT,
3354 "important setting has been changed. "
3355 "Need to update packet templates, too\n");
3356 SET_BIT(adev->set_mask, SET_TEMPLATES);
3358 if (adev->set_mask & GETSET_CHANNEL) {
3359 /* This will actually tune RX/TX to the channel */
3360 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3361 switch (adev->mode) {
3362 case ACX_MODE_0_ADHOC:
3363 case ACX_MODE_3_AP:
3364 /* Beacons contain channel# - update them */
3365 SET_BIT(adev->set_mask, SET_TEMPLATES);
3368 switch (adev->mode) {
3369 case ACX_MODE_0_ADHOC:
3370 case ACX_MODE_2_STA:
3371 start_scan = 1;
3375 /* Apply settings */
3378 if (adev->get_mask & GETSET_STATION_ID) {
3379 u8 stationID[4 + ACX1xx_REG_DOT11_STATION_ID_LEN];
3380 const u8 *paddr;
3382 acx_s_query(adev, &stationID, ACX1xx_REG_DOT11_STATION_ID);
3383 paddr = &stationID[4];
3384 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3385 for (i = 0; i < ETH_ALEN; i++) {
3386 /* we copy the MAC address (reversed in
3387 * the card) to the netdevice's MAC
3388 * address, and on ifup it will be
3389 * copied into iwadev->dev_addr */
3390 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3392 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3393 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3396 if (adev->get_mask & GETSET_SENSITIVITY) {
3397 if ((RADIO_RFMD_11 == adev->radio_type)
3398 || (RADIO_MAXIM_0D == adev->radio_type)
3399 || (RADIO_RALINK_15 == adev->radio_type)) {
3400 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3401 } else {
3402 acx_log(LOG_WARNING, L_INIT,
3403 "don't know how to get sensitivity "
3404 "for radio type 0x%02X\n", adev->radio_type);
3405 adev->sensitivity = 0;
3407 acx_log(LOG_DEBUG, L_INIT, "got sensitivity value %u\n",
3408 adev->sensitivity);
3410 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3413 if (adev->get_mask & GETSET_ANTENNA) {
3414 u8 antenna[4 + ACX1xx_REG_DOT11_CURRENT_ANTENNA_LEN];
3416 memset(antenna, 0, sizeof(antenna));
3417 acx_s_query(adev, antenna,
3418 ACX1xx_REG_DOT11_CURRENT_ANTENNA);
3419 adev->antenna = antenna[4];
3420 acx_log(LOG_INFO, L_INIT, "got antenna value 0x%02X\n",
3421 adev->antenna);
3422 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3425 if (adev->get_mask & GETSET_ED_THRESH) {
3426 if (IS_ACX100(adev)) {
3427 u8 ed_threshold[4 + ACX100_REG_DOT11_ED_THRESHOLD_LEN];
3429 memset(ed_threshold, 0, sizeof(ed_threshold));
3430 acx_s_query(adev, ed_threshold,
3431 ACX100_REG_DOT11_ED_THRESHOLD);
3432 adev->ed_threshold = ed_threshold[4];
3433 } else {
3434 acx_log(LOG_WARNING, L_INIT,
3435 "acx111 doesn't support ED\n");
3436 adev->ed_threshold = 0;
3438 acx_log(LOG_INFO, L_INIT,
3439 "got Energy Detect (ED) threshold %u\n",
3440 adev->ed_threshold);
3441 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3444 if (adev->get_mask & GETSET_CCA) {
3445 if (IS_ACX100(adev)) {
3446 u8 cca[4 + ACX1xx_REG_DOT11_CURRENT_CCA_MODE_LEN];
3448 memset(cca, 0, sizeof(adev->cca));
3449 acx_s_query(adev, cca,
3450 ACX1xx_REG_DOT11_CURRENT_CCA_MODE);
3451 adev->cca = cca[4];
3452 } else {
3453 acx_log(LOG_WARNING, L_INIT,
3454 "acx111 doesn't support CCA\n");
3455 adev->cca = 0;
3457 acx_log(LOG_INFO, L_INIT,
3458 "got Channel Clear Assessment (CCA) value %u\n",
3459 adev->cca);
3460 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3463 if (adev->get_mask & GETSET_REG_DOMAIN) {
3464 acx_ie_generic_t dom;
3466 acx_s_query(adev, &dom,
3467 ACX1xx_REG_DOT11_CURRENT_REG_DOMAIN);
3468 adev->reg_dom_id = dom.m.bytes[0];
3469 acx_s_set_sane_reg_domain(adev, 0);
3470 acx_log(LOG_INFO, L_INIT,
3471 "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3472 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3475 if (adev->set_mask & GETSET_STATION_ID) {
3476 u8 stationID[4 + ACX1xx_REG_DOT11_STATION_ID_LEN];
3477 u8 *paddr;
3479 paddr = &stationID[4];
3480 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3481 for (i = 0; i < ETH_ALEN; i++) {
3482 /* copy the MAC address we obtained when we noticed
3483 * that the ethernet iface's MAC changed
3484 * to the card (reversed in
3485 * the card!) */
3486 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3488 acx_s_configure(adev, &stationID, ACX1xx_REG_DOT11_STATION_ID);
3489 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3492 if (adev->set_mask & SET_STA_LIST) {
3493 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3495 if (adev->set_mask & SET_RATE_FALLBACK) {
3496 u8 rate[4 + ACX1xx_REG_RATE_FALLBACK_LEN];
3498 /* configure to not do fallbacks when not in auto rate mode */
3499 rate[4] =
3500 (adev->
3501 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3502 acx_log(LOG_DEBUG, L_INIT,
3503 "updating Tx fallback to %u retries\n", rate[4]);
3504 acx_s_configure(adev, &rate, ACX1xx_REG_RATE_FALLBACK);
3505 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3507 if (adev->set_mask & GETSET_TXPOWER) {
3508 acx_log(LOG_DEBUG, L_INIT, "updating transmit power: %u dBm\n",
3509 adev->tx_level_dbm);
3510 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3511 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3514 if (adev->set_mask & GETSET_SENSITIVITY) {
3515 acx_log(LOG_DEBUG, L_INIT, "updating sensitivity value: %u\n",
3516 adev->sensitivity);
3517 switch (adev->radio_type) {
3518 case RADIO_RFMD_11:
3519 case RADIO_MAXIM_0D:
3520 case RADIO_RALINK_15:
3521 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3522 break;
3523 case RADIO_RADIA_16:
3524 case RADIO_UNKNOWN_17:
3525 acx111_s_sens_radio_16_17(adev);
3526 break;
3527 default:
3528 acx_log(LOG_WARNING, L_INIT,
3529 "don't know how to modify sensitivity "
3530 "for radio type 0x%02X\n", adev->radio_type);
3532 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3535 if (adev->set_mask & GETSET_ANTENNA) {
3536 /* antenna */
3537 u8 antenna[4 + ACX1xx_REG_DOT11_CURRENT_ANTENNA_LEN];
3539 memset(antenna, 0, sizeof(antenna));
3540 antenna[4] = adev->antenna;
3541 acx_log(LOG_DEBUG, L_INIT, "updating antenna value: 0x%02X\n",
3542 adev->antenna);
3543 acx_s_configure(adev, &antenna,
3544 ACX1xx_REG_DOT11_CURRENT_ANTENNA);
3545 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3548 if (adev->set_mask & GETSET_ED_THRESH) {
3549 /* ed_threshold */
3550 acx_log(LOG_INFO, L_INIT,
3551 "updating Energy Detect (ED) threshold: %u\n",
3552 adev->ed_threshold);
3553 if (IS_ACX100(adev)) {
3554 u8 ed_threshold[4 + ACX100_REG_DOT11_ED_THRESHOLD_LEN];
3556 memset(ed_threshold, 0, sizeof(ed_threshold));
3557 ed_threshold[4] = adev->ed_threshold;
3558 acx_s_configure(adev, &ed_threshold,
3559 ACX100_REG_DOT11_ED_THRESHOLD);
3560 } else
3561 acx_log(LOG_WARNING, L_INIT,
3562 "acx111 doesn't support ED!\n");
3563 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3566 if (adev->set_mask & GETSET_CCA) {
3567 /* CCA value */
3568 acx_log(LOG_DEBUG, L_INIT,
3569 "updating Channel Clear Assessment (CCA) value: "
3570 "0x%02X\n", adev->cca);
3571 if (IS_ACX100(adev)) {
3572 u8 cca[4 + ACX1xx_REG_DOT11_CURRENT_CCA_MODE_LEN];
3574 memset(cca, 0, sizeof(cca));
3575 cca[4] = adev->cca;
3576 acx_s_configure(adev, &cca,
3577 ACX1xx_REG_DOT11_CURRENT_CCA_MODE);
3578 } else
3579 acx_log(LOG_WARNING, L_INIT,
3580 "acx111 doesn't support CCA!\n");
3581 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3584 if (adev->set_mask & GETSET_LED_POWER) {
3585 /* Enable Tx */
3586 acx_log(LOG_INFO, L_INIT,
3587 "updating power LED status: %u\n", adev->led_power);
3589 acx_lock(adev, flags); /* acxpci_l_power_led expects that the lock is already taken! */
3590 if (IS_PCI(adev))
3591 acxpci_l_power_led(adev, adev->led_power);
3592 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3593 acx_unlock(adev, flags);
3596 if (adev->set_mask & GETSET_POWER_80211) {
3597 #if POWER_SAVE_80211
3598 acx_s_update_80211_powersave_mode(adev);
3599 #endif
3600 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3603 if (adev->set_mask & GETSET_CHANNEL) {
3604 /* channel */
3605 acx_log(LOG_INFO, L_INIT, "updating channel to: %u\n",
3606 adev->channel);
3607 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3610 if (adev->set_mask & GETSET_TX) {
3611 /* set Tx */
3612 acx_log(LOG_INFO, L_INIT, "updating: %s Tx\n",
3613 adev->tx_disabled ? "disable" : "enable");
3614 if (adev->tx_disabled)
3615 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3616 else {
3617 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3618 &adev->channel, 1);
3619 FIXME();
3620 /* This needs to be keyed on WEP? */
3621 /* acx111_s_feature_on(adev, 0,
3622 FEATURE2_NO_TXCRYPT |
3623 FEATURE2_SNIFFER); */
3624 acx_wake_queue(adev->ieee, NULL);
3626 CLEAR_BIT(adev->set_mask, GETSET_TX);
3629 if (adev->set_mask & GETSET_RX) {
3630 /* Enable Rx */
3631 acx_log(LOG_INFO, L_INIT,
3632 "updating: enable Rx on channel: %u\n", adev->channel);
3633 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3634 CLEAR_BIT(adev->set_mask, GETSET_RX);
3637 if (adev->set_mask & GETSET_RETRY) {
3638 u8 short_retry[4 + ACX1xx_REG_DOT11_SHORT_RETRY_LIMIT_LEN];
3639 u8 long_retry[4 + ACX1xx_REG_DOT11_LONG_RETRY_LIMIT_LEN];
3641 acx_log(LOG_INFO, L_INIT,
3642 "updating short retry limit: %u, "
3643 "long retry limit: %u\n",
3644 adev->short_retry, adev->long_retry);
3645 short_retry[0x4] = adev->short_retry;
3646 long_retry[0x4] = adev->long_retry;
3647 acx_s_configure(adev, &short_retry,
3648 ACX1xx_REG_DOT11_SHORT_RETRY_LIMIT);
3649 acx_s_configure(adev, &long_retry,
3650 ACX1xx_REG_DOT11_LONG_RETRY_LIMIT);
3651 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3654 if (adev->set_mask & SET_MSDU_LIFETIME) {
3655 u8 xmt_msdu_lifetime[4 +
3656 ACX1xx_REG_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3658 acx_log(LOG_DEBUG, L_INIT, "updating tx MSDU lifetime: %u\n",
3659 adev->msdu_lifetime);
3660 *(u32 *) & xmt_msdu_lifetime[4] =
3661 cpu_to_le32((u32) adev->msdu_lifetime);
3662 acx_s_configure(adev, &xmt_msdu_lifetime,
3663 ACX1xx_REG_DOT11_MAX_XMIT_MSDU_LIFETIME);
3664 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3667 if (adev->set_mask & GETSET_REG_DOMAIN) {
3668 acx_log(LOG_INFO, L_INIT,
3669 "updating regulatory domain: 0x%02X\n",
3670 adev->reg_dom_id);
3671 acx_s_set_sane_reg_domain(adev, 1);
3672 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3674 if (adev->set_mask & GETSET_MODE ) {
3675 acx111_s_feature_on(adev, 0,
3676 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3677 switch (adev->mode) {
3678 case ACX_MODE_3_AP:
3679 adev->aid = 0;
3680 //acx111_s_feature_off(adev, 0,
3681 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3682 MAC_COPY(adev->bssid, adev->dev_addr);
3683 acx_s_cmd_join_bssid(adev, adev->dev_addr);
3684 break;
3685 case ACX_MODE_MONITOR:
3686 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3687 break;
3688 case ACX_MODE_0_ADHOC:
3689 case ACX_MODE_2_STA:
3690 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3691 break;
3692 default:
3693 break;
3695 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3697 if (adev->set_mask & SET_TEMPLATES) {
3698 switch (adev->mode)
3700 case ACX_MODE_3_AP:
3701 acx_s_set_tim_template(adev);
3702 break;
3703 default:
3704 break;
3706 if (adev->beacon_cache)
3708 acx_s_set_beacon_template(adev, adev->beacon_cache);
3709 dev_kfree_skb(adev->beacon_cache);
3710 adev->beacon_cache = NULL;
3712 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3715 if (adev->set_mask & SET_RXCONFIG) {
3716 acx_s_initialize_rx_config(adev);
3717 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3720 if (adev->set_mask & GETSET_RESCAN) {
3721 /* switch (adev->mode) {
3722 case ACX_MODE_0_ADHOC:
3723 case ACX_MODE_2_STA:
3724 start_scan = 1;
3725 break;
3727 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3730 if (adev->set_mask & GETSET_WEP) {
3731 /* encode */
3733 ie_dot11WEPDefaultKeyID_t dkey;
3734 #ifdef DEBUG_WEP
3735 struct {
3736 u16 type;
3737 u16 len;
3738 u8 val;
3739 } __attribute__ ((packed)) keyindic;
3740 #endif
3741 acx_log(LOG_DEBUG, L_INIT, "updating WEP key settings\n");
3743 acx_s_set_wepkey(adev);
3744 if (adev->wep_enabled) {
3745 dkey.KeyID = adev->wep_current_index;
3746 acx_log(LOG_DEBUG, L_INIT,
3747 "setting WEP key %u as default\n",
3748 dkey.KeyID);
3749 acx_s_configure(adev, &dkey,
3750 ACX1xx_REG_DOT11_WEP_DEFAULT_KEY_SET);
3751 #ifdef DEBUG_WEP
3752 keyindic.val = 3;
3753 acx_s_configure(adev, &keyindic, ACX111_REG_KEY_CHOOSE);
3754 #endif
3757 // start_scan = 1;
3758 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3761 if (adev->set_mask & SET_WEP_OPTIONS) {
3762 acx100_ie_wep_options_t options;
3764 if (IS_ACX111(adev)) {
3765 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
3766 "setting WEP Options for acx111 "
3767 "is not supported\n");
3768 } else {
3769 acx_log(LOG_DEBUG, L_INIT, "setting WEP Options\n");
3771 /* let's choose maximum setting: 4 default keys,
3772 * plus 10 other keys: */
3773 options.NumKeys =
3774 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3775 /* don't decrypt default key only,
3776 * don't override decryption: */
3777 options.WEPOption = 0;
3778 if (adev->mode == ACX_MODE_3_AP) {
3779 /* don't decrypt default key only,
3780 * override decryption mechanism: */
3781 options.WEPOption = 2;
3784 acx_s_configure(adev, &options, ACX100_REG_WEP_OPTIONS);
3786 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3790 /* debug, rate, and nick don't need any handling */
3791 /* what about sniffing mode?? */
3793 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3794 adev->get_mask, adev->set_mask);
3796 /* end: */
3797 FN_EXIT0;
3800 #if 0
3801 /***********************************************************************
3802 ** acx_e_after_interrupt_task
3804 static int acx_s_recalib_radio(acx_device_t * adev)
3806 if (IS_ACX111(adev)) {
3807 acx111_cmd_radiocalib_t cal;
3809 /* automatic recalibration, choose all methods: */
3810 cal.methods = cpu_to_le32(0x8000000f);
3811 /* automatic recalibration every 60 seconds (value in TUs)
3812 * I wonder what the firmware default here is? */
3813 cal.interval = cpu_to_le32(58594);
3814 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3815 &cal, sizeof(cal),
3816 CMD_TIMEOUT_MS(100));
3817 } else {
3818 /* On ACX100, we need to recalibrate the radio
3819 * by issuing a GETSET_TX|GETSET_RX */
3820 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3821 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3822 (OK ==
3823 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3824 &adev->channel, 1))
3825 && (OK ==
3826 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3827 &adev->channel, 1)))
3828 return OK;
3829 return NOT_OK;
3832 #endif // if 0
3833 #if 0
3834 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3836 int res;
3838 /* this helps with ACX100 at least;
3839 * hopefully ACX111 also does a
3840 * recalibration here */
3842 /* clear flag beforehand, since we want to make sure
3843 * it's cleared; then only set it again on specific circumstances */
3844 CLEAR_BIT(adev->after_interrupt_jobs, ACX_TASKLET_CMD_RADIO_RECALIB);
3846 /* better wait a bit between recalibrations to
3847 * prevent overheating due to torturing the card
3848 * into working too long despite high temperature
3849 * (just a safety measure) */
3850 if (adev->recalib_time_last_success
3851 && time_before(jiffies, adev->recalib_time_last_success
3852 + RECALIB_PAUSE * 60 * HZ)) {
3853 if (adev->recalib_msg_ratelimit <= 4) {
3854 printk("%s: less than " STRING(RECALIB_PAUSE)
3855 " minutes since last radio recalibration, "
3856 "not recalibrating (maybe card is too hot?)\n",
3857 wiphy_name(adev->ieee->wiphy));
3858 adev->recalib_msg_ratelimit++;
3859 if (adev->recalib_msg_ratelimit == 5)
3860 printk("disabling above message until next recalib\n");
3862 return;
3865 adev->recalib_msg_ratelimit = 0;
3867 /* note that commands sometimes fail (card busy),
3868 * so only clear flag if we were fully successful */
3869 res = acx_s_recalib_radio(adev);
3870 if (res == OK) {
3871 printk("%s: successfully recalibrated radio\n",
3872 wiphy_name(adev->ieee->wiphy));
3873 adev->recalib_time_last_success = jiffies;
3874 adev->recalib_failure_count = 0;
3875 } else {
3876 /* failed: resubmit, but only limited
3877 * amount of times within some time range
3878 * to prevent endless loop */
3880 adev->recalib_time_last_success = 0; /* we failed */
3882 /* if some time passed between last
3883 * attempts, then reset failure retry counter
3884 * to be able to do next recalib attempt */
3885 if (time_after
3886 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3887 adev->recalib_failure_count = 0;
3889 if (adev->recalib_failure_count < 5) {
3890 /* increment inside only, for speedup of outside path */
3891 adev->recalib_failure_count++;
3892 adev->recalib_time_last_attempt = jiffies;
3893 acx_schedule_task(adev,
3894 ACX_TASKLET_CMD_RADIO_RECALIB);
3898 #endif // if 0
3900 void acx_e_after_interrupt_task(struct work_struct *work)
3902 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
3903 unsigned long flags;
3905 FN_ENTER;
3907 acx_lock(adev, flags);
3909 if (!adev->after_interrupt_jobs || !adev->initialized)
3910 goto end; /* no jobs to do */
3912 /* we see lotsa tx errors */
3913 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_RADIO_RECALIB) {
3914 acx_log_ratelimited(LOG_WARNING, L_ANY,
3915 "too many TX errors??\n");
3916 // acx_s_after_interrupt_recalib(adev);
3919 /* a poor interrupt code wanted to do update_card_settings() */
3920 if (adev->after_interrupt_jobs & ACX_TASKLET_UPDATE_CARD_CFG) {
3921 if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
3922 acx_unlock(adev, flags);
3923 acx_s_update_card_settings(adev);
3924 acx_lock(adev, flags);
3926 CLEAR_BIT(adev->after_interrupt_jobs,
3927 ACX_TASKLET_UPDATE_CARD_CFG);
3930 /* 1) we detected that no Scan_Complete IRQ came from fw, or
3931 ** 2) we found too many STAs */
3932 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_STOP_SCAN) {
3933 acx_log(LOG_DEBUG, L_IRQ, "sending a stop scan cmd...\n");
3934 acx_unlock(adev, flags);
3935 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
3936 acx_lock(adev, flags);
3937 /* HACK: set the IRQ bit, since we won't get a
3938 * scan complete IRQ any more on ACX111 (works on ACX100!),
3939 * since _we_, not a fw, have stopped the scan */
3940 SET_BIT(adev->irq_status, ACX_IRQ_SCAN_COMPLETE);
3941 CLEAR_BIT(adev->after_interrupt_jobs,
3942 ACX_TASKLET_CMD_STOP_SCAN);
3945 /* either fw sent Scan_Complete or we detected that
3946 ** no Scan_Complete IRQ came from fw. Finish scanning,
3947 ** pick join partner if any */
3948 if (adev->after_interrupt_jobs & ACX_TASKLET_COMPLETE_SCAN) {
3949 /* + scan kills current join status - restore it
3950 ** (do we need it for STA?) */
3951 /* + does it happen only with active scans?
3952 ** active and passive scans? ALL scans including
3953 ** background one? */
3954 /* + was not verified that everything is restored
3955 ** (but at least we start to emit beacons again) */
3956 CLEAR_BIT(adev->after_interrupt_jobs,
3957 ACX_TASKLET_COMPLETE_SCAN);
3960 /* STA auth or assoc timed out, start over again */
3962 if (adev->after_interrupt_jobs & ACX_TASKLET_RESTART_SCAN) {
3963 acx_log(LOG_DEBUG, L_IRQ, "sending a start_scan cmd...\n");
3964 CLEAR_BIT(adev->after_interrupt_jobs,
3965 ACX_TASKLET_RESTART_SCAN);
3968 /* whee, we got positive assoc response! 8) */
3969 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_ASSOCIATE) {
3970 CLEAR_BIT(adev->after_interrupt_jobs,
3971 ACX_TASKLET_CMD_ASSOCIATE);
3973 end:
3974 if(adev->after_interrupt_jobs)
3976 acx_log(LOG_DEBUG, L_ANY, "Jobs still to be run: %x\n",
3977 adev->after_interrupt_jobs);
3978 adev->after_interrupt_jobs = 0;
3980 acx_unlock(adev, flags);
3981 // acx_sem_unlock(adev);
3982 FN_EXIT0;
3986 /***********************************************************************
3987 ** acx_schedule_task
3989 ** Schedule the call of the after_interrupt method after leaving
3990 ** the interrupt context.
3992 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
3994 if (!adev->after_interrupt_jobs)
3996 SET_BIT(adev->after_interrupt_jobs, set_flag);
3997 schedule_work(&adev->after_interrupt_task);
4002 /***********************************************************************
4004 void acx_init_task_scheduler(acx_device_t * adev)
4006 /* configure task scheduler */
4007 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4011 /***********************************************************************
4012 ** acx_s_start
4014 void acx_s_start(acx_device_t * adev)
4016 FN_ENTER;
4019 * Ok, now we do everything that can possibly be done with ioctl
4020 * calls to make sure that when it was called before the card
4021 * was up we get the changes asked for
4024 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4025 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4026 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4027 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4029 acx_log(LOG_INFO, L_INIT,
4030 "updating initial settings on iface activation\n");
4031 acx_s_update_card_settings(adev);
4033 FN_EXIT0;
4037 /***********************************************************************
4038 ** acx_update_capabilities
4039 *//*
4040 void acx_update_capabilities(acx_device_t * adev)
4042 u16 cap = 0;
4044 switch (adev->mode) {
4045 case ACX_MODE_3_AP:
4046 SET_BIT(cap, WF_MGMT_CAP_ESS);
4047 break;
4048 case ACX_MODE_0_ADHOC:
4049 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4050 break;
4051 */ /* other types of stations do not emit beacons */
4052 /* }
4054 if (adev->wep_restricted) {
4055 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4057 if (adev->cfgopt_dot11ShortPreambleOption) {
4058 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4060 if (adev->cfgopt_dot11PBCCOption) {
4061 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4063 if (adev->cfgopt_dot11ChannelAgility) {
4064 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4066 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4067 adev->capabilities, cap);
4068 adev->capabilities = cap;
4072 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4075 static void acx_s_select_opmode(acx_device_t * adev)
4077 int changed = 0;
4078 FN_ENTER;
4080 if (adev->interface.operating) {
4081 switch (adev->interface.type) {
4082 case IEEE80211_IF_TYPE_AP:
4083 if (adev->mode != ACX_MODE_3_AP)
4085 adev->mode = ACX_MODE_3_AP;
4086 changed = 1;
4088 break;
4089 case IEEE80211_IF_TYPE_IBSS:
4090 if (adev->mode != ACX_MODE_0_ADHOC)
4092 adev->mode = ACX_MODE_0_ADHOC;
4093 changed = 1;
4095 break;
4096 case IEEE80211_IF_TYPE_STA:
4097 if (adev->mode != ACX_MODE_2_STA)
4099 adev->mode = ACX_MODE_2_STA;
4100 changed = 1;
4102 break;
4103 case IEEE80211_IF_TYPE_WDS:
4104 default:
4105 if (adev->mode != ACX_MODE_OFF)
4107 adev->mode = ACX_MODE_OFF;
4108 changed = 1;
4110 break;
4112 } else {
4113 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4115 if (adev->mode != ACX_MODE_MONITOR)
4117 adev->mode = ACX_MODE_MONITOR;
4118 changed = 1;
4121 else
4123 if (adev->mode != ACX_MODE_OFF)
4125 adev->mode = ACX_MODE_OFF;
4126 changed = 1;
4130 if (changed)
4132 SET_BIT(adev->set_mask, GETSET_MODE);
4133 acx_s_update_card_settings(adev);
4134 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4137 FN_EXIT0;
4141 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4145 int acx_add_interface(struct ieee80211_hw *ieee,
4146 struct ieee80211_if_init_conf *conf)
4148 acx_device_t *adev = ieee2adev(ieee);
4149 unsigned long flags;
4150 int err = -EOPNOTSUPP;
4152 DECLARE_MAC_BUF(mac);
4154 FN_ENTER;
4155 acx_lock(adev, flags);
4157 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4158 adev->interface.monitor++;
4159 } else {
4160 if (adev->interface.operating)
4161 goto out_unlock;
4162 adev->interface.operating = 1;
4163 adev->interface.type = conf->type;
4165 // adev->mode = conf->type;
4167 acx_unlock(adev, flags);
4169 if (adev->initialized)
4170 acx_s_select_opmode(adev);
4172 acx_lock(adev, flags);
4174 err = 0;
4176 acx_log(LOG_INFO, L_ANY, "Virtual interface added "
4177 "(type: 0x%08X, MAC: %s)\n",
4178 conf->type,
4179 print_mac(mac, conf->mac_addr));
4181 out_unlock:
4182 acx_unlock(adev, flags);
4184 FN_EXIT0;
4185 return err;
4188 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4192 void acx_remove_interface(struct ieee80211_hw *hw,
4193 struct ieee80211_if_init_conf *conf)
4195 acx_device_t *adev = ieee2adev(hw);
4197 DECLARE_MAC_BUF(mac);
4199 FN_ENTER;
4201 acx_sem_lock(adev);
4202 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4203 adev->interface.monitor--;
4204 // assert(bcm->interface.monitor >= 0);
4205 } else {
4206 adev->interface.operating = 0;
4209 acx_log(LOG_INFO, L_ANY, "Removing interface: %d %d\n",
4210 adev->interface.operating, conf->type);
4211 acx_sem_unlock(adev);
4213 if (adev->initialized)
4214 acx_s_select_opmode(adev);
4215 flush_scheduled_work();
4217 acx_log(LOG_INFO, L_ANY, "Virtual interface removed "
4218 "(type: 0x%08X, MAC: %s)\n",
4219 conf->type, print_mac(mac, conf->mac_addr));
4221 FN_EXIT0;
4224 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4228 int acx_net_reset(struct ieee80211_hw *ieee)
4230 acx_device_t *adev = ieee2adev(ieee);
4231 FN_ENTER;
4232 if (IS_PCI(adev))
4233 acxpci_s_reset_dev(adev);
4234 else
4235 TODO();
4237 FN_EXIT0;
4238 return 0;
4242 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4245 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4247 int result;
4249 FN_ENTER;
4251 acx_sem_lock(adev);
4252 adev->rx_status.channel = channel;
4253 adev->rx_status.freq = freq;
4255 adev->channel = channel;
4256 /* hmm, the following code part is strange, but this is how
4257 * it was being done before... */
4258 acx_log(LOG_DEBUG, L_IOCTL, "Changing to channel %d\n", channel);
4259 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4260 result = -EINPROGRESS; /* need to call commit handler */
4262 acx_sem_unlock(adev);
4263 FN_EXIT1(result);
4264 return result;
4268 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4271 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4273 acx_device_t *adev = ieee2adev(hw);
4274 unsigned long flags;
4276 FN_ENTER;
4278 acx_lock(adev, flags);
4279 //FIXME();
4280 if (!adev->initialized) {
4281 acx_unlock(adev, flags);
4282 return 0;
4284 if (conf->beacon_int != adev->beacon_interval)
4285 adev->beacon_interval = conf->beacon_int;
4286 if (conf->channel != adev->channel) {
4287 acx_unlock(adev, flags);
4288 acx_selectchannel(adev, conf->channel,conf->freq);
4289 acx_lock(adev, flags);
4290 /* acx_schedule_task(adev,
4291 ACX_TASKLET_UPDATE_CARD_CFG
4292 */ /*+ ACX_TASKLET_RESTART_SCAN */ /*);*/
4295 if (conf->short_slot_time != adev->short_slot) {
4296 // assert(phy->type == BCM43xx_PHYTYPE_G);
4297 if (conf->short_slot_time)
4298 acx_short_slot_timing_enable(adev);
4299 else
4300 acx_short_slot_timing_disable(adev);
4301 acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4304 adev->tx_disabled = !conf->radio_enabled;
4305 /* if (conf->power_level != 0){
4306 adev->tx_level_dbm = conf->power_level;
4307 acx_s_set_tx_level(adev, adev->tx_level_dbm);
4308 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4309 //acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4312 //FIXME: This does not seem to wake up:
4313 #if 0
4314 if (conf->power_level == 0) {
4315 if (radio->enabled)
4316 bcm43xx_radio_turn_off(bcm);
4317 } else {
4318 if (!radio->enabled)
4319 bcm43xx_radio_turn_on(bcm);
4321 #endif
4323 //TODO: phymode
4324 //TODO: antennas
4325 if (adev->set_mask > 0) {
4326 acx_unlock(adev, flags);
4327 acx_s_update_card_settings(adev);
4328 acx_lock(adev, flags);
4330 acx_unlock(adev, flags);
4332 FN_EXIT0;
4333 return 0;
4337 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4341 extern int acx_config_interface(struct ieee80211_hw* ieee,
4342 struct ieee80211_vif *vif,
4343 struct ieee80211_if_conf *conf)
4345 acx_device_t *adev = ieee2adev(ieee);
4346 unsigned long flags;
4347 int err = -ENODEV;
4348 FN_ENTER;
4349 if (!adev->interface.operating)
4350 goto err_out;
4352 if (adev->initialized)
4353 acx_s_select_opmode(adev);
4355 acx_lock(adev, flags);
4357 if ((conf->type == IEEE80211_IF_TYPE_AP)
4358 && (adev->vif == vif)) {
4359 if ((conf->ssid_len > 0) && conf->ssid)
4361 adev->essid_len = conf->ssid_len;
4362 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4363 SET_BIT(adev->set_mask, SET_TEMPLATES);
4366 if (conf->beacon != 0)
4368 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4369 adev->beacon_cache = conf->beacon;
4370 SET_BIT(adev->set_mask, SET_TEMPLATES);
4373 acx_unlock(adev, flags);
4375 if (adev->set_mask != 0)
4376 acx_s_update_card_settings(adev);
4377 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4378 err = 0;
4379 err_out:
4380 FN_EXIT1(err);
4381 return err;
4385 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4389 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4390 struct ieee80211_tx_queue_stats *stats)
4392 // acx_device_t *adev = ndev2adev(net_dev);
4393 struct ieee80211_tx_queue_stats_data *data;
4394 int err = -ENODEV;
4396 FN_ENTER;
4398 // acx_lock(adev, flags);
4399 data = &(stats->data[0]);
4400 data->len = 0;
4401 data->limit = TX_CNT;
4402 data->count = 0;
4403 // acx_unlock(adev, flags);
4405 FN_EXIT0;
4406 return err;
4409 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4413 int acx_net_conf_tx(struct ieee80211_hw *hw,
4414 int queue, const struct ieee80211_tx_queue_params *params)
4416 FN_ENTER;
4417 // TODO();
4418 FN_EXIT0;
4419 return 0;
4422 static void keymac_write(acx_device_t * adev, u16 index, const u32 * addr)
4424 /* for keys 0-3 there is no associated mac address */
4425 if (index < 4)
4426 return;
4428 index -= 4;
4429 if (1) {
4430 TODO();
4432 bcm43xx_shm_write32(bcm,
4433 BCM43xx_SHM_HWMAC,
4434 index * 2,
4435 cpu_to_be32(*addr));
4436 bcm43xx_shm_write16(bcm,
4437 BCM43xx_SHM_HWMAC,
4438 (index * 2) + 1,
4439 cpu_to_be16(*((u16 *)(addr + 1))));
4441 } else {
4442 if (index < 8) {
4443 TODO(); /* Put them in the macaddress filter */
4444 } else {
4445 TODO();
4446 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4447 Keep in mind to update the count of keymacs in 0x003 */
4453 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4457 int acx_clear_keys(acx_device_t * adev)
4459 static const u32 zero_mac[2] = { 0 };
4460 unsigned int i, j, nr_keys = 54;
4461 u16 offset;
4463 /* FixMe:Check for Number of Keys available */
4465 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4467 for (i = 0; i < nr_keys; i++) {
4468 adev->key[i].enabled = 0;
4469 /* returns for i < 4 immediately */
4470 keymac_write(adev, i, zero_mac);
4472 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4473 0x100 + (i * 2), 0x0000);
4475 for (j = 0; j < 8; j++) {
4476 offset =
4477 adev->security_offset + (j * 4) +
4478 (i * ACX_SEC_KEYSIZE);
4480 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4481 offset, 0x0000);
4485 return 1;
4489 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4493 int acx_key_write(acx_device_t * adev,
4494 u16 index, u8 algorithm,
4495 const struct ieee80211_key_conf *key, const u8 * mac_addr)
4497 // struct iw_point *dwrq = &wrqu->encoding;
4498 int result;
4500 FN_ENTER;
4502 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4503 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4505 // acx_sem_lock(adev);
4507 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4508 if (key->keylen > 0) {
4509 /* if index is 0 or invalid, use default key */
4510 if (index > 3)
4511 index = (int)adev->wep_current_index;
4512 if ((algorithm == ACX_SEC_ALGO_WEP) ||
4513 (algorithm == ACX_SEC_ALGO_WEP104)) {
4514 switch(key->keylen) {
4515 case 40 / 8:
4516 /* WEP 40-bit =
4517 40-bit entered key + 24 bit IV = 64-bit */
4518 adev->wep_keys[index].size = 13;
4519 break;
4520 case 104 / 8:
4521 /* WEP 104-bit =
4522 104-bit entered key + 24-bit IV = 128-bit */
4523 adev->wep_keys[index].size = 29;
4524 break;
4525 case 128 / 8:
4526 /* WEP 128-bit =
4527 128-bit entered key + 24 bit IV = 152-bit */
4528 adev->wep_keys[index].size = 16;
4529 break;
4530 default:
4531 adev->wep_keys[index].size = 0;
4532 return -EINVAL; /* shouldn't happen */
4535 memset(adev->wep_keys[index].key, 0,
4536 sizeof(adev->wep_keys[index].key));
4537 memcpy(adev->wep_keys[index].key, key, key->keylen);
4538 } else {
4539 /* set transmit key */
4540 if (index <= 3)
4541 adev->wep_current_index = index;
4542 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4543 /* complain if we were not just setting
4544 * the key mode */
4545 // result = -EINVAL;
4546 // goto end_unlock;
4547 // }
4551 adev->wep_enabled = (algorithm == ALG_WEP);
4553 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4555 if (algorithm & IW_ENCODE_OPEN) {
4556 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4557 adev->wep_restricted = 0;
4559 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4560 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4561 adev->wep_restricted = 1;
4564 // adev->auth_alg = algorithm;
4565 /* set flag to make sure the card WEP settings get updated */
4566 if (adev->wep_enabled) {
4567 SET_BIT(adev->set_mask, GETSET_WEP);
4568 acx_s_update_card_settings(adev);
4569 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4572 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4573 dwrq->length, extra, dwrq->flags);
4574 for (index = 0; index <= 3; index++) {
4575 if (adev->wep_keys[index].size) {
4576 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4577 adev->wep_keys[index].index,
4578 (int) adev->wep_keys[index].size,
4579 adev->wep_keys[index].key);
4583 result = -EINPROGRESS;
4584 // acx_sem_unlock(adev);
4586 FN_EXIT1(result);
4587 return result;
4593 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4597 int acx_net_set_key(struct ieee80211_hw *ieee,
4598 enum set_key_cmd cmd, const u8 *local_addr,
4599 const u8 * addr, struct ieee80211_key_conf *key)
4601 // return 0;
4602 struct acx_device *adev = ieee2adev(ieee);
4603 unsigned long flags;
4604 u8 algorithm;
4605 u16 index;
4606 int err = -EINVAL;
4607 FN_ENTER;
4608 // TODO();
4609 switch (key->alg) {
4610 default:
4611 /* case ALG_NONE:
4612 case ALG_NULL:
4613 algorithm = ACX_SEC_ALGO_NONE;
4614 break;
4615 */ case ALG_WEP:
4616 if (key->keylen == 5)
4617 algorithm = ACX_SEC_ALGO_WEP;
4618 else
4619 algorithm = ACX_SEC_ALGO_WEP104;
4620 break;
4621 case ALG_TKIP:
4622 algorithm = ACX_SEC_ALGO_TKIP;
4623 break;
4624 case ALG_CCMP:
4625 algorithm = ACX_SEC_ALGO_AES;
4626 break;
4629 index = (u8) (key->keyidx);
4630 if (index >= ARRAY_SIZE(adev->key))
4631 goto out;
4632 acx_lock(adev, flags);
4633 switch (cmd) {
4634 case SET_KEY:
4635 err = acx_key_write(adev, index, algorithm, key, addr);
4636 if (err)
4637 goto out_unlock;
4638 key->hw_key_idx = index;
4639 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4640 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4641 adev->default_key_idx = index;*/
4642 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4643 adev->key[index].enabled = 1;
4644 break;
4645 case DISABLE_KEY:
4646 adev->key[index].enabled = 0;
4647 err = 0;
4648 break;
4649 /* case ENABLE_COMPRESSION:
4650 case DISABLE_COMPRESSION:
4651 err = 0;
4652 break; */
4654 out_unlock:
4655 acx_unlock(adev, flags);
4656 out:
4657 FN_EXIT0;
4658 return err;
4663 /***********************************************************************
4664 ** Common function to parse ALL configoption struct formats
4665 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4666 ** FIXME: logging should be removed here and added to a /proc file instead
4668 ** Look into bcm43xx
4670 void
4671 acx_s_parse_configoption(acx_device_t * adev,
4672 const acx111_ie_configoption_t * pcfg)
4674 const u8 *pEle;
4675 int i;
4676 int is_acx111 = IS_ACX111(adev);
4678 acx_log_dump(LOG_DEBUG, L_REALLYVERBOSE, pcfg, sizeof(*pcfg),
4679 "configoption struct content:\n");
4681 if ((is_acx111 && (adev->eeprom_version == 5))
4682 || (!is_acx111 && (adev->eeprom_version == 4))
4683 || (!is_acx111 && (adev->eeprom_version == 5))) {
4684 /* these versions are known to be supported */
4685 } else {
4686 acx_log(LOG_WARNING, L_ANY,
4687 "unknown chip and EEPROM version combination "
4688 "(%s, v%d), "
4689 "don't know how to parse config options yet. "
4690 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4691 adev->eeprom_version);
4692 return;
4695 /* first custom-parse the first part which has chip-specific layout */
4697 pEle = (const u8 *)pcfg;
4699 pEle += 4; /* skip (type,len) header */
4701 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4702 pEle += sizeof(adev->cfgopt_NVSv);
4704 if (is_acx111) {
4705 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4706 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4708 adev->cfgopt_probe_delay = 200; /* good default value? */
4709 pEle += 2; /* FIXME: unknown, value 0x0001 */
4710 } else {
4711 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4712 pEle += sizeof(adev->cfgopt_MAC);
4714 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4715 pEle += sizeof(adev->cfgopt_probe_delay);
4716 if ((adev->cfgopt_probe_delay < 100)
4717 || (adev->cfgopt_probe_delay > 500)) {
4718 acx_log(LOG_WARNING, L_ANY,
4719 "strange probe_delay value %d, "
4720 "tweaking to 200\n", adev->cfgopt_probe_delay);
4721 adev->cfgopt_probe_delay = 200;
4725 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4726 pEle += sizeof(adev->cfgopt_eof_memory);
4728 acx_log(LOG_INFO, L_ANY, "NVS_vendor_offs:%04X probe_delay:%d "
4729 "eof_memory:%d\n",
4730 adev->cfgopt_NVS_vendor_offs, adev->cfgopt_probe_delay,
4731 adev->cfgopt_eof_memory);
4733 adev->cfgopt_dot11CCAModes = *pEle++;
4734 adev->cfgopt_dot11Diversity = *pEle++;
4735 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4736 adev->cfgopt_dot11PBCCOption = *pEle++;
4737 adev->cfgopt_dot11ChannelAgility = *pEle++;
4738 adev->cfgopt_dot11PhyType = *pEle++;
4739 adev->cfgopt_dot11TempType = *pEle++;
4740 acx_log(LOG_INFO, L_ANY,
4741 "CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4742 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4743 adev->cfgopt_dot11CCAModes, adev->cfgopt_dot11Diversity,
4744 adev->cfgopt_dot11ShortPreambleOption,
4745 adev->cfgopt_dot11PBCCOption, adev->cfgopt_dot11ChannelAgility,
4746 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4748 /* then use common parsing for next part which has common layout */
4750 pEle++; /* skip table_count (6) */
4752 adev->cfgopt_antennas.type = pEle[0];
4753 adev->cfgopt_antennas.len = pEle[1];
4756 * FIXME: a candidate for acx_log_dump(), but the code is bizarre
4758 acx_log(LOG_INFO, L_ANY, "AntennaID:%02X Len:%02X Data:",
4759 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4760 for (i = 0; i < pEle[1]; i++) {
4761 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4762 printk("%02X ", pEle[i + 2]);
4764 printk("\n");
4766 pEle += pEle[1] + 2;
4767 adev->cfgopt_power_levels.type = pEle[0];
4768 adev->cfgopt_power_levels.len = pEle[1];
4771 * FIXME: see above
4773 acx_log(LOG_INFO, L_ANY, "PowerLevelID:%02X Len:%02X Data:",
4774 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4775 for (i = 0; i < pEle[1]; i++) {
4776 adev->cfgopt_power_levels.list[i] =
4777 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4778 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4780 printk("\n");
4782 pEle += pEle[1] * 2 + 2;
4783 adev->cfgopt_data_rates.type = pEle[0];
4784 adev->cfgopt_data_rates.len = pEle[1];
4787 * FIXME again
4789 acx_log(LOG_INFO, L_ANY, "DataRatesID:%02X Len:%02X Data:",
4790 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4791 for (i = 0; i < pEle[1]; i++) {
4792 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4793 printk("%02X ", pEle[i + 2]);
4795 printk("\n");
4797 pEle += pEle[1] + 2;
4798 adev->cfgopt_domains.type = pEle[0];
4799 adev->cfgopt_domains.len = pEle[1];
4802 * And again
4804 acx_log(LOG_INFO, L_ANY, "DomainID:%02X Len:%02X Data:",
4805 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4806 for (i = 0; i < pEle[1]; i++) {
4807 adev->cfgopt_domains.list[i] = pEle[i + 2];
4808 printk("%02X ", pEle[i + 2]);
4810 printk("\n");
4812 pEle += pEle[1] + 2;
4813 adev->cfgopt_product_id.type = pEle[0];
4814 adev->cfgopt_product_id.len = pEle[1];
4815 for (i = 0; i < pEle[1]; i++) {
4816 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4818 acx_log(LOG_INFO, L_ANY, "ProductID:%02X Len:%02X Data:%.*s\n",
4819 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4820 adev->cfgopt_product_id.len,
4821 (char *)adev->cfgopt_product_id.list);
4823 pEle += pEle[1] + 2;
4824 adev->cfgopt_manufacturer.type = pEle[0];
4825 adev->cfgopt_manufacturer.len = pEle[1];
4826 for (i = 0; i < pEle[1]; i++) {
4827 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4829 acx_log(LOG_INFO, L_ANY, "ManufacturerID:%02X Len:%02X Data:%.*s\n",
4830 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4831 adev->cfgopt_manufacturer.len,
4832 (char *)adev->cfgopt_manufacturer.list);
4834 printk("EEPROM part:\n");
4835 for (i=0; i<58; i++) {
4836 printk("%02X =======> 0x%02X\n",
4837 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4843 /***********************************************************************
4844 ** Linux Kernel Specific
4846 static int __init acx_e_init_module(void)
4848 int r1, r2;
4850 acx_struct_size_check();
4852 acx_log(LOG_INFO, L_ANY, "this driver is still EXPERIMENTAL\n");
4853 acx_log(LOG_INFO, L_ANY, "acx: reading README file and/or "
4854 "Craig's HOWTO is recommended, "
4855 "visit http://acx100.sourceforge.net/wiki in case "
4856 "of further questions/discussion\n");
4858 #if defined(CONFIG_ACX_MAC80211_PCI)
4859 r1 = acxpci_e_init_module();
4860 #else
4861 r1 = -EINVAL;
4862 #endif
4863 #if defined(CONFIG_ACX_MAC80211_USB)
4864 r2 = acxusb_e_init_module();
4865 #else
4866 r2 = -EINVAL;
4867 #endif
4868 if (r2 && r1) /* both failed! */
4869 return r2 ? r2 : r1;
4870 /* return success if at least one succeeded */
4871 return 0;
4874 static void __exit acx_e_cleanup_module(void)
4876 #if defined(CONFIG_ACX_MAC80211_PCI)
4877 acxpci_e_cleanup_module();
4878 #endif
4879 #if defined(CONFIG_ACX_MAC80211_USB)
4880 acxusb_e_cleanup_module();
4881 #endif
4884 module_init(acx_e_init_module)
4885 module_exit(acx_e_cleanup_module)