Rename acxusb.h to acx_struct_usb.h
[acx-mac80211.git] / common.c
blob044cd7564679197d4f827be4559e2dba51f5ac62
1 /**** (legal) claimer in README
2 ** Copyright (C) 2003 ACX100 Open Source Project
3 */
5 #include <linux/version.h>
6 #include <linux/module.h>
7 #include <linux/kernel.h>
8 #include <linux/sched.h>
9 #include <linux/types.h>
10 #include <linux/slab.h>
11 #include <linux/delay.h>
12 #include <linux/proc_fs.h>
13 #include <linux/if_arp.h>
14 #include <linux/rtnetlink.h>
15 #include <linux/netdevice.h>
16 #include <linux/etherdevice.h>
17 #include <linux/wireless.h>
18 #include <linux/pm.h>
19 #include <linux/vmalloc.h>
20 #include <linux/firmware.h>
21 //#include <net/iw_handler.h>
22 #include <linux/ethtool.h>
23 //#include <linux/utsrelease.h>
25 #include "acx.h"
26 #include "acx_debug.h"
27 #include "acx_log.h"
28 #include "acx_irq.h"
31 /***********************************************************************
34 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf);
38 MODULE_LICENSE("GPL");
39 /* USB had this: MODULE_AUTHOR("Martin Wawro <martin.wawro AT uni-dortmund.de>"); */
40 MODULE_AUTHOR("ACX100 Open Source Driver development team");
41 MODULE_DESCRIPTION
42 ("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)");
44 MODULE_VERSION(ACX_RELEASE);
46 /***********************************************************************
48 /* Probably a number of acx's intermediate buffers for USB transfers,
49 ** not to be confused with number of descriptors in tx/rx rings
50 ** (which are not directly accessible to host in USB devices) */
51 #define USB_RX_CNT 10
52 #define USB_TX_CNT 10
55 /***********************************************************************
58 /* minutes to wait until next radio recalibration: */
59 #define RECALIB_PAUSE 5
61 /* Please keep acx_reg_domain_ids_len in sync... */
62 const u8 acx_reg_domain_ids[acx_reg_domain_ids_len] =
63 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 };
64 static const u16 reg_domain_channel_masks[acx_reg_domain_ids_len] =
65 { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc };
66 const char *const
67 acx_reg_domain_strings[] = {
68 /* 0 */ " 1-11 FCC (USA)",
69 /* 1 */ " 1-11 DOC/IC (Canada)",
70 /* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */
71 /* 2 */ " 1-13 ETSI (Europe)",
72 /* 3 */ "10-11 Spain",
73 /* 4 */ "10-13 France",
74 /* 5 */ " 14 MKK (Japan)",
75 /* 6 */ " 1-14 MKK1",
76 /* 7 */ " 3-9 Israel (not all firmware versions)",
77 NULL /* needs to remain as last entry */
82 /***********************************************************************
83 ** Debugging support
85 #ifdef PARANOID_LOCKING
86 static unsigned max_lock_time;
87 static unsigned max_sem_time;
89 /* Obvious or linux kernel specific derived code follows: */
91 void acx_lock_unhold()
93 max_lock_time = 0;
96 void acx_sem_unhold()
98 max_sem_time = 0;
101 static inline const char *sanitize_str(const char *s)
103 const char *t = strrchr(s, '/');
104 if (t)
105 return t + 1;
106 return s;
109 void acx_lock_debug(acx_device_t * adev, const char *where)
111 unsigned int count = 100 * 1000 * 1000;
112 where = sanitize_str(where);
113 while (--count) {
114 if (!spin_is_locked(&adev->spinlock))
115 break;
116 cpu_relax();
118 if (!count) {
119 printk(KERN_EMERG "LOCKUP: already taken at %s!\n",
120 adev->last_lock);
121 BUG();
123 adev->last_lock = where;
124 rdtscl(adev->lock_time);
127 void acx_unlock_debug(acx_device_t * adev, const char *where)
129 #ifdef SMP
130 if (!spin_is_locked(&adev->spinlock)) {
131 where = sanitize_str(where);
132 printk(KERN_EMERG "STRAY UNLOCK at %s!\n", where);
133 BUG();
135 #endif
136 if (acx_debug & L_LOCK) {
137 unsigned long diff;
138 rdtscl(diff);
139 diff -= adev->lock_time;
140 if (diff > max_lock_time) {
141 where = sanitize_str(where);
142 acx_log(LOG_DEBUG, L_LOCK, "max lock hold time "
143 "%ld CPU ticks from %s to %s\n", diff,
144 adev->last_lock, where);
145 max_lock_time = diff;
149 #endif /* PARANOID_LOCKING */
153 /***********************************************************************
154 ** Basically a mdelay/msleep with logging
156 void acx_s_mwait(int ms)
158 FN_ENTER;
159 mdelay(ms);
160 FN_EXIT0;
164 /***********************************************************************
165 ** acx_cmd_status_str
167 const char *acx_cmd_status_str(unsigned int state)
169 static const char *const cmd_error_strings[] = {
170 "Idle",
171 "Success",
172 "Unknown Command",
173 "Invalid Information Element",
174 "Channel rejected",
175 "Channel invalid in current regulatory domain",
176 "MAC invalid",
177 "Command rejected (read-only information element)",
178 "Command rejected",
179 "Already asleep",
180 "TX in progress",
181 "Already awake",
182 "Write only",
183 "RX in progress",
184 "Invalid parameter",
185 "Scan in progress",
186 "Failed"
188 return state < ARRAY_SIZE(cmd_error_strings) ?
189 cmd_error_strings[state] : "?";
192 /***********************************************************************
193 ** acx_s_get_firmware_version
195 ** Obvious
197 void acx_s_get_firmware_version(acx_device_t * adev)
199 fw_ver_t fw;
200 u8 hexarr[4] = { 0, 0, 0, 0 };
201 int hexidx = 0, val = 0;
202 const char *num;
203 char c;
205 FN_ENTER;
207 memset(fw.fw_id, 'E', FW_ID_SIZE);
208 acx_s_interrogate(adev, &fw, ACX1xx_IE_FWREV);
209 memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE);
210 adev->firmware_version[FW_ID_SIZE] = '\0';
212 acx_log(LOG_DEBUG, L_ANY, "fw_ver: fw_id='%s' hw_id=%08X\n",
213 adev->firmware_version, fw.hw_id);
215 if (strncmp(fw.fw_id, "Rev ", 4) != 0) {
216 acx_log(LOG_WARNING, L_ANY, "acx: strange firmware version string "
217 "'%s', please report\n", adev->firmware_version);
218 adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */
219 } else {
220 num = &fw.fw_id[4];
221 while (1) {
222 c = *num++;
223 if ((c == '.') || (c == '\0')) {
224 hexarr[hexidx++] = val;
225 if ((hexidx > 3) || (c == '\0')) /* end? */
226 break;
227 val = 0;
228 continue;
230 if ((c >= '0') && (c <= '9'))
231 c -= '0';
232 else
233 c = c - 'a' + (char)10;
234 val = val * 16 + c;
237 adev->firmware_numver = (u32) ((hexarr[0] << 24) |
238 (hexarr[1] << 16)
239 | (hexarr[2] << 8) | hexarr[3]);
240 acx_log(LOG_DEBUG, L_ANY, "firmware_numver 0x%08X\n",
241 adev->firmware_numver);
244 adev->firmware_id = le32_to_cpu(fw.hw_id);
246 /* we're able to find out more detailed chip names now */
247 switch (adev->firmware_id & 0xffff0000) {
248 case 0x01010000:
249 case 0x01020000:
250 adev->chip_name = "TNETW1100A";
251 break;
252 case 0x01030000:
253 adev->chip_name = "TNETW1100B";
254 break;
255 case 0x03000000:
256 case 0x03010000:
257 adev->chip_name = "TNETW1130";
258 break;
259 case 0x04030000: /* 0x04030101 is TNETW1450 */
260 adev->chip_name = "TNETW1450";
261 break;
262 default:
263 acx_log(LOG_WARNING, L_ANY,"unknown chip ID 0x%08X, "
264 "please report\n", adev->firmware_id);
265 break;
268 FN_EXIT0;
272 /***********************************************************************
273 ** acx_display_hardware_details
275 ** Displays hw/fw version, radio type etc...
277 ** Obvious
279 void acx_display_hardware_details(acx_device_t * adev)
281 const char *radio_str, *form_str;
283 FN_ENTER;
285 switch (adev->radio_type) {
286 case RADIO_MAXIM_0D:
287 radio_str = "Maxim";
288 break;
289 case RADIO_RFMD_11:
290 radio_str = "RFMD";
291 break;
292 case RADIO_RALINK_15:
293 radio_str = "Ralink";
294 break;
295 case RADIO_RADIA_16:
296 radio_str = "Radia";
297 break;
298 case RADIO_UNKNOWN_17:
299 /* TI seems to have a radio which is
300 * additionally 802.11a capable, too */
301 radio_str = "802.11a/b/g radio?! Please report";
302 break;
303 case RADIO_UNKNOWN_19:
304 radio_str = "A radio used by Safecom cards?! Please report";
305 break;
306 case RADIO_UNKNOWN_1B:
307 radio_str = "An unknown radio used by TNETW1450 USB adapters";
308 break;
309 default:
310 radio_str = "UNKNOWN, please report radio type name!";
311 break;
314 switch (adev->form_factor) {
315 case 0x00:
316 form_str = "unspecified";
317 break;
318 case 0x01:
319 form_str = "(mini-)PCI / CardBus";
320 break;
321 case 0x02:
322 form_str = "USB";
323 break;
324 case 0x03:
325 form_str = "Compact Flash";
326 break;
327 default:
328 form_str = "UNKNOWN, please report";
329 break;
332 acx_log(LOG_INFO, L_ANY, "acx: chipset %s, radio type 0x%02X (%s), "
333 "form factor 0x%02X (%s), EEPROM version 0x%02X, "
334 "uploaded firmware '%s'\n",
335 adev->chip_name, adev->radio_type, radio_str,
336 adev->form_factor, form_str, adev->eeprom_version,
337 adev->firmware_version);
339 FN_EXIT0;
343 /***********************************************************************
344 ** acx_e_get_stats, acx_e_get_wireless_stats
347 acx_e_get_stats(struct ieee80211_hw *hw,
348 struct ieee80211_low_level_stats *stats)
350 acx_device_t *adev = ieee2adev(hw);
351 unsigned long flags;
352 acx_lock(adev, flags);
353 memcpy(stats, &adev->ieee_stats, sizeof(*stats));
354 acx_unlock(adev, flags);
355 return 0;
359 /***********************************************************************
360 ** maps acx111 tx descr rate field to acx100 one
362 const u8 acx_bitpos2rate100[] = {
363 RATE100_1, /* 0 */
364 RATE100_2, /* 1 */
365 RATE100_5, /* 2 */
366 RATE100_2, /* 3, should not happen */
367 RATE100_2, /* 4, should not happen */
368 RATE100_11, /* 5 */
369 RATE100_2, /* 6, should not happen */
370 RATE100_2, /* 7, should not happen */
371 RATE100_22, /* 8 */
372 RATE100_2, /* 9, should not happen */
373 RATE100_2, /* 10, should not happen */
374 RATE100_2, /* 11, should not happen */
375 RATE100_2, /* 12, should not happen */
376 RATE100_2, /* 13, should not happen */
377 RATE100_2, /* 14, should not happen */
378 RATE100_2, /* 15, should not happen */
381 u8 acx_rate111to100(u16 r)
383 return acx_bitpos2rate100[highest_bit(r)];
387 /***********************************************************************
388 ** Calculate level like the feb 2003 windows driver seems to do
390 static u8 acx_signal_to_winlevel(u8 rawlevel)
392 /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
393 u8 winlevel = ((4 + (rawlevel * 5)) / 8);
395 if (winlevel > 100)
396 winlevel = 100;
397 return winlevel;
400 u8 acx_signal_determine_quality(u8 signal, u8 noise)
402 int qual;
404 qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2;
406 if (qual > 100)
407 return 100;
408 if (qual < 0)
409 return 0;
410 return qual;
414 /***********************************************************************
415 ** Interrogate/configure commands
418 /* FIXME: the lengths given here probably aren't always correct.
419 * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4",
420 * unless the firmware actually expects a different length than the struct length */
421 static const u16 acx100_ie_len[] = {
423 ACX100_IE_ACX_TIMER_LEN,
424 sizeof(acx100_ie_powersave_t) - 4, /* is that 6 or 8??? */
425 ACX1xx_IE_QUEUE_CONFIG_LEN,
426 ACX100_IE_BLOCK_SIZE_LEN,
427 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
428 ACX1xx_IE_RATE_FALLBACK_LEN,
429 ACX100_IE_WEP_OPTIONS_LEN,
430 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
432 ACX1xx_IE_ASSOC_ID_LEN,
434 ACX111_IE_CONFIG_OPTIONS_LEN,
435 ACX1xx_IE_FWREV_LEN,
436 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
437 ACX1xx_IE_MEDIUM_USAGE_LEN,
438 ACX1xx_IE_RXCONFIG_LEN,
441 sizeof(fw_stats_t) - 4,
443 ACX1xx_IE_FEATURE_CONFIG_LEN,
444 ACX111_IE_KEY_CHOOSE_LEN,
445 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
446 ACX1FF_IE_WONE_CONFIG_LEN,
448 ACX1FF_IE_TID_CONFIG_LEN,
452 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
453 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
454 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
455 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
457 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
458 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
459 ACX1FF_IE_CCA_THRESHOLD_LEN,
460 ACX1FF_IE_EVENT_MASK_LEN,
461 ACX1FF_IE_DTIM_PERIOD_LEN,
463 ACX1FF_IE_ACI_CONFIG_SET_LEN,
470 ACX1FF_IE_EEPROM_VER_LEN,
473 static const u16 acx100_ie_len_dot11[] = {
475 ACX1xx_IE_DOT11_STATION_ID_LEN,
477 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
478 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
479 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
480 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
481 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
482 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
484 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
485 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
487 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
488 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
489 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
490 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
496 static const u16 acx111_ie_len[] = {
498 ACX100_IE_ACX_TIMER_LEN,
499 sizeof(acx111_ie_powersave_t) - 4,
500 ACX1xx_IE_QUEUE_CONFIG_LEN,
501 ACX100_IE_BLOCK_SIZE_LEN,
502 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
503 ACX1xx_IE_RATE_FALLBACK_LEN,
504 ACX100_IE_WEP_OPTIONS_LEN,
505 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
507 ACX1xx_IE_ASSOC_ID_LEN,
509 ACX111_IE_CONFIG_OPTIONS_LEN,
510 ACX1xx_IE_FWREV_LEN,
511 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
512 ACX1xx_IE_MEDIUM_USAGE_LEN,
513 ACX1xx_IE_RXCONFIG_LEN,
516 sizeof(fw_stats_t) - 4,
518 ACX1xx_IE_FEATURE_CONFIG_LEN,
519 ACX111_IE_KEY_CHOOSE_LEN,
520 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
521 ACX1FF_IE_WONE_CONFIG_LEN,
523 ACX1FF_IE_TID_CONFIG_LEN,
527 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
528 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
529 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
530 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
532 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
533 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
534 ACX1FF_IE_CCA_THRESHOLD_LEN,
535 ACX1FF_IE_EVENT_MASK_LEN,
536 ACX1FF_IE_DTIM_PERIOD_LEN,
538 ACX1FF_IE_ACI_CONFIG_SET_LEN,
545 ACX1FF_IE_EEPROM_VER_LEN,
548 static const u16 acx111_ie_len_dot11[] = {
550 ACX1xx_IE_DOT11_STATION_ID_LEN,
552 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
553 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
554 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
555 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
556 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
557 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
559 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
560 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
562 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
563 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
564 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
565 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
572 #if !ACX_DEBUG
573 int acx_s_configure(acx_device_t * adev, void *pdr, int type)
575 #else
577 acx_s_configure_debug(acx_device_t * adev, void *pdr, int type,
578 const char *typestr)
580 #endif
581 u16 len;
582 int res;
584 if (type < 0x1000)
585 len = adev->ie_len[type];
586 else
587 len = adev->ie_len_dot11[type - 0x1000];
589 acx_log(LOG_DEBUG, L_CTL, "configure (type:%s,len:%u)\n", typestr, len);
590 if (unlikely(!len)) {
591 acx_log(LOG_DEBUG, L_ANY, "zero-length type %s?!\n", typestr);
594 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
595 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
596 res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4);
597 if (unlikely(OK != res)) {
598 #if ACX_DEBUG
599 acx_log(LOG_WARNING, L_ANY, "%s: configure (type:%s) FAILED\n",
600 wiphy_name(adev->ieee->wiphy), typestr);
601 #else
602 acx_log(LOG_WARNING, L_ANY,
603 "%s: configure (type:0x%X) FAILED\n",
604 wiphy_name(adev->ieee->wiphy), type);
605 #endif
606 /* dump_stack() is already done in issue_cmd() */
608 return res;
611 #if !ACX_DEBUG
612 int acx_s_interrogate(acx_device_t * adev, void *pdr, int type)
614 #else
616 acx_s_interrogate_debug(acx_device_t * adev, void *pdr, int type,
617 const char *typestr)
619 #endif
620 u16 len;
621 int res;
623 FN_ENTER;
625 /* FIXME: no check whether this exceeds the array yet.
626 * We should probably remember the number of entries... */
627 if (type < 0x1000)
628 len = adev->ie_len[type];
629 else
630 len = adev->ie_len_dot11[type - 0x1000];
632 acx_log(LOG_DEBUG, L_CTL, "interrogate (type:%s,len:%u)\n",
633 typestr, len);
635 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
636 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
637 res = acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, pdr, len + 4);
638 if (unlikely(OK != res)) {
639 #if ACX_DEBUG
640 acx_log(LOG_WARNING, L_ANY,
641 "%s: interrogate (type:%s) FAILED\n",
642 wiphy_name(adev->ieee->wiphy), typestr);
643 #else
644 acx_log(LOG_WARNING, L_ANY,
645 "%s: interrogate (type:0x%X) FAILED\n",
646 wiphy_name(adev->ieee->wiphy), type);
647 #endif
648 /* dump_stack() is already done in issue_cmd() */
651 FN_EXIT1(res);
652 return res;
655 #if CMD_DISCOVERY
656 void great_inquisitor(acx_device_t * adev)
658 static struct {
659 u16 type;
660 u16 len;
661 /* 0x200 was too large here: */
662 u8 data[0x100 - 4];
663 } __attribute__ ((packed)) ie;
664 u16 type;
666 FN_ENTER;
668 /* 0..0x20, 0x1000..0x1020 */
669 for (type = 0; type <= 0x1020; type++) {
670 if (type == 0x21)
671 type = 0x1000;
672 ie.type = cpu_to_le16(type);
673 ie.len = cpu_to_le16(sizeof(ie) - 4);
674 acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie));
676 FN_EXIT0;
678 #endif
681 #ifdef CONFIG_PROC_FS
682 /***********************************************************************
683 ** /proc files
685 /***********************************************************************
686 ** acx_l_proc_output
687 ** Generate content for our /proc entry
689 ** Arguments:
690 ** buf is a pointer to write output to
691 ** adev is the usual pointer to our private struct acx_device
692 ** Returns:
693 ** number of bytes actually written to buf
694 ** Side effects:
695 ** none
697 static int acx_l_proc_output(char *buf, acx_device_t * adev)
699 char *p = buf;
701 FN_ENTER;
703 p += sprintf(p,
704 "acx driver version:\t\t" ACX_RELEASE "\n"
705 "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n"
706 "chip name:\t\t\t%s (0x%08X)\n"
707 "radio type:\t\t\t0x%02X\n"
708 "form factor:\t\t\t0x%02X\n"
709 "EEPROM version:\t\t\t0x%02X\n"
710 "firmware version:\t\t%s (0x%08X)\n",
711 adev->chip_name, adev->firmware_id,
712 adev->radio_type,
713 adev->form_factor,
714 adev->eeprom_version,
715 adev->firmware_version, adev->firmware_numver);
717 FN_EXIT1(p - buf);
718 return p - buf;
722 /***********************************************************************
724 static int acx_s_proc_diag_output(char *buf, acx_device_t * adev)
726 char *p = buf;
727 unsigned long flags;
728 ssize_t len = 0, partlen;
729 u32 temp1, temp2;
730 u8 *st, *st_end;
731 #ifdef __BIG_ENDIAN
732 u8 *st2;
733 #endif
734 fw_stats_t *fw_stats;
735 char *part_str = NULL;
736 fw_stats_tx_t *tx = NULL;
737 fw_stats_rx_t *rx = NULL;
738 fw_stats_dma_t *dma = NULL;
739 fw_stats_irq_t *irq = NULL;
740 fw_stats_wep_t *wep = NULL;
741 fw_stats_pwr_t *pwr = NULL;
742 fw_stats_mic_t *mic = NULL;
743 fw_stats_aes_t *aes = NULL;
744 fw_stats_event_t *evt = NULL;
746 FN_ENTER;
748 acx_lock(adev, flags);
750 if (IS_PCI(adev))
751 p = acxpci_s_proc_diag_output(p, adev);
753 p += sprintf(p,
754 "\n"
755 "** network status **\n"
756 "dev_state_mask 0x%04X\n"
757 "mode %u, channel %u, "
758 "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
759 adev->dev_state_mask,
760 adev->mode, adev->channel,
761 adev->reg_dom_id, adev->reg_dom_chanmask);
762 p += sprintf(p,
763 "ESSID \"%s\", essid_active %d, essid_len %d, "
764 "essid_for_assoc \"%s\", nick \"%s\"\n"
765 "WEP ena %d, restricted %d, idx %d\n",
766 adev->essid, adev->essid_active, (int)adev->essid_len,
767 adev->essid_for_assoc, adev->nick,
768 adev->wep_enabled, adev->wep_restricted,
769 adev->wep_current_index);
770 p += sprintf(p, "dev_addr " MACSTR "\n", MAC(adev->dev_addr));
771 p += sprintf(p, "bssid " MACSTR "\n", MAC(adev->bssid));
772 p += sprintf(p, "ap_filter " MACSTR "\n", MAC(adev->ap));
774 p += sprintf(p, "\n" "** PHY status **\n"
775 "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
776 "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
777 "rate_basic 0x%04X, rate_oper 0x%04X\n"
778 "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
779 "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
780 adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */
781 adev->sensitivity, adev->antenna, adev->ed_threshold,
782 adev->cca, adev->preamble_mode, adev->rate_basic, adev->rate_oper, adev->rts_threshold,
783 adev->frag_threshold, adev->short_retry, adev->long_retry,
784 adev->msdu_lifetime, adev->listen_interval,
785 adev->beacon_interval);
787 acx_unlock(adev, flags);
789 p += sprintf(p,
790 "\n"
791 "** Firmware **\n"
792 "NOTE: version dependent statistics layout, "
793 "please report if you suspect wrong parsing!\n"
794 "\n" "version \"%s\"\n", adev->firmware_version);
796 /* TODO: may replace kmalloc/memset with kzalloc once
797 * Linux 2.6.14 is widespread */
798 fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL);
799 if (!fw_stats) {
800 FN_EXIT1(0);
801 return 0;
803 memset(fw_stats, 0, sizeof(*fw_stats));
805 st = (u8 *) fw_stats;
807 part_str = "statistics query command";
809 if (OK != acx_s_interrogate(adev, st, ACX1xx_IE_FIRMWARE_STATISTICS))
810 goto fw_stats_end;
812 st += sizeof(u16);
813 len = *(u16 *) st;
815 if (len > sizeof(*fw_stats)) {
816 p += sprintf(p,
817 "firmware version with bigger fw_stats struct detected\n"
818 "(%zu vs. %zu), please report\n", len, sizeof(fw_stats_t));
819 if (len > sizeof(*fw_stats)) {
820 p += sprintf(p, "struct size exceeded allocation!\n");
821 len = sizeof(*fw_stats);
824 st += sizeof(u16);
825 st_end = st - 2 * sizeof(u16) + len;
827 #ifdef __BIG_ENDIAN
828 /* let's make one bold assumption here:
829 * (hopefully!) *all* statistics fields are u32 only,
830 * thus if we need to make endianness corrections
831 * we can simply do them in one go, in advance */
832 st2 = (u8 *) fw_stats;
833 for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4)
834 *(u32 *) st2 = le32_to_cpu(*(u32 *) st2);
835 #endif
837 part_str = "Rx/Tx";
839 /* directly at end of a struct part? --> no error! */
840 if (st == st_end)
841 goto fw_stats_end;
843 tx = (fw_stats_tx_t *) st;
844 st += sizeof(fw_stats_tx_t);
845 rx = (fw_stats_rx_t *) st;
846 st += sizeof(fw_stats_rx_t);
847 partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t);
849 if (IS_ACX100(adev)) {
850 /* at least ACX100 PCI F/W 1.9.8.b
851 * and ACX100 USB F/W 1.0.7-USB
852 * don't have those two fields... */
853 st -= 2 * sizeof(u32);
855 /* our parsing doesn't quite match this firmware yet,
856 * log failure */
857 if (st > st_end)
858 goto fw_stats_fail;
859 temp1 = temp2 = 999999999;
860 } else {
861 if (st > st_end)
862 goto fw_stats_fail;
863 temp1 = rx->rx_aci_events;
864 temp2 = rx->rx_aci_resets;
867 p += sprintf(p,
868 "%s:\n"
869 " tx_desc_overfl %u\n"
870 " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
871 " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n"
872 " rx_aci_events %u, rx_aci_resets %u\n",
873 part_str,
874 tx->tx_desc_of,
875 rx->rx_oom,
876 rx->rx_hdr_of,
877 rx->rx_hw_stuck,
878 rx->rx_dropped_frame,
879 rx->rx_frame_ptr_err, rx->rx_xfr_hint_trig, temp1, temp2);
881 part_str = "DMA";
883 if (st == st_end)
884 goto fw_stats_end;
886 dma = (fw_stats_dma_t *) st;
887 partlen = sizeof(fw_stats_dma_t);
888 st += partlen;
890 if (st > st_end)
891 goto fw_stats_fail;
893 p += sprintf(p,
894 "%s:\n"
895 " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n",
896 part_str,
897 dma->rx_dma_req,
898 dma->rx_dma_err, dma->tx_dma_req, dma->tx_dma_err);
900 part_str = "IRQ";
902 if (st == st_end)
903 goto fw_stats_end;
905 irq = (fw_stats_irq_t *) st;
906 partlen = sizeof(fw_stats_irq_t);
907 st += partlen;
909 if (st > st_end)
910 goto fw_stats_fail;
912 p += sprintf(p,
913 "%s:\n"
914 " cmd_cplt %u, fiq %u\n"
915 " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
916 " irqs %u, tx_procs %u, decrypt_done %u\n"
917 " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
918 " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
919 " host_acks %u, pci_pm %u, acm_wakeups %u\n",
920 part_str,
921 irq->cmd_cplt,
922 irq->fiq,
923 irq->rx_hdrs,
924 irq->rx_cmplt,
925 irq->rx_mem_of,
926 irq->rx_rdys,
927 irq->irqs,
928 irq->tx_procs,
929 irq->decrypt_done,
930 irq->dma_0_done,
931 irq->dma_1_done,
932 irq->tx_exch_complet,
933 irq->commands,
934 irq->rx_procs,
935 irq->hw_pm_mode_changes,
936 irq->host_acks, irq->pci_pm, irq->acm_wakeups);
938 part_str = "WEP";
940 if (st == st_end)
941 goto fw_stats_end;
943 wep = (fw_stats_wep_t *) st;
944 partlen = sizeof(fw_stats_wep_t);
945 st += partlen;
947 if (IS_ACX100(adev)) {
948 /* at least ACX100 PCI F/W 1.9.8.b
949 * and ACX100 USB F/W 1.0.7-USB
950 * don't have those two fields... */
951 st -= 2 * sizeof(u32);
952 if (st > st_end)
953 goto fw_stats_fail;
954 temp1 = temp2 = 999999999;
955 } else {
956 if (st > st_end)
957 goto fw_stats_fail;
958 temp1 = wep->wep_pkt_decrypt;
959 temp2 = wep->wep_decrypt_irqs;
962 p += sprintf(p,
963 "%s:\n"
964 " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
965 " wep_key_not_found %u, wep_decrypt_fail %u\n"
966 " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
967 part_str,
968 wep->wep_key_count,
969 wep->wep_default_key_count,
970 wep->dot11_def_key_mib,
971 wep->wep_key_not_found,
972 wep->wep_decrypt_fail, temp1, temp2);
974 part_str = "power";
976 if (st == st_end)
977 goto fw_stats_end;
979 pwr = (fw_stats_pwr_t *) st;
980 partlen = sizeof(fw_stats_pwr_t);
981 st += partlen;
983 if (st > st_end)
984 goto fw_stats_fail;
986 p += sprintf(p,
987 "%s:\n"
988 " tx_start_ctr %u, no_ps_tx_too_short %u\n"
989 " rx_start_ctr %u, no_ps_rx_too_short %u\n"
990 " lppd_started %u\n"
991 " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n",
992 part_str,
993 pwr->tx_start_ctr,
994 pwr->no_ps_tx_too_short,
995 pwr->rx_start_ctr,
996 pwr->no_ps_rx_too_short,
997 pwr->lppd_started,
998 pwr->no_lppd_too_noisy,
999 pwr->no_lppd_too_short, pwr->no_lppd_matching_frame);
1001 part_str = "MIC";
1003 if (st == st_end)
1004 goto fw_stats_end;
1006 mic = (fw_stats_mic_t *) st;
1007 partlen = sizeof(fw_stats_mic_t);
1008 st += partlen;
1010 if (st > st_end)
1011 goto fw_stats_fail;
1013 p += sprintf(p,
1014 "%s:\n"
1015 " mic_rx_pkts %u, mic_calc_fail %u\n",
1016 part_str, mic->mic_rx_pkts, mic->mic_calc_fail);
1018 part_str = "AES";
1020 if (st == st_end)
1021 goto fw_stats_end;
1023 aes = (fw_stats_aes_t *) st;
1024 partlen = sizeof(fw_stats_aes_t);
1025 st += partlen;
1027 if (st > st_end)
1028 goto fw_stats_fail;
1030 p += sprintf(p,
1031 "%s:\n"
1032 " aes_enc_fail %u, aes_dec_fail %u\n"
1033 " aes_enc_pkts %u, aes_dec_pkts %u\n"
1034 " aes_enc_irq %u, aes_dec_irq %u\n",
1035 part_str,
1036 aes->aes_enc_fail,
1037 aes->aes_dec_fail,
1038 aes->aes_enc_pkts,
1039 aes->aes_dec_pkts, aes->aes_enc_irq, aes->aes_dec_irq);
1041 part_str = "event";
1043 if (st == st_end)
1044 goto fw_stats_end;
1046 evt = (fw_stats_event_t *) st;
1047 partlen = sizeof(fw_stats_event_t);
1048 st += partlen;
1050 if (st > st_end)
1051 goto fw_stats_fail;
1053 p += sprintf(p,
1054 "%s:\n"
1055 " heartbeat %u, calibration %u\n"
1056 " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
1057 " oom_late %u\n"
1058 " phy_tx_err %u, tx_stuck %u\n",
1059 part_str,
1060 evt->heartbeat,
1061 evt->calibration,
1062 evt->rx_mismatch,
1063 evt->rx_mem_empty,
1064 evt->rx_pool,
1065 evt->oom_late, evt->phy_tx_err, evt->tx_stuck);
1067 if (st < st_end)
1068 goto fw_stats_bigger;
1070 goto fw_stats_end;
1072 fw_stats_fail:
1073 st -= partlen;
1074 p += sprintf(p,
1075 "failed at %s part (size %zu), offset %zu (struct size %zu), "
1076 "please report\n", part_str, partlen,
1077 ((void *)st - (void *)fw_stats), len);
1079 fw_stats_bigger:
1080 for (; st < st_end; st += 4)
1081 p += sprintf(p,
1082 "UNKN%3d: %u\n",
1083 (int)((void *)st - (void *)fw_stats), *(u32 *) st);
1085 fw_stats_end:
1086 kfree(fw_stats);
1088 FN_EXIT1(p - buf);
1089 return p - buf;
1093 /***********************************************************************
1095 static int acx_s_proc_phy_output(char *buf, acx_device_t * adev)
1097 char *p = buf;
1098 int i;
1100 FN_ENTER;
1103 if (RADIO_RFMD_11 != adev->radio_type) {
1104 printk("sorry, not yet adapted for radio types "
1105 "other than RFMD, please verify "
1106 "PHY size etc. first!\n");
1107 goto end;
1111 /* The PHY area is only 0x80 bytes long; further pages after that
1112 * only have some page number registers with altered value,
1113 * all other registers remain the same. */
1114 for (i = 0; i < 0x80; i++) {
1115 acx_s_read_phy_reg(adev, i, p++);
1118 FN_EXIT1(p - buf);
1119 return p - buf;
1123 /***********************************************************************
1124 ** acx_e_read_proc_XXXX
1125 ** Handle our /proc entry
1127 ** Arguments:
1128 ** standard kernel read_proc interface
1129 ** Returns:
1130 ** number of bytes written to buf
1131 ** Side effects:
1132 ** none
1134 static int
1135 acx_e_read_proc(char *buf, char **start, off_t offset, int count,
1136 int *eof, void *data)
1138 acx_device_t *adev = (acx_device_t *) data;
1139 unsigned long flags;
1140 int length;
1142 FN_ENTER;
1144 acx_sem_lock(adev);
1145 acx_lock(adev, flags);
1146 /* fill buf */
1147 length = acx_l_proc_output(buf, adev);
1148 acx_unlock(adev, flags);
1149 acx_sem_unlock(adev);
1151 /* housekeeping */
1152 if (length <= offset + count)
1153 *eof = 1;
1154 *start = buf + offset;
1155 length -= offset;
1156 if (length > count)
1157 length = count;
1158 if (length < 0)
1159 length = 0;
1160 FN_EXIT1(length);
1161 return length;
1164 static int
1165 acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count,
1166 int *eof, void *data)
1168 acx_device_t *adev = (acx_device_t *) data;
1169 int length;
1171 FN_ENTER;
1173 acx_sem_lock(adev);
1174 /* fill buf */
1175 length = acx_s_proc_diag_output(buf, adev);
1176 acx_sem_unlock(adev);
1178 /* housekeeping */
1179 if (length <= offset + count)
1180 *eof = 1;
1181 *start = buf + offset;
1182 length -= offset;
1183 if (length > count)
1184 length = count;
1185 if (length < 0)
1186 length = 0;
1187 FN_EXIT1(length);
1188 return length;
1191 static int
1192 acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count,
1193 int *eof, void *data)
1195 acx_device_t *adev = (acx_device_t *) data;
1196 int length;
1198 FN_ENTER;
1200 /* fill buf */
1201 length = 0;
1202 if (IS_PCI(adev)) {
1203 acx_sem_lock(adev);
1204 length = acxpci_proc_eeprom_output(buf, adev);
1205 acx_sem_unlock(adev);
1208 /* housekeeping */
1209 if (length <= offset + count)
1210 *eof = 1;
1211 *start = buf + offset;
1212 length -= offset;
1213 if (length > count)
1214 length = count;
1215 if (length < 0)
1216 length = 0;
1217 FN_EXIT1(length);
1218 return length;
1221 static int
1222 acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count,
1223 int *eof, void *data)
1225 acx_device_t *adev = (acx_device_t *) data;
1226 int length;
1228 FN_ENTER;
1230 acx_sem_lock(adev);
1231 /* fill buf */
1232 length = acx_s_proc_phy_output(buf, adev);
1233 acx_sem_unlock(adev);
1235 /* housekeeping */
1236 if (length <= offset + count)
1237 *eof = 1;
1238 *start = buf + offset;
1239 length -= offset;
1240 if (length > count)
1241 length = count;
1242 if (length < 0)
1243 length = 0;
1244 FN_EXIT1(length);
1245 return length;
1249 /***********************************************************************
1250 ** /proc files registration
1252 static const char *const
1253 proc_files[] = { "", "_diag", "_eeprom", "_phy" };
1255 static read_proc_t *const
1256 proc_funcs[] = {
1257 acx_e_read_proc,
1258 acx_e_read_proc_diag,
1259 acx_e_read_proc_eeprom,
1260 acx_e_read_proc_phy
1263 static int manage_proc_entries(struct ieee80211_hw *hw, int remove)
1265 acx_device_t *adev = ieee2adev(hw);
1266 char procbuf[80];
1267 int i;
1269 FN_ENTER;
1271 for (i = 0; i < ARRAY_SIZE(proc_files); i++) {
1272 snprintf(procbuf, sizeof(procbuf),
1273 "driver/acx%s", proc_files[i]);
1274 acx_log(LOG_INFO, L_INIT, "%sing /proc entry %s\n",
1275 remove ? "remov" : "creat", procbuf);
1276 if (!remove) {
1277 if (!create_proc_read_entry
1278 (procbuf, 0, NULL, proc_funcs[i], adev)) {
1279 acx_log(LOG_WARNING, L_ANY,
1280 "cannot register /proc entry %s\n", procbuf);
1281 FN_EXIT1(NOT_OK);
1282 return NOT_OK;
1284 } else {
1285 remove_proc_entry(procbuf, NULL);
1288 FN_EXIT0;
1289 return OK;
1292 int acx_proc_register_entries(struct ieee80211_hw *ieee)
1294 return manage_proc_entries(ieee, 0);
1297 int acx_proc_unregister_entries(struct ieee80211_hw *ieee)
1299 return manage_proc_entries(ieee, 1);
1301 #endif /* CONFIG_PROC_FS */
1303 /****
1304 ** Gathered From rt2x00 and bcm43xx_mac80211 projects
1306 void acx_free_modes(acx_device_t * adev)
1309 // kfree(adev->modes);
1310 // adev->modes = NULL;
1314 #define RATETAB_ENT(_rate, _rateid, _flags) \
1316 .rate = (_rate), \
1317 .val = (_rateid), \
1318 .val2 = (_rateid), \
1319 .flags = (_flags), \
1323 static struct ieee80211_rate __acx_rates[] = {
1324 { .rate = 10,
1325 .val = RATE111_1,
1326 .flags = IEEE80211_RATE_CCK },
1327 { .rate = 20,
1328 .val = RATE111_2,
1329 .flags = IEEE80211_RATE_CCK },
1330 { .rate = 55,
1331 .val = RATE111_5,
1332 .flags = IEEE80211_RATE_CCK },
1333 { .rate = 110,
1334 .val = RATE111_11,
1335 .flags = IEEE80211_RATE_CCK },
1336 { .rate = 60,
1337 .val = RATE111_6,
1338 .flags = IEEE80211_RATE_OFDM },
1339 { .rate = 90,
1340 .val = RATE111_9,
1341 .flags = IEEE80211_RATE_OFDM },
1342 { .rate = 120,
1343 .val = RATE111_12,
1344 .flags = IEEE80211_RATE_OFDM },
1345 { .rate = 180,
1346 .val = RATE111_18,
1347 .flags = IEEE80211_RATE_OFDM },
1348 { .rate = 240,
1349 .val = RATE111_24,
1350 .flags = IEEE80211_RATE_OFDM },
1351 { .rate = 360,
1352 .val = RATE111_36,
1353 .flags = IEEE80211_RATE_OFDM },
1354 { .rate = 480,
1355 .val = RATE111_48,
1356 .flags = IEEE80211_RATE_OFDM },
1357 { .rate = 540,
1358 .val = RATE111_54,
1359 .flags = IEEE80211_RATE_OFDM },
1362 static struct ieee80211_channel channels[] = {
1363 { .chan = 1,
1364 .freq = 2412},
1365 { .chan = 2,
1366 .freq = 2417},
1367 { .chan = 3,
1368 .freq = 2422},
1369 { .chan = 4,
1370 .freq = 2427},
1371 { .chan = 5,
1372 .freq = 2432},
1373 { .chan = 6,
1374 .freq = 2437},
1375 { .chan = 7,
1376 .freq = 2442},
1377 { .chan = 8,
1378 .freq = 2447},
1379 { .chan = 9,
1380 .freq = 2452},
1381 { .chan = 10,
1382 .freq = 2457},
1383 { .chan = 11,
1384 .freq = 2462},
1385 { .chan = 12,
1386 .freq = 2467},
1387 { .chan = 13,
1388 .freq = 2472},
1391 int acx_setup_modes(acx_device_t * adev)
1393 struct ieee80211_hw *hw = adev->ieee;
1394 struct ieee80211_hw_mode *mode;
1395 int err = -ENOMEM;
1397 FN_ENTER;
1399 if (IS_ACX111(adev)) {
1401 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);
1402 err = acx_setup_modes_gphy(adev);
1404 mode = &adev->modes[0];
1406 /* from the zd1211rw driver: - do we need to do the same? */
1408 memcpy(mode->channels, channels, sizeof(channels));
1409 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1412 mode->mode = MODE_IEEE80211G;
1413 mode->num_channels = ARRAY_SIZE(channels);
1414 mode->num_rates = 12;
1415 mode->rates = __acx_rates;
1416 } else {
1418 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1419 err = acx_setup_modes_bphy(adev);
1421 mode = &adev->modes[1];
1423 /* from the zd1211rw driver: - do we need to do the same? */
1425 memcpy(mode->channels, channels, sizeof(channels));
1426 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1429 mode->mode = MODE_IEEE80211B;
1430 mode->num_channels = ARRAY_SIZE(channels);
1431 mode->num_rates = 4;
1432 mode->rates = __acx_rates;
1435 /* if (err && adev->modes)
1436 kfree(adev->modes);*/
1438 mode->channels = channels;
1439 err = ieee80211_register_hwmode(hw, mode);
1441 FN_EXIT1(err);
1442 return err;
1446 /***********************************************************************
1447 ** acx_fill_beacon_or_proberesp_template
1449 ** Origin: derived from rt2x00 project
1451 static int
1452 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1453 struct acx_template_beacon *templ,
1454 struct sk_buff* skb /* in host order! */)
1456 FN_ENTER;
1458 memcpy(templ,skb->data, skb->len);
1459 FN_EXIT1(skb->len);
1460 return skb->len;
1463 /***********************************************************************
1464 ** acx_s_set_beacon_template
1468 static int
1469 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1471 struct acx_template_beacon bcn;
1472 int len, result;
1474 FN_ENTER;
1475 acx_log(LOG_INFO, L_ANY, "size of template: %08zX, "
1476 "size of beacon: %08X\n",
1477 sizeof(struct acx_template_beacon),skb->len);
1478 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1479 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1481 FN_EXIT1(result);
1482 return result;
1485 /***********************************************************************
1486 ** acx_cmd_join_bssid
1488 ** Common code for both acx100 and acx111.
1490 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1491 static const u8 bitpos2genframe_txrate[] = {
1492 10, /* 0. 1 Mbit/s */
1493 20, /* 1. 2 Mbit/s */
1494 55, /* 2. 5.5 Mbit/s */
1495 0x0B, /* 3. 6 Mbit/s */
1496 0x0F, /* 4. 9 Mbit/s */
1497 110, /* 5. 11 Mbit/s */
1498 0x0A, /* 6. 12 Mbit/s */
1499 0x0E, /* 7. 18 Mbit/s */
1500 220, /* 8. 22 Mbit/s */
1501 0x09, /* 9. 24 Mbit/s */
1502 0x0D, /* 10. 36 Mbit/s */
1503 0x08, /* 11. 48 Mbit/s */
1504 0x0C, /* 12. 54 Mbit/s */
1505 10, /* 13. 1 Mbit/s, should never happen */
1506 10, /* 14. 1 Mbit/s, should never happen */
1507 10, /* 15. 1 Mbit/s, should never happen */
1510 /* Looks scary, eh?
1511 ** Actually, each one compiled into one AND and one SHIFT,
1512 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1513 static inline unsigned int rate111to5bits(unsigned int rate)
1515 return (rate & 0x7)
1516 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1517 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1521 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1523 acx_joinbss_t tmp;
1524 int dtim_interval;
1525 int i;
1527 if (mac_is_zero(bssid))
1528 return;
1530 FN_ENTER;
1532 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1533 1 : adev->dtim_interval;
1535 memset(&tmp, 0, sizeof(tmp));
1537 for (i = 0; i < ETH_ALEN; i++) {
1538 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1541 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1543 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1544 ** are sent with one of these rates */
1545 if (IS_ACX111(adev)) {
1546 /* It was experimentally determined that rates_basic
1547 ** can take 11g rates as well, not only rates
1548 ** defined with JOINBSS_RATES_BASIC111_nnn.
1549 ** Just use RATE111_nnn constants... */
1550 tmp.u.acx111.dtim_interval = dtim_interval;
1551 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1552 acx_log(LOG_INFO, L_ASSOC, "rates_basic:%04X, "
1553 "rates_supported:%04X\n",
1554 adev->rate_basic, adev->rate_oper);
1555 } else {
1556 tmp.u.acx100.dtim_interval = dtim_interval;
1557 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1558 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1559 acx_log(LOG_INFO, L_ASSOC, "rates_basic:%04X->%02X, "
1560 "rates_supported:%04X->%02X\n",
1561 adev->rate_basic, tmp.u.acx100.rates_basic,
1562 adev->rate_oper, tmp.u.acx100.rates_supported);
1565 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1566 ** will be sent (rate/modulation/preamble) */
1567 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1568 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1569 /* we can use short pre *if* all peers can understand it */
1570 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1572 /* we switch fw to STA mode in MONITOR mode, it seems to be
1573 ** the only mode where fw does not emit beacons by itself
1574 ** but allows us to send anything (we really want to retain
1575 ** ability to tx arbitrary frames in MONITOR mode)
1577 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1578 tmp.channel = adev->channel;
1579 tmp.essid_len = adev->essid_len;
1581 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1582 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1584 acx_log(LOG_DEBUG, L_ASSOC, "BSS_Type = %u\n", tmp.macmode);
1585 acx_log(LOG_DEBUG, L_ASSOC, "JoinBSSID MAC:" MACSTR "\n",
1586 adev->bssid, "\n");
1588 /* acx_update_capabilities(adev); */
1589 FN_EXIT0;
1592 /***********************************************************************
1593 ** acxpci_i_set_multicast_list
1594 ** FIXME: most likely needs refinement
1597 void acx_i_set_multicast_list(struct ieee80211_hw *hw,
1598 unsigned int changed_flags,
1599 unsigned int *total_flags,
1600 int mc_count, struct dev_addr_list *mc_list)
1602 acx_device_t *adev = ieee2adev(hw);
1603 unsigned long flags;
1605 FN_ENTER;
1607 acx_lock(adev, flags);
1609 changed_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1610 FIF_CONTROL | FIF_OTHER_BSS);
1611 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1612 FIF_CONTROL | FIF_OTHER_BSS);
1613 /* if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1614 return; */
1616 if (*total_flags) {
1617 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1618 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1619 SET_BIT(adev->set_mask, SET_RXCONFIG);
1620 /* let kernel know in case *we* needed to set promiscuous */
1621 } else {
1622 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1623 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1624 SET_BIT(adev->set_mask, SET_RXCONFIG);
1627 /* cannot update card settings directly here, atomic context */
1628 acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
1630 acx_unlock(adev, flags);
1632 FN_EXIT0;
1635 /***********************************************************************
1636 ** acx111 feature config
1638 ** Obvious
1640 static int
1641 acx111_s_get_feature_config(acx_device_t * adev,
1642 u32 * feature_options, u32 * data_flow_options)
1644 struct acx111_ie_feature_config feat;
1646 FN_ENTER;
1648 if (!IS_ACX111(adev)) {
1649 return NOT_OK;
1652 memset(&feat, 0, sizeof(feat));
1654 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1655 FN_EXIT1(NOT_OK);
1656 return NOT_OK;
1658 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
1659 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1660 feat.feature_options, feat.data_flow_options);
1662 if (feature_options)
1663 *feature_options = le32_to_cpu(feat.feature_options);
1664 if (data_flow_options)
1665 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1667 FN_EXIT0;
1668 return OK;
1672 static int
1673 acx111_s_set_feature_config(acx_device_t * adev,
1674 u32 feature_options, u32 data_flow_options,
1675 unsigned int mode
1676 /* 0 == remove, 1 == add, 2 == set */ )
1678 struct acx111_ie_feature_config feat;
1680 FN_ENTER;
1682 if (!IS_ACX111(adev)) {
1683 FN_EXIT1(NOT_OK);
1684 return NOT_OK;
1687 if ((mode < 0) || (mode > 2)) {
1688 FN_EXIT1(NOT_OK);
1689 return NOT_OK;
1692 if (mode != 2)
1693 /* need to modify old data */
1694 acx111_s_get_feature_config(adev, &feat.feature_options,
1695 &feat.data_flow_options);
1696 else {
1697 /* need to set a completely new value */
1698 feat.feature_options = 0;
1699 feat.data_flow_options = 0;
1702 if (mode == 0) { /* remove */
1703 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1704 CLEAR_BIT(feat.data_flow_options,
1705 cpu_to_le32(data_flow_options));
1706 } else { /* add or set */
1707 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1708 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1711 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
1712 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1713 "new: feature 0x%08X dataflow 0x%08X\n",
1714 feature_options, data_flow_options, mode,
1715 le32_to_cpu(feat.feature_options),
1716 le32_to_cpu(feat.data_flow_options));
1718 if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1719 FN_EXIT1(NOT_OK);
1720 return NOT_OK;
1723 FN_EXIT0;
1724 return OK;
1727 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1729 return acx111_s_set_feature_config(adev, f, d, 0);
1731 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1733 return acx111_s_set_feature_config(adev, f, d, 1);
1735 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1737 return acx111_s_set_feature_config(adev, f, d, 2);
1741 /***********************************************************************
1742 ** acx100_s_init_memory_pools
1744 static int
1745 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1747 acx100_ie_memblocksize_t MemoryBlockSize;
1748 acx100_ie_memconfigoption_t MemoryConfigOption;
1749 int TotalMemoryBlocks;
1750 int RxBlockNum;
1751 int TotalRxBlockSize;
1752 int TxBlockNum;
1753 int TotalTxBlockSize;
1755 FN_ENTER;
1757 /* Let's see if we can follow this:
1758 first we select our memory block size (which I think is
1759 completely arbitrary) */
1760 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1762 /* Then we alert the card to our decision of block size */
1763 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
1764 goto bad;
1767 /* We figure out how many total blocks we can create, using
1768 the block size we chose, and the beginning and ending
1769 memory pointers, i.e.: end-start/size */
1770 TotalMemoryBlocks =
1771 (le32_to_cpu(mmt->PoolEnd) -
1772 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1774 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "TotalMemoryBlocks=%u (%u bytes)\n",
1775 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1777 /* MemoryConfigOption.DMA_config bitmask:
1778 access to ACX memory is to be done:
1779 0x00080000 using PCI conf space?!
1780 0x00040000 using IO instructions?
1781 0x00000000 using memory access instructions
1782 0x00020000 using local memory block linked list (else what?)
1783 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1785 if (IS_PCI(adev)) {
1786 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1787 /* Declare start of the Rx host pool */
1788 MemoryConfigOption.pRxHostDesc =
1789 cpu2acx(adev->rxhostdesc_startphy);
1790 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "pRxHostDesc 0x%08X, "
1791 "rxhostdesc_startphy 0x%lX\n",
1792 acx2cpu(MemoryConfigOption.pRxHostDesc),
1793 (long)adev->rxhostdesc_startphy);
1794 } else {
1795 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1798 /* 50% of the allotment of memory blocks go to tx descriptors */
1799 TxBlockNum = TotalMemoryBlocks / 2;
1800 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1802 /* and 50% go to the rx descriptors */
1803 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1804 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1806 /* size of the tx and rx descriptor queues */
1807 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1808 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1809 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "TxBlockNum %u RxBlockNum %u "
1810 "TotalTxBlockSize %u TotalTxBlockSize %u\n",
1811 TxBlockNum, RxBlockNum, TotalTxBlockSize, TotalRxBlockSize);
1814 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1815 MemoryConfigOption.rx_mem =
1816 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1818 /* align the rx descriptor queue to units of 0x20
1819 * and offset it by the tx descriptor queue */
1820 MemoryConfigOption.tx_mem =
1821 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
1822 0x1f) & ~0x1f);
1823 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "rx_mem %08X rx_mem %08X\n",
1824 MemoryConfigOption.tx_mem, MemoryConfigOption.rx_mem);
1826 /* alert the device to our decision */
1827 if (OK !=
1828 acx_s_configure(adev, &MemoryConfigOption,
1829 ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
1830 goto bad;
1833 /* and tell the device to kick it into gear */
1834 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
1835 goto bad;
1837 FN_EXIT1(OK);
1838 return OK;
1839 bad:
1840 FN_EXIT1(NOT_OK);
1841 return NOT_OK;
1845 /***********************************************************************
1846 ** acx100_s_create_dma_regions
1848 ** Note that this fn messes up heavily with hardware, but we cannot
1849 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1851 /* OLD CODE? - let's rewrite it! */
1852 static int acx100_s_create_dma_regions(acx_device_t * adev)
1854 acx100_ie_queueconfig_t queueconf;
1855 acx_ie_memmap_t memmap;
1856 int res = NOT_OK;
1857 u32 tx_queue_start, rx_queue_start;
1859 FN_ENTER;
1861 /* read out the acx100 physical start address for the queues */
1862 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1863 goto fail;
1866 tx_queue_start = le32_to_cpu(memmap.QueueStart);
1867 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
1869 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "initializing Queue Indicator\n");
1871 memset(&queueconf, 0, sizeof(queueconf));
1873 /* Not needed for PCI, so we can avoid setting them altogether */
1874 if (IS_USB(adev)) {
1875 queueconf.NumTxDesc = USB_TX_CNT;
1876 queueconf.NumRxDesc = USB_RX_CNT;
1879 /* calculate size of queues */
1880 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
1881 RX_CNT * sizeof(rxdesc_t) + 8);
1882 queueconf.NumTxQueues = 1; /* number of tx queues */
1883 /* sets the beginning of the tx descriptor queue */
1884 queueconf.TxQueueStart = memmap.QueueStart;
1885 /* done by memset: queueconf.TxQueuePri = 0; */
1886 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
1887 queueconf.QueueOptions = 1; /* auto reset descriptor */
1888 /* sets the end of the rx descriptor queue */
1889 queueconf.QueueEnd =
1890 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
1892 /* sets the beginning of the next queue */
1893 queueconf.HostQueueEnd =
1894 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
1895 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
1896 goto fail;
1899 if (IS_PCI(adev)) {
1900 /* sets the beginning of the rx descriptor queue, after the tx descrs */
1901 if (OK != acxpci_s_create_hostdesc_queues(adev))
1902 goto fail;
1903 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
1906 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1907 goto fail;
1910 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
1911 0x1f) & ~0x1f);
1913 if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1914 goto fail;
1917 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
1918 goto fail;
1921 res = OK;
1922 goto end;
1924 fail:
1925 acx_s_mwait(1000); /* ? */
1926 if (IS_PCI(adev))
1927 acxpci_free_desc_queues(adev);
1928 end:
1929 FN_EXIT1(res);
1930 return res;
1934 /***********************************************************************
1935 ** acx111_s_create_dma_regions
1937 ** Note that this fn messes heavily with hardware, but we cannot
1938 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1940 #define ACX111_PERCENT(percent) ((percent)/5)
1942 static int acx111_s_create_dma_regions(acx_device_t * adev)
1944 struct acx111_ie_memoryconfig memconf;
1945 struct acx111_ie_queueconfig queueconf;
1946 u32 tx_queue_start, rx_queue_start;
1948 FN_ENTER;
1950 /* Calculate memory positions and queue sizes */
1952 /* Set up our host descriptor pool + data pool */
1953 if (IS_PCI(adev)) {
1954 if (OK != acxpci_s_create_hostdesc_queues(adev))
1955 goto fail;
1958 memset(&memconf, 0, sizeof(memconf));
1959 /* the number of STAs (STA contexts) to support
1960 ** NB: was set to 1 and everything seemed to work nevertheless... */
1961 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
1962 /* specify the memory block size. Default is 256 */
1963 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
1964 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
1965 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
1966 /* set the count of our queues
1967 ** NB: struct acx111_ie_memoryconfig shall be modified
1968 ** if we ever will switch to more than one rx and/or tx queue */
1969 memconf.count_rx_queues = 1;
1970 memconf.count_tx_queues = 1;
1971 /* 0 == Busmaster Indirect Memory Organization, which is what we want
1972 * (using linked host descs with their allocated mem).
1973 * 2 == Generic Bus Slave */
1974 /* done by memset: memconf.options = 0; */
1975 /* let's use 25% for fragmentations and 75% for frame transfers
1976 * (specified in units of 5%) */
1977 memconf.fragmentation = ACX111_PERCENT(75);
1978 /* Rx descriptor queue config */
1979 memconf.rx_queue1_count_descs = RX_CNT;
1980 memconf.rx_queue1_type = 7; /* must be set to 7 */
1981 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
1982 if (IS_PCI(adev)) {
1983 memconf.rx_queue1_host_rx_start =
1984 cpu2acx(adev->rxhostdesc_startphy);
1986 /* Tx descriptor queue config */
1987 memconf.tx_queue1_count_descs = TX_CNT;
1988 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
1990 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
1991 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
1992 ** But it is actually correct wrt IE numbers.
1993 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
1994 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
1995 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
1996 if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
1997 goto fail;
2000 acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
2002 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2003 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2005 acx_log(LOG_DEBUG, L_INIT, "dump queue head (from card):\n"
2006 "len: %u\n"
2007 "tx_memory_block_address: %X\n"
2008 "rx_memory_block_address: %X\n"
2009 "tx1_queue address: %X\n"
2010 "rx1_queue address: %X\n",
2011 le16_to_cpu(queueconf.len),
2012 le32_to_cpu(queueconf.tx_memory_block_address),
2013 le32_to_cpu(queueconf.rx_memory_block_address),
2014 tx_queue_start, rx_queue_start);
2016 if (IS_PCI(adev))
2017 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2019 FN_EXIT1(OK);
2020 return OK;
2021 fail:
2022 if (IS_PCI(adev))
2023 acxpci_free_desc_queues(adev);
2025 FN_EXIT1(NOT_OK);
2026 return NOT_OK;
2030 /***********************************************************************
2032 static void acx_s_initialize_rx_config(acx_device_t * adev)
2034 struct {
2035 u16 id;
2036 u16 len;
2037 u16 rx_cfg1;
2038 u16 rx_cfg2;
2039 } __attribute__ ((packed)) cfg;
2040 switch (adev->mode) {
2041 case ACX_MODE_MONITOR:
2042 adev->rx_config_1 = (u16) (0
2043 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2044 /* | RX_CFG1_FILTER_SSID */
2045 /* | RX_CFG1_FILTER_BCAST */
2046 /* | RX_CFG1_RCV_MC_ADDR1 */
2047 /* | RX_CFG1_RCV_MC_ADDR0 */
2048 /* | RX_CFG1_FILTER_ALL_MULTI */
2049 /* | RX_CFG1_FILTER_BSSID */
2050 /* | RX_CFG1_FILTER_MAC */
2051 | RX_CFG1_RCV_PROMISCUOUS
2052 | RX_CFG1_INCLUDE_FCS
2053 /* | RX_CFG1_INCLUDE_PHY_HDR */
2055 adev->rx_config_2 = (u16) (0
2056 | RX_CFG2_RCV_ASSOC_REQ
2057 | RX_CFG2_RCV_AUTH_FRAMES
2058 | RX_CFG2_RCV_BEACON_FRAMES
2059 | RX_CFG2_RCV_CONTENTION_FREE
2060 | RX_CFG2_RCV_CTRL_FRAMES
2061 | RX_CFG2_RCV_DATA_FRAMES
2062 | RX_CFG2_RCV_BROKEN_FRAMES
2063 | RX_CFG2_RCV_MGMT_FRAMES
2064 | RX_CFG2_RCV_PROBE_REQ
2065 | RX_CFG2_RCV_PROBE_RESP
2066 | RX_CFG2_RCV_ACK_FRAMES
2067 | RX_CFG2_RCV_OTHER);
2068 break;
2069 default:
2070 adev->rx_config_1 = (u16) (0
2071 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2072 /* | RX_CFG1_FILTER_SSID */
2073 /* | RX_CFG1_FILTER_BCAST */
2074 /* | RX_CFG1_RCV_MC_ADDR1 */
2075 /* | RX_CFG1_RCV_MC_ADDR0 */
2076 /* | RX_CFG1_FILTER_ALL_MULTI */
2077 /* | RX_CFG1_FILTER_BSSID */
2078 /* | RX_CFG1_FILTER_MAC */
2079 | RX_CFG1_RCV_PROMISCUOUS
2080 /* | RX_CFG1_INCLUDE_FCS */
2081 /* | RX_CFG1_INCLUDE_PHY_HDR */
2083 adev->rx_config_2 = (u16) (0
2084 | RX_CFG2_RCV_ASSOC_REQ
2085 | RX_CFG2_RCV_AUTH_FRAMES
2086 | RX_CFG2_RCV_BEACON_FRAMES
2087 | RX_CFG2_RCV_CONTENTION_FREE
2088 | RX_CFG2_RCV_CTRL_FRAMES
2089 | RX_CFG2_RCV_DATA_FRAMES
2090 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2091 | RX_CFG2_RCV_MGMT_FRAMES
2092 | RX_CFG2_RCV_PROBE_REQ
2093 | RX_CFG2_RCV_PROBE_RESP
2094 | RX_CFG2_RCV_ACK_FRAMES
2095 | RX_CFG2_RCV_OTHER);
2096 break;
2098 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2100 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2101 || (adev->firmware_numver >= 0x02000000))
2102 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2103 else
2104 adev->phy_header_len = 0;
2106 acx_log(LOG_DEBUG, L_INIT, "setting RXconfig to %04X:%04X\n",
2107 adev->rx_config_1, adev->rx_config_2);
2109 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2110 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2111 acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
2115 /***********************************************************************
2116 ** FIXME: this should be solved in a general way for all radio types
2117 ** by decoding the radio firmware module,
2118 ** since it probably has some standard structure describing how to
2119 ** set the power level of the radio module which it controls.
2120 ** Or maybe not, since the radio module probably has a function interface
2121 ** instead which then manages Tx level programming :-\
2123 ** Obvious
2125 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2127 struct acx111_ie_tx_level tx_level;
2129 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2130 * 1 (30mW) [15dBm]
2131 * 2 (10mW) [10dBm]
2132 * For now, just assume all other acx111 cards have the same.
2133 * FIXME: Ideally we would query it here, but we first need a
2134 * standard way to query individual configoptions easily.
2135 * Well, now we have proper cfgopt txpower variables, but this still
2136 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2137 if (level_dbm <= 12) {
2138 tx_level.level = 2; /* 10 dBm */
2139 adev->tx_level_dbm = 10;
2140 } else {
2141 tx_level.level = 1; /* 15 dBm */
2142 adev->tx_level_dbm = 15;
2144 if (level_dbm != adev->tx_level_dbm)
2145 acx_log(LOG_WARNING, L_INIT, "acx111 firmware has specific "
2146 "power levels only: adjusted %d dBm to %d dBm!\n",
2147 level_dbm, adev->tx_level_dbm);
2149 return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
2152 static int acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
2154 if (IS_ACX111(adev)) {
2155 return acx111_s_set_tx_level(adev, level_dbm);
2157 if (IS_PCI(adev)) {
2158 return acx100pci_s_set_tx_level(adev, level_dbm);
2161 return OK;
2165 /***********************************************************************
2166 ** acx_s_set_defaults
2168 void acx_s_set_defaults(acx_device_t * adev)
2170 struct ieee80211_conf *conf = &adev->ieee->conf;
2171 unsigned long flags;
2172 u16 default_irq_mask = (IS_ACX111(adev)) ?
2173 ACX111_DEFAULT_IRQ_MASK :
2174 ACX100_DEFAULT_IRQ_MASK;
2176 FN_ENTER;
2178 acx_lock(adev, flags);
2179 /* do it before getting settings, prevent bogus channel 0 warning */
2180 adev->channel = 1;
2182 /* query some settings from the card.
2183 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2184 * query is REQUIRED, otherwise the card won't work correctly! */
2185 adev->get_mask =
2186 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2187 GETSET_REG_DOMAIN;
2188 /* Only ACX100 supports ED and CCA */
2189 if (IS_ACX100(adev))
2190 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2192 acx_unlock(adev, flags);
2194 acx_s_update_card_settings(adev);
2196 acx_lock(adev, flags);
2198 /* set our global interrupt mask */
2199 if (IS_PCI(adev))
2200 adev->irq_mask = default_irq_mask;
2202 adev->led_power = 1; /* LED is active on startup */
2203 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2204 adev->brange_time_last_state_change = jiffies;
2206 /* copy the MAC address we just got from the card
2207 * into our MAC address used during current 802.11 session */
2208 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
2209 MAC_BCAST(adev->ap);
2211 adev->essid_len =
2212 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2213 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2214 adev->essid_active = 1;
2216 /* we have a nick field to waste, so why not abuse it
2217 * to announce the driver version? ;-) */
2218 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2220 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2221 /* first regulatory domain entry in EEPROM == default reg. domain */
2222 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2225 /* 0xffff would be better, but then we won't get a "scan complete"
2226 * interrupt, so our current infrastructure will fail: */
2227 adev->scan_count = 1;
2228 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2229 adev->scan_duration = 100;
2230 adev->scan_probe_delay = 200;
2231 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2232 adev->scan_rate = ACX_SCAN_RATE_1;
2235 adev->mode = ACX_MODE_2_STA;
2236 adev->listen_interval = 100;
2237 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2238 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2240 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2242 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2243 adev->frag_threshold = 2346;
2245 /* use standard default values for retry limits */
2246 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2247 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2249 adev->preamble_mode = 2; /* auto */
2250 adev->fallback_threshold = 3;
2251 adev->stepup_threshold = 10;
2252 adev->rate_bcast = RATE111_1;
2253 adev->rate_bcast100 = RATE100_1;
2254 adev->rate_basic = RATE111_1 | RATE111_2;
2255 adev->rate_auto = 1;
2256 if (IS_ACX111(adev)) {
2257 adev->rate_oper = RATE111_ALL;
2258 } else {
2259 adev->rate_oper = RATE111_ACX100_COMPAT;
2262 /* Supported Rates element - the rates here are given in units of
2263 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2264 acx_l_update_ratevector(adev);
2266 /* set some more defaults */
2267 if (IS_ACX111(adev)) {
2268 /* 30mW (15dBm) is default, at least in my acx111 card: */
2269 adev->tx_level_dbm = 15;
2270 conf->power_level = adev->tx_level_dbm;
2271 acx_unlock(adev, flags);
2272 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2273 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2274 acx_lock(adev, flags);
2275 } else {
2276 /* don't use max. level, since it might be dangerous
2277 * (e.g. WRT54G people experience
2278 * excessive Tx power damage!) */
2279 adev->tx_level_dbm = 18;
2280 conf->power_level = adev->tx_level_dbm;
2281 acx_unlock(adev, flags);
2282 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2283 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2284 acx_lock(adev, flags);
2287 /* adev->tx_level_auto = 1; */
2288 if (IS_ACX111(adev)) {
2289 /* start with sensitivity level 1 out of 3: */
2290 adev->sensitivity = 1;
2293 /* #define ENABLE_POWER_SAVE */
2294 #ifdef ENABLE_POWER_SAVE
2295 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2296 adev->ps_listen_interval = 1;
2297 adev->ps_options =
2298 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2299 adev->ps_hangover_period = 30;
2300 adev->ps_enhanced_transition_time = 0;
2301 #else
2302 adev->ps_wakeup_cfg = 0;
2303 adev->ps_listen_interval = 0;
2304 adev->ps_options = 0;
2305 adev->ps_hangover_period = 0;
2306 adev->ps_enhanced_transition_time = 0;
2307 #endif
2309 /* These settings will be set in fw on ifup */
2310 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2311 /* configure card to do rate fallback when in auto rate mode */
2312 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2313 /* better re-init the antenna value we got above */
2314 | GETSET_ANTENNA
2315 #if POWER_SAVE_80211
2316 | GETSET_POWER_80211
2317 #endif
2320 acx_unlock(adev, flags);
2321 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2323 acx_s_initialize_rx_config(adev);
2325 FN_EXIT0;
2329 /***********************************************************************
2330 ** acx_l_process_rxbuf
2332 ** NB: used by USB code also
2334 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2336 struct ieee80211_hdr *hdr;
2337 u16 fc, buf_len;
2339 FN_ENTER;
2341 hdr = acx_get_wlan_hdr(adev, rxbuf);
2342 fc = le16_to_cpu(hdr->frame_control);
2343 /* length of frame from control field to first byte of FCS */
2344 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2346 acx_log_dump(LOG_DEBUG, L_DATA, hdr, buf_len, "RX: 802.11 buffer:\n");
2348 acx_l_rx(adev, rxbuf);
2349 /* Now check Rx quality level, AFTER processing packet.
2350 * I tried to figure out how to map these levels to dBm
2351 * values, but for the life of me I really didn't
2352 * manage to get it. Either these values are not meant to
2353 * be expressed in dBm, or it's some pretty complicated
2354 * calculation. */
2356 #ifdef FROM_SCAN_SOURCE_ONLY
2357 /* only consider packets originating from the MAC
2358 * address of the device that's managing our BSSID.
2359 * Disable it for now, since it removes information (levels
2360 * from different peers) and slows the Rx path. *//*
2361 if (adev->ap_client && mac_is_equal(hdr->a2, adev->ap_client->address)) {
2363 #endif
2365 FN_EXIT0;
2369 /***********************************************************************
2370 ** acx_l_handle_txrate_auto
2372 ** Theory of operation:
2373 ** client->rate_cap is a bitmask of rates client is capable of.
2374 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2375 ** It is set as a result of iwconfig rate N [auto]
2376 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2377 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2378 ** auto (0x00ff == 18Mbit or any lower value),
2379 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2381 ** client->rate_cur is a value for rate111 field in tx descriptor.
2382 ** It is always set to txrate_cfg sans zero or more most significant
2383 ** bits. This routine handles selection of new rate_cur value depending on
2384 ** outcome of last tx event.
2386 ** client->rate_100 is a precalculated rate value for acx100
2387 ** (we can do without it, but will need to calculate it on each tx).
2389 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2390 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2391 ** In theory you can implement it, but so far it is considered not worth doing.
2393 ** 22Mbit, of course, is PBCC always. */
2395 /* maps acx100 tx descr rate field to acx111 one */
2397 static u16 rate100to111(u8 r)
2399 switch (r) {
2400 case RATE100_1:
2401 return RATE111_1;
2402 case RATE100_2:
2403 return RATE111_2;
2404 case RATE100_5:
2405 case (RATE100_5 | RATE100_PBCC511):
2406 return RATE111_5;
2407 case RATE100_11:
2408 case (RATE100_11 | RATE100_PBCC511):
2409 return RATE111_11;
2410 case RATE100_22:
2411 return RATE111_22;
2412 default:
2413 printk("acx: unexpected acx100 txrate: %u! "
2414 "Please report\n", r);
2415 return RATE111_1;
2422 acx_i_start_xmit(struct ieee80211_hw *hw,
2423 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2425 acx_device_t *adev = ieee2adev(hw);
2426 tx_t *tx;
2427 void *txbuf;
2428 unsigned long flags;
2430 int txresult = NOT_OK;
2432 FN_ENTER;
2434 if (unlikely(!skb)) {
2435 /* indicate success */
2436 txresult = OK;
2437 goto out;
2440 if (unlikely(!adev)) {
2441 goto out;
2444 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2445 goto out;
2447 if (unlikely(!adev->initialized)) {
2448 goto out;
2451 acx_lock(adev, flags);
2453 tx = acx_l_alloc_tx(adev);
2455 if (unlikely(!tx)) {
2456 acx_log_ratelimited(LOG_WARNING, L_ANY, "%s: start_xmit: "
2457 "txdesc ring is full, dropping tx\n",
2458 wiphy_name(adev->ieee->wiphy));
2459 txresult = NOT_OK;
2460 goto out_unlock;
2463 txbuf = acx_l_get_txbuf(adev, tx);
2465 if (unlikely(!txbuf)) {
2466 /* Card was removed */
2467 txresult = NOT_OK;
2468 acx_l_dealloc_tx(adev, tx);
2469 goto out_unlock;
2471 memcpy(txbuf, skb->data, skb->len);
2473 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2475 txresult = OK;
2476 adev->stats.tx_packets++;
2477 adev->stats.tx_bytes += skb->len;
2479 out_unlock:
2480 acx_unlock(adev, flags);
2482 out:
2483 FN_EXIT1(txresult);
2484 return txresult;
2486 /***********************************************************************
2487 ** acx_l_update_ratevector
2489 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2491 const u8 acx_bitpos2ratebyte[] = {
2492 DOT11RATEBYTE_1,
2493 DOT11RATEBYTE_2,
2494 DOT11RATEBYTE_5_5,
2495 DOT11RATEBYTE_6_G,
2496 DOT11RATEBYTE_9_G,
2497 DOT11RATEBYTE_11,
2498 DOT11RATEBYTE_12_G,
2499 DOT11RATEBYTE_18_G,
2500 DOT11RATEBYTE_22,
2501 DOT11RATEBYTE_24_G,
2502 DOT11RATEBYTE_36_G,
2503 DOT11RATEBYTE_48_G,
2504 DOT11RATEBYTE_54_G,
2507 void acx_l_update_ratevector(acx_device_t * adev)
2509 u16 bcfg = adev->rate_basic;
2510 u16 ocfg = adev->rate_oper;
2511 u8 *supp = adev->rate_supported;
2512 const u8 *dot11 = acx_bitpos2ratebyte;
2514 FN_ENTER;
2516 while (ocfg) {
2517 if (ocfg & 1) {
2518 *supp = *dot11;
2519 if (bcfg & 1) {
2520 *supp |= 0x80;
2522 supp++;
2524 dot11++;
2525 ocfg >>= 1;
2526 bcfg >>= 1;
2528 adev->rate_supported_len = supp - adev->rate_supported;
2530 acx_log_dump(LOG_DEBUG, L_ASSOC, adev->rate_supported,
2531 adev->rate_supported_len, "new ratevector:\n");
2533 FN_EXIT0;
2536 /***********************************************************************
2537 ** acx_i_timer
2539 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2541 ** Obvious
2543 void acx_i_timer(unsigned long address)
2545 unsigned long flags;
2546 acx_device_t *adev = (acx_device_t *) address;
2548 FN_ENTER;
2550 acx_lock(adev, flags);
2552 FIXME();
2553 /* We need calibration and stats gather tasks to perform here */
2555 acx_unlock(adev, flags);
2557 FN_EXIT0;
2561 /***********************************************************************
2562 ** acx_set_timer
2564 ** Sets the 802.11 state management timer's timeout.
2566 ** Linux derived
2568 void acx_set_timer(acx_device_t * adev, int timeout_us)
2570 FN_ENTER;
2572 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_IRQ,
2573 "%s(%u ms)\n", __func__, timeout_us / 1000);
2575 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2576 acx_log(LOG_WARNING, L_ANY, "attempt to set the timer "
2577 "when the card interface is not up!\n");
2578 goto end;
2581 /* first check if the timer was already initialized, THEN modify it */
2582 if (adev->mgmt_timer.function) {
2583 mod_timer(&adev->mgmt_timer,
2584 jiffies + (timeout_us * HZ / 1000000));
2586 end:
2587 FN_EXIT0;
2590 /** acx_plcp_get_bitrate_cck
2592 ** Obvious
2594 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2596 switch (plcp) {
2597 case 0x0A:
2598 return ACX_CCK_RATE_1MB;
2599 case 0x14:
2600 return ACX_CCK_RATE_2MB;
2601 case 0x37:
2602 return ACX_CCK_RATE_5MB;
2603 case 0x6E:
2604 return ACX_CCK_RATE_11MB;
2606 return 0;
2609 /* Extract the bitrate out of an OFDM PLCP header. */
2610 /** Obvious **/
2611 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2613 switch (plcp & 0xF) {
2614 case 0xB:
2615 return ACX_OFDM_RATE_6MB;
2616 case 0xF:
2617 return ACX_OFDM_RATE_9MB;
2618 case 0xA:
2619 return ACX_OFDM_RATE_12MB;
2620 case 0xE:
2621 return ACX_OFDM_RATE_18MB;
2622 case 0x9:
2623 return ACX_OFDM_RATE_24MB;
2624 case 0xD:
2625 return ACX_OFDM_RATE_36MB;
2626 case 0x8:
2627 return ACX_OFDM_RATE_48MB;
2628 case 0xC:
2629 return ACX_OFDM_RATE_54MB;
2631 return 0;
2635 /***********************************************************************
2636 ** acx_l_rx
2638 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2639 ** buffer and feeds it to the network stack via netif_rx().
2641 ** Look to bcm43xx or p54
2643 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2646 struct ieee80211_rx_status* status = &adev->rx_status;
2647 struct ieee80211_hdr *w_hdr;
2648 struct sk_buff *skb;
2649 int buflen;
2650 FN_ENTER;
2652 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2653 acx_log_ratelimited(LOG_WARNING, L_ANY,
2654 "asked to receive a packet but interface is down??\n");
2655 goto out;
2658 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2659 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2661 * Allocate our skb
2663 skb = dev_alloc_skb(buflen + 2);
2665 if (!skb) {
2666 acx_log_ratelimited(LOG_WARNING, L_ANY,
2667 "skb allocation FAILED\n");
2668 goto out;
2671 skb_reserve(skb, 2);
2672 skb_put(skb, buflen);
2673 memcpy(skb->data, w_hdr, buflen);
2675 // memset(&status, 0, sizeof(status));
2677 status->mactime = rxbuf->time;
2678 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2679 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr);
2680 status->flag = 0;
2681 status->rate = rxbuf->phy_plcp_signal;
2682 status->antenna = 1;
2683 if (rxbuf->phy_stat_baseband & (1 << 3)) { /* Uses OFDM */
2684 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2685 } else {
2686 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2690 * FIXME: should it really be done here??
2692 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2693 adev->stats.rx_packets++;
2694 adev->stats.rx_bytes += skb->len;
2695 out:
2696 FN_EXIT0;
2701 /***********************************************************************
2702 ** acx_s_read_fw
2704 ** Loads a firmware image
2706 ** Returns:
2707 ** 0 unable to load file
2708 ** pointer to firmware success
2710 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2711 u32 * size)
2713 firmware_image_t *res;
2714 const struct firmware *fw_entry;
2716 res = NULL;
2717 acx_log(LOG_INFO, L_INIT, "requesting firmware image '%s'\n", file);
2718 if (!request_firmware(&fw_entry, file, dev)) {
2719 *size = 8;
2720 if (fw_entry->size >= 8)
2721 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2722 if (fw_entry->size != *size) {
2723 acx_log(LOG_WARNING, L_ANY,
2724 "acx: firmware size does not match "
2725 "firmware header: %d != %d, "
2726 "aborting fw upload\n",
2727 (int)fw_entry->size, (int)*size);
2728 goto release_ret;
2730 res = vmalloc(*size);
2731 if (!res) {
2732 acx_log(LOG_INFO, L_ANY, "acx: no memory for firmware "
2733 "(%u bytes)\n", *size);
2734 goto release_ret;
2736 memcpy(res, fw_entry->data, fw_entry->size);
2737 release_ret:
2738 release_firmware(fw_entry);
2739 return res;
2741 acx_log(LOG_WARNING, L_ANY, "acx: firmware image '%s' was not provided. "
2742 "Check your hotplug scripts\n", file);
2744 /* checksum will be verified in write_fw, so don't bother here */
2745 return res;
2749 /***********************************************************************
2750 ** acx_s_set_wepkey
2752 static void acx100_s_set_wepkey(acx_device_t * adev)
2754 ie_dot11WEPDefaultKey_t dk;
2755 int i;
2757 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2758 if (adev->wep_keys[i].size != 0) {
2759 acx_log(LOG_DEBUG, L_INIT, "setting WEP key: %d with "
2760 "total size: %d\n",
2761 i, (int)adev->wep_keys[i].size);
2762 dk.action = 1;
2763 dk.keySize = adev->wep_keys[i].size;
2764 dk.defaultKeyNum = i;
2765 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2766 acx_s_configure(adev, &dk,
2767 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
2772 static void acx111_s_set_wepkey(acx_device_t * adev)
2774 acx111WEPDefaultKey_t dk;
2775 int i;
2777 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2778 if (adev->wep_keys[i].size != 0) {
2779 acx_log(LOG_DEBUG, L_INIT, "setting WEP key: %d with "
2780 "total size: %d\n", i,
2781 (int)adev->wep_keys[i].size);
2782 memset(&dk, 0, sizeof(dk));
2783 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2784 dk.keySize = adev->wep_keys[i].size;
2786 /* are these two lines necessary? */
2787 dk.type = 0; /* default WEP key */
2788 dk.index = 0; /* ignored when setting default key */
2790 dk.defaultKeyNum = i;
2791 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2792 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2793 sizeof(dk));
2797 /* Obvious */
2798 static void acx_s_set_wepkey(acx_device_t * adev)
2800 if (IS_ACX111(adev))
2801 acx111_s_set_wepkey(adev);
2802 else
2803 acx100_s_set_wepkey(adev);
2807 /***********************************************************************
2808 ** acx100_s_init_wep
2810 ** FIXME: this should probably be moved into the new card settings
2811 ** management, but since we're also modifying the memory map layout here
2812 ** due to the WEP key space we want, we should take care...
2814 static int acx100_s_init_wep(acx_device_t * adev)
2816 acx100_ie_wep_options_t options;
2817 ie_dot11WEPDefaultKeyID_t dk;
2818 acx_ie_memmap_t pt;
2819 int res = NOT_OK;
2821 FN_ENTER;
2823 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2824 goto fail;
2827 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "CodeEnd:%X\n", pt.CodeEnd);
2829 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2830 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2832 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2833 goto fail;
2836 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2837 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2838 options.WEPOption = 0x00;
2840 acx_log(LOG_DEBUG, L_ASSOC, "writing WEP options\n");
2841 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
2843 acx100_s_set_wepkey(adev);
2845 if (adev->wep_keys[adev->wep_current_index].size != 0) {
2846 acx_log(LOG_DEBUG, L_ASSOC,
2847 "setting active default WEP key number: %d\n",
2848 adev->wep_current_index);
2849 dk.KeyID = adev->wep_current_index;
2850 acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
2852 /* FIXME!!! wep_key_struct is filled nowhere! But adev
2853 * is initialized to 0, and we don't REALLY need those keys either */
2854 /* for (i = 0; i < 10; i++) {
2855 if (adev->wep_key_struct[i].len != 0) {
2856 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
2857 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
2858 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
2859 wep_mgmt.Action = cpu_to_le16(1);
2860 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
2861 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
2862 adev->wep_key_struct[i].index = i;
2868 /* now retrieve the updated WEPCacheEnd pointer... */
2869 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2870 acx_log(LOG_WARNING, L_ANY,
2871 "%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
2872 wiphy_name(adev->ieee->wiphy));
2873 goto fail;
2875 /* ...and tell it to start allocating templates at that location */
2876 /* (no endianness conversion needed) */
2877 pt.PacketTemplateStart = pt.WEPCacheEnd;
2879 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2880 acx_log(LOG_WARNING, L_ANY,
2881 "%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
2882 wiphy_name(adev->ieee->wiphy));
2883 goto fail;
2885 res = OK;
2887 fail:
2888 FN_EXIT1(res);
2889 return res;
2893 static int
2894 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
2895 unsigned int cmd)
2897 int res;
2898 union {
2899 acx_template_nullframe_t null;
2900 acx_template_beacon_t b;
2901 acx_template_tim_t tim;
2902 acx_template_probereq_t preq;
2903 acx_template_proberesp_t presp;
2904 } templ;
2906 memset(&templ, 0, len);
2907 templ.null.size = cpu_to_le16(len - 2);
2908 res = acx_s_issue_cmd(adev, cmd, &templ, len);
2909 return res;
2912 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
2914 return acx_s_init_max_template_generic(adev,
2915 sizeof(acx_template_nullframe_t),
2916 ACX1xx_CMD_CONFIG_NULL_DATA);
2919 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
2921 return acx_s_init_max_template_generic(adev,
2922 sizeof(acx_template_beacon_t),
2923 ACX1xx_CMD_CONFIG_BEACON);
2926 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
2928 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
2929 ACX1xx_CMD_CONFIG_TIM);
2932 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
2934 return acx_s_init_max_template_generic(adev,
2935 sizeof(acx_template_proberesp_t),
2936 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
2939 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
2941 return acx_s_init_max_template_generic(adev,
2942 sizeof(acx_template_probereq_t),
2943 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
2946 /***********************************************************************
2947 ** acx_s_set_tim_template
2949 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
2950 ** by calling this function
2951 ** (it can be done by irq handler on each DTIM irq or by timer...)
2953 [802.11 7.3.2.6] TIM information element:
2954 - 1 EID
2955 - 1 Length
2956 1 1 DTIM Count
2957 indicates how many beacons (including this) appear before next DTIM
2958 (0=this one is a DTIM)
2959 2 1 DTIM Period
2960 number of beacons between successive DTIMs
2961 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
2962 3 1 Bitmap Control
2963 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
2964 set to 1 in TIM elements with a value of 0 in the DTIM Count field
2965 when one or more broadcast or multicast frames are buffered at the AP.
2966 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
2967 4 n Partial Virtual Bitmap
2968 Visible part of traffic-indication bitmap.
2969 Full bitmap consists of 2008 bits (251 octets) such that bit number N
2970 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
2971 in octet number N/8 where the low-order bit of each octet is bit0,
2972 and the high order bit is bit7.
2973 Each set bit in virtual bitmap corresponds to traffic buffered by AP
2974 for a specific station (with corresponding AID?).
2975 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
2976 Bitmap Offset is a number of skipped zero octets (see above).
2977 'Missing' octets at the tail are also assumed to be zero.
2978 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
2979 This means that traffic-indication bitmap is:
2980 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
2981 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
2983 static int acx_s_set_tim_template(acx_device_t * adev)
2985 /* For now, configure smallish test bitmap, all zero ("no pending data") */
2986 enum { bitmap_size = 5 };
2988 acx_template_tim_t t;
2989 int result;
2991 FN_ENTER;
2993 memset(&t, 0, sizeof(t));
2994 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
2995 t.tim_eid = WLAN_EID_TIM;
2996 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
2997 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
2998 FN_EXIT1(result);
2999 return result;
3005 #if POWER_SAVE_80211
3006 /***********************************************************************
3007 ** acx_s_set_null_data_template
3009 static int acx_s_set_null_data_template(acx_device_t * adev)
3011 struct acx_template_nullframe b;
3012 int result;
3014 FN_ENTER;
3016 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3018 b.size = cpu_to_le16(sizeof(b) - 2);
3019 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3020 b.hdr.dur = 0;
3021 MAC_BCAST(b.hdr.a1);
3022 MAC_COPY(b.hdr.a2, adev->dev_addr);
3023 MAC_COPY(b.hdr.a3, adev->bssid);
3024 b.hdr.seq = 0;
3026 result =
3027 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3029 FN_EXIT1(result);
3030 return result;
3032 #endif
3039 /***********************************************************************
3040 ** acx_s_init_packet_templates()
3042 ** NOTE: order is very important here, to have a correct memory layout!
3043 ** init templates: max Probe Request (station mode), max NULL data,
3044 ** max Beacon, max TIM, max Probe Response.
3046 static int acx_s_init_packet_templates(acx_device_t * adev)
3048 acx_ie_memmap_t mm; /* ACX100 only */
3049 int result = NOT_OK;
3051 FN_ENTER;
3053 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_INIT,
3054 "initializing max packet templates\n");
3056 if (OK != acx_s_init_max_probe_request_template(adev))
3057 goto failed;
3059 if (OK != acx_s_init_max_null_data_template(adev))
3060 goto failed;
3062 if (OK != acx_s_init_max_beacon_template(adev))
3063 goto failed;
3065 if (OK != acx_s_init_max_tim_template(adev))
3066 goto failed;
3068 if (OK != acx_s_init_max_probe_response_template(adev))
3069 goto failed;
3071 if (IS_ACX111(adev)) {
3072 /* ACX111 doesn't need the memory map magic below,
3073 * and the other templates will be set later (acx_start) */
3074 result = OK;
3075 goto success;
3078 /* ACX100 will have its TIM template set,
3079 * and we also need to update the memory map */
3081 if (OK != acx_s_set_tim_template(adev))
3082 goto failed_acx100;
3084 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
3085 "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3087 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3088 goto failed_acx100;
3090 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3091 if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3092 goto failed_acx100;
3094 result = OK;
3095 goto success;
3097 failed_acx100:
3098 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_INIT,
3099 /* "cb=0x%X\n" */
3100 "ACXMemoryMap:\n"
3101 ".CodeStart=0x%X\n"
3102 ".CodeEnd=0x%X\n"
3103 ".WEPCacheStart=0x%X\n"
3104 ".WEPCacheEnd=0x%X\n"
3105 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3106 /* len, */
3107 le32_to_cpu(mm.CodeStart),
3108 le32_to_cpu(mm.CodeEnd),
3109 le32_to_cpu(mm.WEPCacheStart),
3110 le32_to_cpu(mm.WEPCacheEnd),
3111 le32_to_cpu(mm.PacketTemplateStart),
3112 le32_to_cpu(mm.PacketTemplateEnd));
3114 failed:
3115 acx_log(LOG_WARNING, L_ANY, "%s: %s() FAILED\n",
3116 wiphy_name(adev->ieee->wiphy), __func__);
3118 success:
3119 FN_EXIT1(result);
3120 return result;
3125 /***********************************************************************
3126 ** acx_s_init_mac
3128 int acx_s_init_mac(acx_device_t * adev)
3130 int result = NOT_OK;
3132 FN_ENTER;
3134 if (IS_ACX111(adev)) {
3135 adev->ie_len = acx111_ie_len;
3136 adev->ie_len_dot11 = acx111_ie_len_dot11;
3137 } else {
3138 adev->ie_len = acx100_ie_len;
3139 adev->ie_len_dot11 = acx100_ie_len_dot11;
3142 if (IS_PCI(adev)) {
3143 adev->memblocksize = 256; /* 256 is default */
3144 /* try to load radio for both ACX100 and ACX111, since both
3145 * chips have at least some firmware versions making use of an
3146 * external radio module */
3147 acxpci_s_upload_radio(adev);
3148 } else {
3149 adev->memblocksize = 128;
3152 if (IS_ACX111(adev)) {
3153 /* for ACX111, the order is different from ACX100
3154 1. init packet templates
3155 2. create station context and create dma regions
3156 3. init wep default keys
3158 if (OK != acx_s_init_packet_templates(adev))
3159 goto fail;
3160 if (OK != acx111_s_create_dma_regions(adev)) {
3161 acx_log(LOG_WARNING, L_ANY,
3162 "%s: acx111_create_dma_regions FAILED\n",
3163 wiphy_name(adev->ieee->wiphy));
3164 goto fail;
3166 } else {
3167 if (OK != acx100_s_init_wep(adev))
3168 goto fail;
3169 if (OK != acx_s_init_packet_templates(adev))
3170 goto fail;
3171 if (OK != acx100_s_create_dma_regions(adev)) {
3172 acx_log(LOG_WARNING, L_ANY,
3173 "%s: acx100_create_dma_regions FAILED\n",
3174 wiphy_name(adev->ieee->wiphy));
3175 goto fail;
3179 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3180 result = OK;
3182 fail:
3183 if (result)
3184 acx_log(LOG_WARNING, L_ANY, "init_mac() FAILED\n");
3185 FN_EXIT1(result);
3186 return result;
3191 #if POWER_SAVE_80211
3192 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3194 /* merge both structs in a union to be able to have common code */
3195 union {
3196 acx111_ie_powersave_t acx111;
3197 acx100_ie_powersave_t acx100;
3198 } pm;
3200 /* change 802.11 power save mode settings */
3201 acx_log(LOG_DEBUG, L_INIT, "updating 802.11 power save mode settings: "
3202 "wakeup_cfg 0x%02X, listen interval %u, "
3203 "options 0x%02X, hangover period %u, "
3204 "enhanced_ps_transition_time %u\n",
3205 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3206 adev->ps_options, adev->ps_hangover_period,
3207 adev->ps_enhanced_transition_time);
3208 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3209 acx_log(LOG_DEBUG, L_INIT, "Previous PS mode settings: "
3210 "wakeup_cfg 0x%02X, "
3211 "listen interval %u, options 0x%02X, "
3212 "hangover period %u, "
3213 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3214 pm.acx111.wakeup_cfg,
3215 pm.acx111.listen_interval,
3216 pm.acx111.options,
3217 pm.acx111.hangover_period,
3218 IS_ACX111(adev) ?
3219 pm.acx111.enhanced_ps_transition_time
3220 : pm.acx100.enhanced_ps_transition_time,
3221 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3222 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3223 pm.acx111.listen_interval = adev->ps_listen_interval;
3224 pm.acx111.options = adev->ps_options;
3225 pm.acx111.hangover_period = adev->ps_hangover_period;
3226 if (IS_ACX111(adev)) {
3227 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3228 pm.acx111.enhanced_ps_transition_time =
3229 cpu_to_le32(adev->ps_enhanced_transition_time);
3230 } else {
3231 pm.acx100.enhanced_ps_transition_time =
3232 cpu_to_le16(adev->ps_enhanced_transition_time);
3234 acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT);
3235 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3236 acx_log(LOG_DEBUG, L_INIT, "wakeup_cfg: 0x%02X\n",
3237 pm.acx111.wakeup_cfg);
3238 acx_s_mwait(40);
3239 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3240 acx_log(LOG_DEBUG, L_INIT, "wakeup_cfg: 0x%02X\n",
3241 pm.acx111.wakeup_cfg);
3242 acx_log(LOG_DEBUG, L_INIT, "power save mode change %s\n",
3243 (pm.acx111.wakeup_cfg & PS_CFG_PENDING) ?
3244 "FAILED" : "was successful");
3245 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3246 * that power save mode change was successful. */
3247 /* FIXME: we shouldn't trigger a scan immediately after
3248 * fiddling with power save mode (since the firmware is sending
3249 * a NULL frame then). */
3251 #endif
3254 /***********************************************************************
3255 ** acx_s_update_card_settings
3257 ** Applies accumulated changes in various adev->xxxx members
3258 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3259 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3261 void acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
3263 unsigned mask;
3265 unsigned int i;
3267 for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
3268 if (acx_reg_domain_ids[i] == adev->reg_dom_id)
3269 break;
3271 if (sizeof(acx_reg_domain_ids) == i) {
3272 acx_log(LOG_WARNING, L_INIT,
3273 "Invalid or unsupported regulatory domain"
3274 " 0x%02X specified, falling back to FCC (USA)!"
3275 " Please report if this sounds fishy!\n",
3276 adev->reg_dom_id);
3277 i = 0;
3278 adev->reg_dom_id = acx_reg_domain_ids[i];
3280 /* since there was a mismatch, we need to force updating */
3281 do_set = 1;
3284 if (do_set) {
3285 acx_ie_generic_t dom;
3286 dom.m.bytes[0] = adev->reg_dom_id;
3287 acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3290 adev->reg_dom_chanmask = reg_domain_channel_masks[i];
3292 mask = (1 << (adev->channel - 1));
3295 * Check our channels wrt the current regulatory domain
3297 if (adev->reg_dom_chanmask & mask)
3298 return;
3301 * Hmm nope, need to adjust channels!
3304 mask = 1;
3305 for (i = 1; i <= 14; i++) {
3306 if (!(adev->reg_dom_chanmask & mask)) {
3307 mask <<= 1;
3308 continue;
3310 acx_log(LOG_INFO, L_ANY, "%s: adjusting selected channel "
3311 "from %d to %d due to new regulatory domain\n",
3312 wiphy_name(adev->ieee->wiphy), adev->channel, i);
3313 adev->channel = i;
3314 break;
3318 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3320 u32 feature1, feature2;
3322 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3323 acx_log(LOG_WARNING, L_ANY,
3324 "%s: invalid sensitivity setting (1..3), "
3325 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3326 adev->sensitivity = 1;
3328 acx111_s_get_feature_config(adev, &feature1, &feature2);
3329 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3330 if (adev->sensitivity > 1)
3331 SET_BIT(feature1, FEATURE1_LOW_RX);
3332 if (adev->sensitivity > 2)
3333 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3334 acx111_s_feature_set(adev, feature1, feature2);
3338 void acx_s_update_card_settings(acx_device_t *adev)
3340 unsigned long flags;
3341 unsigned int start_scan = 0;
3342 int i;
3344 FN_ENTER;
3346 acx_log(LOG_DEBUG, L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3347 adev->get_mask, adev->set_mask);
3349 /* Track dependencies betweed various settings */
3351 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3352 acx_log(LOG_DEBUG, L_INIT,
3353 "important setting has been changed. "
3354 "Need to update packet templates, too\n");
3355 SET_BIT(adev->set_mask, SET_TEMPLATES);
3357 if (adev->set_mask & GETSET_CHANNEL) {
3358 /* This will actually tune RX/TX to the channel */
3359 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3360 switch (adev->mode) {
3361 case ACX_MODE_0_ADHOC:
3362 case ACX_MODE_3_AP:
3363 /* Beacons contain channel# - update them */
3364 SET_BIT(adev->set_mask, SET_TEMPLATES);
3367 switch (adev->mode) {
3368 case ACX_MODE_0_ADHOC:
3369 case ACX_MODE_2_STA:
3370 start_scan = 1;
3374 /* Apply settings */
3377 if (adev->get_mask & GETSET_STATION_ID) {
3378 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3379 const u8 *paddr;
3381 acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3382 paddr = &stationID[4];
3383 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3384 for (i = 0; i < ETH_ALEN; i++) {
3385 /* we copy the MAC address (reversed in
3386 * the card) to the netdevice's MAC
3387 * address, and on ifup it will be
3388 * copied into iwadev->dev_addr */
3389 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3391 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3392 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3395 if (adev->get_mask & GETSET_SENSITIVITY) {
3396 if ((RADIO_RFMD_11 == adev->radio_type)
3397 || (RADIO_MAXIM_0D == adev->radio_type)
3398 || (RADIO_RALINK_15 == adev->radio_type)) {
3399 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3400 } else {
3401 acx_log(LOG_WARNING, L_INIT,
3402 "don't know how to get sensitivity "
3403 "for radio type 0x%02X\n", adev->radio_type);
3404 adev->sensitivity = 0;
3406 acx_log(LOG_DEBUG, L_INIT, "got sensitivity value %u\n",
3407 adev->sensitivity);
3409 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3412 if (adev->get_mask & GETSET_ANTENNA) {
3413 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3415 memset(antenna, 0, sizeof(antenna));
3416 acx_s_interrogate(adev, antenna,
3417 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3418 adev->antenna = antenna[4];
3419 acx_log(LOG_INFO, L_INIT, "got antenna value 0x%02X\n",
3420 adev->antenna);
3421 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3424 if (adev->get_mask & GETSET_ED_THRESH) {
3425 if (IS_ACX100(adev)) {
3426 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3428 memset(ed_threshold, 0, sizeof(ed_threshold));
3429 acx_s_interrogate(adev, ed_threshold,
3430 ACX100_IE_DOT11_ED_THRESHOLD);
3431 adev->ed_threshold = ed_threshold[4];
3432 } else {
3433 acx_log(LOG_WARNING, L_INIT,
3434 "acx111 doesn't support ED\n");
3435 adev->ed_threshold = 0;
3437 acx_log(LOG_INFO, L_INIT,
3438 "got Energy Detect (ED) threshold %u\n",
3439 adev->ed_threshold);
3440 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3443 if (adev->get_mask & GETSET_CCA) {
3444 if (IS_ACX100(adev)) {
3445 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3447 memset(cca, 0, sizeof(adev->cca));
3448 acx_s_interrogate(adev, cca,
3449 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3450 adev->cca = cca[4];
3451 } else {
3452 acx_log(LOG_WARNING, L_INIT,
3453 "acx111 doesn't support CCA\n");
3454 adev->cca = 0;
3456 acx_log(LOG_INFO, L_INIT,
3457 "got Channel Clear Assessment (CCA) value %u\n",
3458 adev->cca);
3459 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3462 if (adev->get_mask & GETSET_REG_DOMAIN) {
3463 acx_ie_generic_t dom;
3465 acx_s_interrogate(adev, &dom,
3466 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3467 adev->reg_dom_id = dom.m.bytes[0];
3468 acx_s_set_sane_reg_domain(adev, 0);
3469 acx_log(LOG_INFO, L_INIT,
3470 "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3471 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3474 if (adev->set_mask & GETSET_STATION_ID) {
3475 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3476 u8 *paddr;
3478 paddr = &stationID[4];
3479 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3480 for (i = 0; i < ETH_ALEN; i++) {
3481 /* copy the MAC address we obtained when we noticed
3482 * that the ethernet iface's MAC changed
3483 * to the card (reversed in
3484 * the card!) */
3485 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3487 acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3488 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3491 if (adev->set_mask & SET_STA_LIST) {
3492 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3494 if (adev->set_mask & SET_RATE_FALLBACK) {
3495 u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
3497 /* configure to not do fallbacks when not in auto rate mode */
3498 rate[4] =
3499 (adev->
3500 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3501 acx_log(LOG_DEBUG, L_INIT,
3502 "updating Tx fallback to %u retries\n", rate[4]);
3503 acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK);
3504 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3506 if (adev->set_mask & GETSET_TXPOWER) {
3507 acx_log(LOG_DEBUG, L_INIT, "updating transmit power: %u dBm\n",
3508 adev->tx_level_dbm);
3509 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3510 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3513 if (adev->set_mask & GETSET_SENSITIVITY) {
3514 acx_log(LOG_DEBUG, L_INIT, "updating sensitivity value: %u\n",
3515 adev->sensitivity);
3516 switch (adev->radio_type) {
3517 case RADIO_RFMD_11:
3518 case RADIO_MAXIM_0D:
3519 case RADIO_RALINK_15:
3520 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3521 break;
3522 case RADIO_RADIA_16:
3523 case RADIO_UNKNOWN_17:
3524 acx111_s_sens_radio_16_17(adev);
3525 break;
3526 default:
3527 acx_log(LOG_WARNING, L_INIT,
3528 "don't know how to modify sensitivity "
3529 "for radio type 0x%02X\n", adev->radio_type);
3531 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3534 if (adev->set_mask & GETSET_ANTENNA) {
3535 /* antenna */
3536 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3538 memset(antenna, 0, sizeof(antenna));
3539 antenna[4] = adev->antenna;
3540 acx_log(LOG_DEBUG, L_INIT, "updating antenna value: 0x%02X\n",
3541 adev->antenna);
3542 acx_s_configure(adev, &antenna,
3543 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3544 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3547 if (adev->set_mask & GETSET_ED_THRESH) {
3548 /* ed_threshold */
3549 acx_log(LOG_INFO, L_INIT,
3550 "updating Energy Detect (ED) threshold: %u\n",
3551 adev->ed_threshold);
3552 if (IS_ACX100(adev)) {
3553 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3555 memset(ed_threshold, 0, sizeof(ed_threshold));
3556 ed_threshold[4] = adev->ed_threshold;
3557 acx_s_configure(adev, &ed_threshold,
3558 ACX100_IE_DOT11_ED_THRESHOLD);
3559 } else
3560 acx_log(LOG_WARNING, L_INIT,
3561 "acx111 doesn't support ED!\n");
3562 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3565 if (adev->set_mask & GETSET_CCA) {
3566 /* CCA value */
3567 acx_log(LOG_DEBUG, L_INIT,
3568 "updating Channel Clear Assessment (CCA) value: "
3569 "0x%02X\n", adev->cca);
3570 if (IS_ACX100(adev)) {
3571 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3573 memset(cca, 0, sizeof(cca));
3574 cca[4] = adev->cca;
3575 acx_s_configure(adev, &cca,
3576 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3577 } else
3578 acx_log(LOG_WARNING, L_INIT,
3579 "acx111 doesn't support CCA!\n");
3580 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3583 if (adev->set_mask & GETSET_LED_POWER) {
3584 /* Enable Tx */
3585 acx_log(LOG_INFO, L_INIT,
3586 "updating power LED status: %u\n", adev->led_power);
3588 acx_lock(adev, flags); /* acxpci_l_power_led expects that the lock is already taken! */
3589 if (IS_PCI(adev))
3590 acxpci_l_power_led(adev, adev->led_power);
3591 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3592 acx_unlock(adev, flags);
3595 if (adev->set_mask & GETSET_POWER_80211) {
3596 #if POWER_SAVE_80211
3597 acx_s_update_80211_powersave_mode(adev);
3598 #endif
3599 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3602 if (adev->set_mask & GETSET_CHANNEL) {
3603 /* channel */
3604 acx_log(LOG_INFO, L_INIT, "updating channel to: %u\n",
3605 adev->channel);
3606 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3609 if (adev->set_mask & GETSET_TX) {
3610 /* set Tx */
3611 acx_log(LOG_INFO, L_INIT, "updating: %s Tx\n",
3612 adev->tx_disabled ? "disable" : "enable");
3613 if (adev->tx_disabled)
3614 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3615 else {
3616 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3617 &adev->channel, 1);
3618 FIXME();
3619 /* This needs to be keyed on WEP? */
3620 /* acx111_s_feature_on(adev, 0,
3621 FEATURE2_NO_TXCRYPT |
3622 FEATURE2_SNIFFER); */
3623 acx_wake_queue(adev->ieee, NULL);
3625 CLEAR_BIT(adev->set_mask, GETSET_TX);
3628 if (adev->set_mask & GETSET_RX) {
3629 /* Enable Rx */
3630 acx_log(LOG_INFO, L_INIT,
3631 "updating: enable Rx on channel: %u\n", adev->channel);
3632 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3633 CLEAR_BIT(adev->set_mask, GETSET_RX);
3636 if (adev->set_mask & GETSET_RETRY) {
3637 u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
3638 u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
3640 acx_log(LOG_INFO, L_INIT,
3641 "updating short retry limit: %u, "
3642 "long retry limit: %u\n",
3643 adev->short_retry, adev->long_retry);
3644 short_retry[0x4] = adev->short_retry;
3645 long_retry[0x4] = adev->long_retry;
3646 acx_s_configure(adev, &short_retry,
3647 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
3648 acx_s_configure(adev, &long_retry,
3649 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
3650 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3653 if (adev->set_mask & SET_MSDU_LIFETIME) {
3654 u8 xmt_msdu_lifetime[4 +
3655 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3657 acx_log(LOG_DEBUG, L_INIT, "updating tx MSDU lifetime: %u\n",
3658 adev->msdu_lifetime);
3659 *(u32 *) & xmt_msdu_lifetime[4] =
3660 cpu_to_le32((u32) adev->msdu_lifetime);
3661 acx_s_configure(adev, &xmt_msdu_lifetime,
3662 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
3663 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3666 if (adev->set_mask & GETSET_REG_DOMAIN) {
3667 acx_log(LOG_INFO, L_INIT,
3668 "updating regulatory domain: 0x%02X\n",
3669 adev->reg_dom_id);
3670 acx_s_set_sane_reg_domain(adev, 1);
3671 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3673 if (adev->set_mask & GETSET_MODE ) {
3674 acx111_s_feature_on(adev, 0,
3675 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3676 switch (adev->mode) {
3677 case ACX_MODE_3_AP:
3678 adev->aid = 0;
3679 //acx111_s_feature_off(adev, 0,
3680 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3681 MAC_COPY(adev->bssid, adev->dev_addr);
3682 acx_s_cmd_join_bssid(adev, adev->dev_addr);
3683 break;
3684 case ACX_MODE_MONITOR:
3685 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3686 break;
3687 case ACX_MODE_0_ADHOC:
3688 case ACX_MODE_2_STA:
3689 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3690 break;
3691 default:
3692 break;
3694 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3696 if (adev->set_mask & SET_TEMPLATES) {
3697 switch (adev->mode)
3699 case ACX_MODE_3_AP:
3700 acx_s_set_tim_template(adev);
3701 break;
3702 default:
3703 break;
3705 if (adev->beacon_cache)
3707 acx_s_set_beacon_template(adev, adev->beacon_cache);
3708 dev_kfree_skb(adev->beacon_cache);
3709 adev->beacon_cache = NULL;
3711 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3714 if (adev->set_mask & SET_RXCONFIG) {
3715 acx_s_initialize_rx_config(adev);
3716 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3719 if (adev->set_mask & GETSET_RESCAN) {
3720 /* switch (adev->mode) {
3721 case ACX_MODE_0_ADHOC:
3722 case ACX_MODE_2_STA:
3723 start_scan = 1;
3724 break;
3726 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3729 if (adev->set_mask & GETSET_WEP) {
3730 /* encode */
3732 ie_dot11WEPDefaultKeyID_t dkey;
3733 #ifdef DEBUG_WEP
3734 struct {
3735 u16 type;
3736 u16 len;
3737 u8 val;
3738 } __attribute__ ((packed)) keyindic;
3739 #endif
3740 acx_log(LOG_DEBUG, L_INIT, "updating WEP key settings\n");
3742 acx_s_set_wepkey(adev);
3743 if (adev->wep_enabled) {
3744 dkey.KeyID = adev->wep_current_index;
3745 acx_log(LOG_DEBUG, L_INIT,
3746 "setting WEP key %u as default\n",
3747 dkey.KeyID);
3748 acx_s_configure(adev, &dkey,
3749 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
3750 #ifdef DEBUG_WEP
3751 keyindic.val = 3;
3752 acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
3753 #endif
3756 // start_scan = 1;
3757 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3760 if (adev->set_mask & SET_WEP_OPTIONS) {
3761 acx100_ie_wep_options_t options;
3763 if (IS_ACX111(adev)) {
3764 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
3765 "setting WEP Options for acx111 "
3766 "is not supported\n");
3767 } else {
3768 acx_log(LOG_DEBUG, L_INIT, "setting WEP Options\n");
3770 /* let's choose maximum setting: 4 default keys,
3771 * plus 10 other keys: */
3772 options.NumKeys =
3773 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3774 /* don't decrypt default key only,
3775 * don't override decryption: */
3776 options.WEPOption = 0;
3777 if (adev->mode == ACX_MODE_3_AP) {
3778 /* don't decrypt default key only,
3779 * override decryption mechanism: */
3780 options.WEPOption = 2;
3783 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3785 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3789 /* debug, rate, and nick don't need any handling */
3790 /* what about sniffing mode?? */
3792 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3793 adev->get_mask, adev->set_mask);
3795 /* end: */
3796 FN_EXIT0;
3799 #if 0
3800 /***********************************************************************
3801 ** acx_e_after_interrupt_task
3803 static int acx_s_recalib_radio(acx_device_t * adev)
3805 if (IS_ACX111(adev)) {
3806 acx111_cmd_radiocalib_t cal;
3808 /* automatic recalibration, choose all methods: */
3809 cal.methods = cpu_to_le32(0x8000000f);
3810 /* automatic recalibration every 60 seconds (value in TUs)
3811 * I wonder what the firmware default here is? */
3812 cal.interval = cpu_to_le32(58594);
3813 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3814 &cal, sizeof(cal),
3815 CMD_TIMEOUT_MS(100));
3816 } else {
3817 /* On ACX100, we need to recalibrate the radio
3818 * by issuing a GETSET_TX|GETSET_RX */
3819 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3820 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3821 (OK ==
3822 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3823 &adev->channel, 1))
3824 && (OK ==
3825 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3826 &adev->channel, 1)))
3827 return OK;
3828 return NOT_OK;
3831 #endif // if 0
3832 #if 0
3833 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3835 int res;
3837 /* this helps with ACX100 at least;
3838 * hopefully ACX111 also does a
3839 * recalibration here */
3841 /* clear flag beforehand, since we want to make sure
3842 * it's cleared; then only set it again on specific circumstances */
3843 CLEAR_BIT(adev->after_interrupt_jobs, ACX_TASKLET_CMD_RADIO_RECALIB);
3845 /* better wait a bit between recalibrations to
3846 * prevent overheating due to torturing the card
3847 * into working too long despite high temperature
3848 * (just a safety measure) */
3849 if (adev->recalib_time_last_success
3850 && time_before(jiffies, adev->recalib_time_last_success
3851 + RECALIB_PAUSE * 60 * HZ)) {
3852 if (adev->recalib_msg_ratelimit <= 4) {
3853 printk("%s: less than " STRING(RECALIB_PAUSE)
3854 " minutes since last radio recalibration, "
3855 "not recalibrating (maybe card is too hot?)\n",
3856 wiphy_name(adev->ieee->wiphy));
3857 adev->recalib_msg_ratelimit++;
3858 if (adev->recalib_msg_ratelimit == 5)
3859 printk("disabling above message until next recalib\n");
3861 return;
3864 adev->recalib_msg_ratelimit = 0;
3866 /* note that commands sometimes fail (card busy),
3867 * so only clear flag if we were fully successful */
3868 res = acx_s_recalib_radio(adev);
3869 if (res == OK) {
3870 printk("%s: successfully recalibrated radio\n",
3871 wiphy_name(adev->ieee->wiphy));
3872 adev->recalib_time_last_success = jiffies;
3873 adev->recalib_failure_count = 0;
3874 } else {
3875 /* failed: resubmit, but only limited
3876 * amount of times within some time range
3877 * to prevent endless loop */
3879 adev->recalib_time_last_success = 0; /* we failed */
3881 /* if some time passed between last
3882 * attempts, then reset failure retry counter
3883 * to be able to do next recalib attempt */
3884 if (time_after
3885 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3886 adev->recalib_failure_count = 0;
3888 if (adev->recalib_failure_count < 5) {
3889 /* increment inside only, for speedup of outside path */
3890 adev->recalib_failure_count++;
3891 adev->recalib_time_last_attempt = jiffies;
3892 acx_schedule_task(adev,
3893 ACX_TASKLET_CMD_RADIO_RECALIB);
3897 #endif // if 0
3899 void acx_e_after_interrupt_task(struct work_struct *work)
3901 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
3902 unsigned long flags;
3904 FN_ENTER;
3906 acx_lock(adev, flags);
3908 if (!adev->after_interrupt_jobs || !adev->initialized)
3909 goto end; /* no jobs to do */
3911 /* we see lotsa tx errors */
3912 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_RADIO_RECALIB) {
3913 acx_log_ratelimited(LOG_WARNING, L_ANY,
3914 "too many TX errors??\n");
3915 // acx_s_after_interrupt_recalib(adev);
3918 /* a poor interrupt code wanted to do update_card_settings() */
3919 if (adev->after_interrupt_jobs & ACX_TASKLET_UPDATE_CARD_CFG) {
3920 if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
3921 acx_unlock(adev, flags);
3922 acx_s_update_card_settings(adev);
3923 acx_lock(adev, flags);
3925 CLEAR_BIT(adev->after_interrupt_jobs,
3926 ACX_TASKLET_UPDATE_CARD_CFG);
3929 /* 1) we detected that no Scan_Complete IRQ came from fw, or
3930 ** 2) we found too many STAs */
3931 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_STOP_SCAN) {
3932 acx_log(LOG_DEBUG, L_IRQ, "sending a stop scan cmd...\n");
3933 acx_unlock(adev, flags);
3934 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
3935 acx_lock(adev, flags);
3936 /* HACK: set the IRQ bit, since we won't get a
3937 * scan complete IRQ any more on ACX111 (works on ACX100!),
3938 * since _we_, not a fw, have stopped the scan */
3939 SET_BIT(adev->irq_status, ACX_IRQ_SCAN_COMPLETE);
3940 CLEAR_BIT(adev->after_interrupt_jobs,
3941 ACX_TASKLET_CMD_STOP_SCAN);
3944 /* either fw sent Scan_Complete or we detected that
3945 ** no Scan_Complete IRQ came from fw. Finish scanning,
3946 ** pick join partner if any */
3947 if (adev->after_interrupt_jobs & ACX_TASKLET_COMPLETE_SCAN) {
3948 /* + scan kills current join status - restore it
3949 ** (do we need it for STA?) */
3950 /* + does it happen only with active scans?
3951 ** active and passive scans? ALL scans including
3952 ** background one? */
3953 /* + was not verified that everything is restored
3954 ** (but at least we start to emit beacons again) */
3955 CLEAR_BIT(adev->after_interrupt_jobs,
3956 ACX_TASKLET_COMPLETE_SCAN);
3959 /* STA auth or assoc timed out, start over again */
3961 if (adev->after_interrupt_jobs & ACX_TASKLET_RESTART_SCAN) {
3962 acx_log(LOG_DEBUG, L_IRQ, "sending a start_scan cmd...\n");
3963 CLEAR_BIT(adev->after_interrupt_jobs,
3964 ACX_TASKLET_RESTART_SCAN);
3967 /* whee, we got positive assoc response! 8) */
3968 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_ASSOCIATE) {
3969 CLEAR_BIT(adev->after_interrupt_jobs,
3970 ACX_TASKLET_CMD_ASSOCIATE);
3972 end:
3973 if(adev->after_interrupt_jobs)
3975 acx_log(LOG_DEBUG, L_ANY, "Jobs still to be run: %x\n",
3976 adev->after_interrupt_jobs);
3977 adev->after_interrupt_jobs = 0;
3979 acx_unlock(adev, flags);
3980 // acx_sem_unlock(adev);
3981 FN_EXIT0;
3985 /***********************************************************************
3986 ** acx_schedule_task
3988 ** Schedule the call of the after_interrupt method after leaving
3989 ** the interrupt context.
3991 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
3993 if (!adev->after_interrupt_jobs)
3995 SET_BIT(adev->after_interrupt_jobs, set_flag);
3996 schedule_work(&adev->after_interrupt_task);
4001 /***********************************************************************
4003 void acx_init_task_scheduler(acx_device_t * adev)
4005 /* configure task scheduler */
4006 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4010 /***********************************************************************
4011 ** acx_s_start
4013 void acx_s_start(acx_device_t * adev)
4015 FN_ENTER;
4018 * Ok, now we do everything that can possibly be done with ioctl
4019 * calls to make sure that when it was called before the card
4020 * was up we get the changes asked for
4023 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4024 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4025 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4026 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4028 acx_log(LOG_INFO, L_INIT,
4029 "updating initial settings on iface activation\n");
4030 acx_s_update_card_settings(adev);
4032 FN_EXIT0;
4036 /***********************************************************************
4037 ** acx_update_capabilities
4038 *//*
4039 void acx_update_capabilities(acx_device_t * adev)
4041 u16 cap = 0;
4043 switch (adev->mode) {
4044 case ACX_MODE_3_AP:
4045 SET_BIT(cap, WF_MGMT_CAP_ESS);
4046 break;
4047 case ACX_MODE_0_ADHOC:
4048 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4049 break;
4050 */ /* other types of stations do not emit beacons */
4051 /* }
4053 if (adev->wep_restricted) {
4054 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4056 if (adev->cfgopt_dot11ShortPreambleOption) {
4057 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4059 if (adev->cfgopt_dot11PBCCOption) {
4060 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4062 if (adev->cfgopt_dot11ChannelAgility) {
4063 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4065 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4066 adev->capabilities, cap);
4067 adev->capabilities = cap;
4071 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4074 static void acx_s_select_opmode(acx_device_t * adev)
4076 int changed = 0;
4077 FN_ENTER;
4079 if (adev->interface.operating) {
4080 switch (adev->interface.type) {
4081 case IEEE80211_IF_TYPE_AP:
4082 if (adev->mode != ACX_MODE_3_AP)
4084 adev->mode = ACX_MODE_3_AP;
4085 changed = 1;
4087 break;
4088 case IEEE80211_IF_TYPE_IBSS:
4089 if (adev->mode != ACX_MODE_0_ADHOC)
4091 adev->mode = ACX_MODE_0_ADHOC;
4092 changed = 1;
4094 break;
4095 case IEEE80211_IF_TYPE_STA:
4096 if (adev->mode != ACX_MODE_2_STA)
4098 adev->mode = ACX_MODE_2_STA;
4099 changed = 1;
4101 break;
4102 case IEEE80211_IF_TYPE_WDS:
4103 default:
4104 if (adev->mode != ACX_MODE_OFF)
4106 adev->mode = ACX_MODE_OFF;
4107 changed = 1;
4109 break;
4111 } else {
4112 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4114 if (adev->mode != ACX_MODE_MONITOR)
4116 adev->mode = ACX_MODE_MONITOR;
4117 changed = 1;
4120 else
4122 if (adev->mode != ACX_MODE_OFF)
4124 adev->mode = ACX_MODE_OFF;
4125 changed = 1;
4129 if (changed)
4131 SET_BIT(adev->set_mask, GETSET_MODE);
4132 acx_s_update_card_settings(adev);
4133 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4136 FN_EXIT0;
4140 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4144 int acx_add_interface(struct ieee80211_hw *ieee,
4145 struct ieee80211_if_init_conf *conf)
4147 acx_device_t *adev = ieee2adev(ieee);
4148 unsigned long flags;
4149 int err = -EOPNOTSUPP;
4151 DECLARE_MAC_BUF(mac);
4153 FN_ENTER;
4154 acx_lock(adev, flags);
4156 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4157 adev->interface.monitor++;
4158 } else {
4159 if (adev->interface.operating)
4160 goto out_unlock;
4161 adev->interface.operating = 1;
4162 adev->interface.type = conf->type;
4164 // adev->mode = conf->type;
4166 acx_unlock(adev, flags);
4168 if (adev->initialized)
4169 acx_s_select_opmode(adev);
4171 acx_lock(adev, flags);
4173 err = 0;
4175 acx_log(LOG_INFO, L_ANY, "Virtual interface added "
4176 "(type: 0x%08X, MAC: %s)\n",
4177 conf->type,
4178 print_mac(mac, conf->mac_addr));
4180 out_unlock:
4181 acx_unlock(adev, flags);
4183 FN_EXIT0;
4184 return err;
4187 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4191 void acx_remove_interface(struct ieee80211_hw *hw,
4192 struct ieee80211_if_init_conf *conf)
4194 acx_device_t *adev = ieee2adev(hw);
4196 DECLARE_MAC_BUF(mac);
4198 FN_ENTER;
4200 acx_sem_lock(adev);
4201 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4202 adev->interface.monitor--;
4203 // assert(bcm->interface.monitor >= 0);
4204 } else {
4205 adev->interface.operating = 0;
4208 acx_log(LOG_INFO, L_ANY, "Removing interface: %d %d\n",
4209 adev->interface.operating, conf->type);
4210 acx_sem_unlock(adev);
4212 if (adev->initialized)
4213 acx_s_select_opmode(adev);
4214 flush_scheduled_work();
4216 acx_log(LOG_INFO, L_ANY, "Virtual interface removed "
4217 "(type: 0x%08X, MAC: %s)\n",
4218 conf->type, print_mac(mac, conf->mac_addr));
4220 FN_EXIT0;
4223 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4227 int acx_net_reset(struct ieee80211_hw *ieee)
4229 acx_device_t *adev = ieee2adev(ieee);
4230 FN_ENTER;
4231 if (IS_PCI(adev))
4232 acxpci_s_reset_dev(adev);
4233 else
4234 TODO();
4236 FN_EXIT0;
4237 return 0;
4241 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4244 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4246 int result;
4248 FN_ENTER;
4250 acx_sem_lock(adev);
4251 adev->rx_status.channel = channel;
4252 adev->rx_status.freq = freq;
4254 adev->channel = channel;
4255 /* hmm, the following code part is strange, but this is how
4256 * it was being done before... */
4257 acx_log(LOG_DEBUG, L_IOCTL, "Changing to channel %d\n", channel);
4258 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4259 result = -EINPROGRESS; /* need to call commit handler */
4261 acx_sem_unlock(adev);
4262 FN_EXIT1(result);
4263 return result;
4267 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4270 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4272 acx_device_t *adev = ieee2adev(hw);
4273 unsigned long flags;
4275 FN_ENTER;
4277 acx_lock(adev, flags);
4278 //FIXME();
4279 if (!adev->initialized) {
4280 acx_unlock(adev, flags);
4281 return 0;
4283 if (conf->beacon_int != adev->beacon_interval)
4284 adev->beacon_interval = conf->beacon_int;
4285 if (conf->channel != adev->channel) {
4286 acx_unlock(adev, flags);
4287 acx_selectchannel(adev, conf->channel,conf->freq);
4288 acx_lock(adev, flags);
4289 /* acx_schedule_task(adev,
4290 ACX_TASKLET_UPDATE_CARD_CFG
4291 */ /*+ ACX_TASKLET_RESTART_SCAN */ /*);*/
4294 if (conf->short_slot_time != adev->short_slot) {
4295 // assert(phy->type == BCM43xx_PHYTYPE_G);
4296 if (conf->short_slot_time)
4297 acx_short_slot_timing_enable(adev);
4298 else
4299 acx_short_slot_timing_disable(adev);
4300 acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4303 adev->tx_disabled = !conf->radio_enabled;
4304 /* if (conf->power_level != 0){
4305 adev->tx_level_dbm = conf->power_level;
4306 acx_s_set_tx_level(adev, adev->tx_level_dbm);
4307 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4308 //acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4311 //FIXME: This does not seem to wake up:
4312 #if 0
4313 if (conf->power_level == 0) {
4314 if (radio->enabled)
4315 bcm43xx_radio_turn_off(bcm);
4316 } else {
4317 if (!radio->enabled)
4318 bcm43xx_radio_turn_on(bcm);
4320 #endif
4322 //TODO: phymode
4323 //TODO: antennas
4324 if (adev->set_mask > 0) {
4325 acx_unlock(adev, flags);
4326 acx_s_update_card_settings(adev);
4327 acx_lock(adev, flags);
4329 acx_unlock(adev, flags);
4331 FN_EXIT0;
4332 return 0;
4336 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4340 extern int acx_config_interface(struct ieee80211_hw* ieee,
4341 struct ieee80211_vif *vif,
4342 struct ieee80211_if_conf *conf)
4344 acx_device_t *adev = ieee2adev(ieee);
4345 unsigned long flags;
4346 int err = -ENODEV;
4347 FN_ENTER;
4348 if (!adev->interface.operating)
4349 goto err_out;
4351 if (adev->initialized)
4352 acx_s_select_opmode(adev);
4354 acx_lock(adev, flags);
4356 if ((conf->type == IEEE80211_IF_TYPE_AP)
4357 && (adev->vif == vif)) {
4358 if ((conf->ssid_len > 0) && conf->ssid)
4360 adev->essid_len = conf->ssid_len;
4361 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4362 SET_BIT(adev->set_mask, SET_TEMPLATES);
4365 if (conf->beacon != 0)
4367 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4368 adev->beacon_cache = conf->beacon;
4369 SET_BIT(adev->set_mask, SET_TEMPLATES);
4372 acx_unlock(adev, flags);
4374 if (adev->set_mask != 0)
4375 acx_s_update_card_settings(adev);
4376 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4377 err = 0;
4378 err_out:
4379 FN_EXIT1(err);
4380 return err;
4384 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4388 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4389 struct ieee80211_tx_queue_stats *stats)
4391 // acx_device_t *adev = ndev2adev(net_dev);
4392 struct ieee80211_tx_queue_stats_data *data;
4393 int err = -ENODEV;
4395 FN_ENTER;
4397 // acx_lock(adev, flags);
4398 data = &(stats->data[0]);
4399 data->len = 0;
4400 data->limit = TX_CNT;
4401 data->count = 0;
4402 // acx_unlock(adev, flags);
4404 FN_EXIT0;
4405 return err;
4408 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4412 int acx_net_conf_tx(struct ieee80211_hw *hw,
4413 int queue, const struct ieee80211_tx_queue_params *params)
4415 FN_ENTER;
4416 // TODO();
4417 FN_EXIT0;
4418 return 0;
4421 static void keymac_write(acx_device_t * adev, u16 index, const u32 * addr)
4423 /* for keys 0-3 there is no associated mac address */
4424 if (index < 4)
4425 return;
4427 index -= 4;
4428 if (1) {
4429 TODO();
4431 bcm43xx_shm_write32(bcm,
4432 BCM43xx_SHM_HWMAC,
4433 index * 2,
4434 cpu_to_be32(*addr));
4435 bcm43xx_shm_write16(bcm,
4436 BCM43xx_SHM_HWMAC,
4437 (index * 2) + 1,
4438 cpu_to_be16(*((u16 *)(addr + 1))));
4440 } else {
4441 if (index < 8) {
4442 TODO(); /* Put them in the macaddress filter */
4443 } else {
4444 TODO();
4445 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4446 Keep in mind to update the count of keymacs in 0x003 */
4452 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4456 int acx_clear_keys(acx_device_t * adev)
4458 static const u32 zero_mac[2] = { 0 };
4459 unsigned int i, j, nr_keys = 54;
4460 u16 offset;
4462 /* FixMe:Check for Number of Keys available */
4464 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4466 for (i = 0; i < nr_keys; i++) {
4467 adev->key[i].enabled = 0;
4468 /* returns for i < 4 immediately */
4469 keymac_write(adev, i, zero_mac);
4471 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4472 0x100 + (i * 2), 0x0000);
4474 for (j = 0; j < 8; j++) {
4475 offset =
4476 adev->security_offset + (j * 4) +
4477 (i * ACX_SEC_KEYSIZE);
4479 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4480 offset, 0x0000);
4484 return 1;
4488 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4492 int acx_key_write(acx_device_t * adev,
4493 u16 index, u8 algorithm,
4494 const struct ieee80211_key_conf *key, const u8 * mac_addr)
4496 // struct iw_point *dwrq = &wrqu->encoding;
4497 int result;
4499 FN_ENTER;
4501 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4502 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4504 // acx_sem_lock(adev);
4506 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4507 if (key->keylen > 0) {
4508 /* if index is 0 or invalid, use default key */
4509 if (index > 3)
4510 index = (int)adev->wep_current_index;
4511 if ((algorithm == ACX_SEC_ALGO_WEP) ||
4512 (algorithm == ACX_SEC_ALGO_WEP104)) {
4513 switch(key->keylen) {
4514 case 40 / 8:
4515 /* WEP 40-bit =
4516 40-bit entered key + 24 bit IV = 64-bit */
4517 adev->wep_keys[index].size = 13;
4518 break;
4519 case 104 / 8:
4520 /* WEP 104-bit =
4521 104-bit entered key + 24-bit IV = 128-bit */
4522 adev->wep_keys[index].size = 29;
4523 break;
4524 case 128 / 8:
4525 /* WEP 128-bit =
4526 128-bit entered key + 24 bit IV = 152-bit */
4527 adev->wep_keys[index].size = 16;
4528 break;
4529 default:
4530 adev->wep_keys[index].size = 0;
4531 return -EINVAL; /* shouldn't happen */
4534 memset(adev->wep_keys[index].key, 0,
4535 sizeof(adev->wep_keys[index].key));
4536 memcpy(adev->wep_keys[index].key, key, key->keylen);
4537 } else {
4538 /* set transmit key */
4539 if (index <= 3)
4540 adev->wep_current_index = index;
4541 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4542 /* complain if we were not just setting
4543 * the key mode */
4544 // result = -EINVAL;
4545 // goto end_unlock;
4546 // }
4550 adev->wep_enabled = (algorithm == ALG_WEP);
4552 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4554 if (algorithm & IW_ENCODE_OPEN) {
4555 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4556 adev->wep_restricted = 0;
4558 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4559 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4560 adev->wep_restricted = 1;
4563 // adev->auth_alg = algorithm;
4564 /* set flag to make sure the card WEP settings get updated */
4565 if (adev->wep_enabled) {
4566 SET_BIT(adev->set_mask, GETSET_WEP);
4567 acx_s_update_card_settings(adev);
4568 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4571 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4572 dwrq->length, extra, dwrq->flags);
4573 for (index = 0; index <= 3; index++) {
4574 if (adev->wep_keys[index].size) {
4575 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4576 adev->wep_keys[index].index,
4577 (int) adev->wep_keys[index].size,
4578 adev->wep_keys[index].key);
4582 result = -EINPROGRESS;
4583 // acx_sem_unlock(adev);
4585 FN_EXIT1(result);
4586 return result;
4592 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4596 int acx_net_set_key(struct ieee80211_hw *ieee,
4597 enum set_key_cmd cmd, const u8 *local_addr,
4598 const u8 * addr, struct ieee80211_key_conf *key)
4600 // return 0;
4601 struct acx_device *adev = ieee2adev(ieee);
4602 unsigned long flags;
4603 u8 algorithm;
4604 u16 index;
4605 int err = -EINVAL;
4606 FN_ENTER;
4607 // TODO();
4608 switch (key->alg) {
4609 default:
4610 /* case ALG_NONE:
4611 case ALG_NULL:
4612 algorithm = ACX_SEC_ALGO_NONE;
4613 break;
4614 */ case ALG_WEP:
4615 if (key->keylen == 5)
4616 algorithm = ACX_SEC_ALGO_WEP;
4617 else
4618 algorithm = ACX_SEC_ALGO_WEP104;
4619 break;
4620 case ALG_TKIP:
4621 algorithm = ACX_SEC_ALGO_TKIP;
4622 break;
4623 case ALG_CCMP:
4624 algorithm = ACX_SEC_ALGO_AES;
4625 break;
4628 index = (u8) (key->keyidx);
4629 if (index >= ARRAY_SIZE(adev->key))
4630 goto out;
4631 acx_lock(adev, flags);
4632 switch (cmd) {
4633 case SET_KEY:
4634 err = acx_key_write(adev, index, algorithm, key, addr);
4635 if (err)
4636 goto out_unlock;
4637 key->hw_key_idx = index;
4638 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4639 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4640 adev->default_key_idx = index;*/
4641 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4642 adev->key[index].enabled = 1;
4643 break;
4644 case DISABLE_KEY:
4645 adev->key[index].enabled = 0;
4646 err = 0;
4647 break;
4648 /* case ENABLE_COMPRESSION:
4649 case DISABLE_COMPRESSION:
4650 err = 0;
4651 break; */
4653 out_unlock:
4654 acx_unlock(adev, flags);
4655 out:
4656 FN_EXIT0;
4657 return err;
4662 /***********************************************************************
4663 ** Common function to parse ALL configoption struct formats
4664 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4665 ** FIXME: logging should be removed here and added to a /proc file instead
4667 ** Look into bcm43xx
4669 void
4670 acx_s_parse_configoption(acx_device_t * adev,
4671 const acx111_ie_configoption_t * pcfg)
4673 const u8 *pEle;
4674 int i;
4675 int is_acx111 = IS_ACX111(adev);
4677 acx_log_dump(LOG_DEBUG, L_REALLYVERBOSE, pcfg, sizeof(*pcfg),
4678 "configoption struct content:\n");
4680 if ((is_acx111 && (adev->eeprom_version == 5))
4681 || (!is_acx111 && (adev->eeprom_version == 4))
4682 || (!is_acx111 && (adev->eeprom_version == 5))) {
4683 /* these versions are known to be supported */
4684 } else {
4685 acx_log(LOG_WARNING, L_ANY,
4686 "unknown chip and EEPROM version combination "
4687 "(%s, v%d), "
4688 "don't know how to parse config options yet. "
4689 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4690 adev->eeprom_version);
4691 return;
4694 /* first custom-parse the first part which has chip-specific layout */
4696 pEle = (const u8 *)pcfg;
4698 pEle += 4; /* skip (type,len) header */
4700 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4701 pEle += sizeof(adev->cfgopt_NVSv);
4703 if (is_acx111) {
4704 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4705 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4707 adev->cfgopt_probe_delay = 200; /* good default value? */
4708 pEle += 2; /* FIXME: unknown, value 0x0001 */
4709 } else {
4710 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4711 pEle += sizeof(adev->cfgopt_MAC);
4713 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4714 pEle += sizeof(adev->cfgopt_probe_delay);
4715 if ((adev->cfgopt_probe_delay < 100)
4716 || (adev->cfgopt_probe_delay > 500)) {
4717 acx_log(LOG_WARNING, L_ANY,
4718 "strange probe_delay value %d, "
4719 "tweaking to 200\n", adev->cfgopt_probe_delay);
4720 adev->cfgopt_probe_delay = 200;
4724 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4725 pEle += sizeof(adev->cfgopt_eof_memory);
4727 acx_log(LOG_INFO, L_ANY, "NVS_vendor_offs:%04X probe_delay:%d "
4728 "eof_memory:%d\n",
4729 adev->cfgopt_NVS_vendor_offs, adev->cfgopt_probe_delay,
4730 adev->cfgopt_eof_memory);
4732 adev->cfgopt_dot11CCAModes = *pEle++;
4733 adev->cfgopt_dot11Diversity = *pEle++;
4734 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4735 adev->cfgopt_dot11PBCCOption = *pEle++;
4736 adev->cfgopt_dot11ChannelAgility = *pEle++;
4737 adev->cfgopt_dot11PhyType = *pEle++;
4738 adev->cfgopt_dot11TempType = *pEle++;
4739 acx_log(LOG_INFO, L_ANY,
4740 "CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4741 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4742 adev->cfgopt_dot11CCAModes, adev->cfgopt_dot11Diversity,
4743 adev->cfgopt_dot11ShortPreambleOption,
4744 adev->cfgopt_dot11PBCCOption, adev->cfgopt_dot11ChannelAgility,
4745 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4747 /* then use common parsing for next part which has common layout */
4749 pEle++; /* skip table_count (6) */
4751 adev->cfgopt_antennas.type = pEle[0];
4752 adev->cfgopt_antennas.len = pEle[1];
4755 * FIXME: a candidate for acx_log_dump(), but the code is bizarre
4757 acx_log(LOG_INFO, L_ANY, "AntennaID:%02X Len:%02X Data:",
4758 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4759 for (i = 0; i < pEle[1]; i++) {
4760 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4761 printk("%02X ", pEle[i + 2]);
4763 printk("\n");
4765 pEle += pEle[1] + 2;
4766 adev->cfgopt_power_levels.type = pEle[0];
4767 adev->cfgopt_power_levels.len = pEle[1];
4770 * FIXME: see above
4772 acx_log(LOG_INFO, L_ANY, "PowerLevelID:%02X Len:%02X Data:",
4773 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4774 for (i = 0; i < pEle[1]; i++) {
4775 adev->cfgopt_power_levels.list[i] =
4776 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4777 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4779 printk("\n");
4781 pEle += pEle[1] * 2 + 2;
4782 adev->cfgopt_data_rates.type = pEle[0];
4783 adev->cfgopt_data_rates.len = pEle[1];
4786 * FIXME again
4788 acx_log(LOG_INFO, L_ANY, "DataRatesID:%02X Len:%02X Data:",
4789 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4790 for (i = 0; i < pEle[1]; i++) {
4791 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4792 printk("%02X ", pEle[i + 2]);
4794 printk("\n");
4796 pEle += pEle[1] + 2;
4797 adev->cfgopt_domains.type = pEle[0];
4798 adev->cfgopt_domains.len = pEle[1];
4801 * And again
4803 acx_log(LOG_INFO, L_ANY, "DomainID:%02X Len:%02X Data:",
4804 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4805 for (i = 0; i < pEle[1]; i++) {
4806 adev->cfgopt_domains.list[i] = pEle[i + 2];
4807 printk("%02X ", pEle[i + 2]);
4809 printk("\n");
4811 pEle += pEle[1] + 2;
4812 adev->cfgopt_product_id.type = pEle[0];
4813 adev->cfgopt_product_id.len = pEle[1];
4814 for (i = 0; i < pEle[1]; i++) {
4815 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4817 acx_log(LOG_INFO, L_ANY, "ProductID:%02X Len:%02X Data:%.*s\n",
4818 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4819 adev->cfgopt_product_id.len,
4820 (char *)adev->cfgopt_product_id.list);
4822 pEle += pEle[1] + 2;
4823 adev->cfgopt_manufacturer.type = pEle[0];
4824 adev->cfgopt_manufacturer.len = pEle[1];
4825 for (i = 0; i < pEle[1]; i++) {
4826 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4828 acx_log(LOG_INFO, L_ANY, "ManufacturerID:%02X Len:%02X Data:%.*s\n",
4829 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4830 adev->cfgopt_manufacturer.len,
4831 (char *)adev->cfgopt_manufacturer.list);
4833 printk("EEPROM part:\n");
4834 for (i=0; i<58; i++) {
4835 printk("%02X =======> 0x%02X\n",
4836 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4842 /***********************************************************************
4843 ** Linux Kernel Specific
4845 static int __init acx_e_init_module(void)
4847 int r1, r2;
4849 acx_struct_size_check();
4851 acx_log(LOG_INFO, L_ANY, "this driver is still EXPERIMENTAL\n");
4852 acx_log(LOG_INFO, L_ANY, "acx: reading README file and/or "
4853 "Craig's HOWTO is recommended, "
4854 "visit http://acx100.sourceforge.net/wiki in case "
4855 "of further questions/discussion\n");
4857 #if defined(CONFIG_ACX_MAC80211_PCI)
4858 r1 = acxpci_e_init_module();
4859 #else
4860 r1 = -EINVAL;
4861 #endif
4862 #if defined(CONFIG_ACX_MAC80211_USB)
4863 r2 = acxusb_e_init_module();
4864 #else
4865 r2 = -EINVAL;
4866 #endif
4867 if (r2 && r1) /* both failed! */
4868 return r2 ? r2 : r1;
4869 /* return success if at least one succeeded */
4870 return 0;
4873 static void __exit acx_e_cleanup_module(void)
4875 #if defined(CONFIG_ACX_MAC80211_PCI)
4876 acxpci_e_cleanup_module();
4877 #endif
4878 #if defined(CONFIG_ACX_MAC80211_USB)
4879 acxusb_e_cleanup_module();
4880 #endif
4883 module_init(acx_e_init_module)
4884 module_exit(acx_e_cleanup_module)