drop 2.6.24 support
[acx-mac80211.git] / common.c
bloba098503673c89a0140584ecdb638a6224e599e53
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 #ifdef CONFIG_X86
160 mdelay(ms);
161 #else
162 msleep(ms);
163 #endif
164 FN_EXIT0;
168 /***********************************************************************
169 ** Not inlined: it's larger than it seems
171 void acx_print_mac(const char *head, const u8 * mac, const char *tail)
173 printk("%s" MACSTR "%s", head, MAC(mac), tail);
179 /***********************************************************************
180 ** acx_cmd_status_str
182 const char *acx_cmd_status_str(unsigned int state)
184 static const char *const cmd_error_strings[] = {
185 "Idle",
186 "Success",
187 "Unknown Command",
188 "Invalid Information Element",
189 "Channel rejected",
190 "Channel invalid in current regulatory domain",
191 "MAC invalid",
192 "Command rejected (read-only information element)",
193 "Command rejected",
194 "Already asleep",
195 "TX in progress",
196 "Already awake",
197 "Write only",
198 "RX in progress",
199 "Invalid parameter",
200 "Scan in progress",
201 "Failed"
203 return state < ARRAY_SIZE(cmd_error_strings) ?
204 cmd_error_strings[state] : "?";
207 /***********************************************************************
208 ** acx_s_get_firmware_version
210 ** Obvious
212 void acx_s_get_firmware_version(acx_device_t * adev)
214 fw_ver_t fw;
215 u8 hexarr[4] = { 0, 0, 0, 0 };
216 int hexidx = 0, val = 0;
217 const char *num;
218 char c;
220 FN_ENTER;
222 memset(fw.fw_id, 'E', FW_ID_SIZE);
223 acx_s_interrogate(adev, &fw, ACX1xx_IE_FWREV);
224 memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE);
225 adev->firmware_version[FW_ID_SIZE] = '\0';
227 acx_log(LOG_DEBUG, L_ANY, "fw_ver: fw_id='%s' hw_id=%08X\n",
228 adev->firmware_version, fw.hw_id);
230 if (strncmp(fw.fw_id, "Rev ", 4) != 0) {
231 acx_log(LOG_WARNING, L_ANY, "acx: strange firmware version string "
232 "'%s', please report\n", adev->firmware_version);
233 adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */
234 } else {
235 num = &fw.fw_id[4];
236 while (1) {
237 c = *num++;
238 if ((c == '.') || (c == '\0')) {
239 hexarr[hexidx++] = val;
240 if ((hexidx > 3) || (c == '\0')) /* end? */
241 break;
242 val = 0;
243 continue;
245 if ((c >= '0') && (c <= '9'))
246 c -= '0';
247 else
248 c = c - 'a' + (char)10;
249 val = val * 16 + c;
252 adev->firmware_numver = (u32) ((hexarr[0] << 24) |
253 (hexarr[1] << 16)
254 | (hexarr[2] << 8) | hexarr[3]);
255 acx_log(LOG_DEBUG, L_ANY, "firmware_numver 0x%08X\n",
256 adev->firmware_numver);
258 if (IS_ACX111(adev)) {
259 if (adev->firmware_numver == 0x00010011) {
260 /* This one does not survive floodpinging */
261 acx_log(LOG_WARNING, L_ANY, "firmware '%s' is known "
262 "to be buggy, please upgrade\n",
263 adev->firmware_version);
267 adev->firmware_id = le32_to_cpu(fw.hw_id);
269 /* we're able to find out more detailed chip names now */
270 switch (adev->firmware_id & 0xffff0000) {
271 case 0x01010000:
272 case 0x01020000:
273 adev->chip_name = "TNETW1100A";
274 break;
275 case 0x01030000:
276 adev->chip_name = "TNETW1100B";
277 break;
278 case 0x03000000:
279 case 0x03010000:
280 adev->chip_name = "TNETW1130";
281 break;
282 case 0x04030000: /* 0x04030101 is TNETW1450 */
283 adev->chip_name = "TNETW1450";
284 break;
285 default:
286 acx_log(LOG_WARNING, L_ANY,"unknown chip ID 0x%08X, "
287 "please report\n", adev->firmware_id);
288 break;
291 FN_EXIT0;
295 /***********************************************************************
296 ** acx_display_hardware_details
298 ** Displays hw/fw version, radio type etc...
300 ** Obvious
302 void acx_display_hardware_details(acx_device_t * adev)
304 const char *radio_str, *form_str;
306 FN_ENTER;
308 switch (adev->radio_type) {
309 case RADIO_MAXIM_0D:
310 radio_str = "Maxim";
311 break;
312 case RADIO_RFMD_11:
313 radio_str = "RFMD";
314 break;
315 case RADIO_RALINK_15:
316 radio_str = "Ralink";
317 break;
318 case RADIO_RADIA_16:
319 radio_str = "Radia";
320 break;
321 case RADIO_UNKNOWN_17:
322 /* TI seems to have a radio which is
323 * additionally 802.11a capable, too */
324 radio_str = "802.11a/b/g radio?! Please report";
325 break;
326 case RADIO_UNKNOWN_19:
327 radio_str = "A radio used by Safecom cards?! Please report";
328 break;
329 case RADIO_UNKNOWN_1B:
330 radio_str = "An unknown radio used by TNETW1450 USB adapters";
331 break;
332 default:
333 radio_str = "UNKNOWN, please report radio type name!";
334 break;
337 switch (adev->form_factor) {
338 case 0x00:
339 form_str = "unspecified";
340 break;
341 case 0x01:
342 form_str = "(mini-)PCI / CardBus";
343 break;
344 case 0x02:
345 form_str = "USB";
346 break;
347 case 0x03:
348 form_str = "Compact Flash";
349 break;
350 default:
351 form_str = "UNKNOWN, please report";
352 break;
355 acx_log(LOG_INFO, L_ANY, "acx: chipset %s, radio type 0x%02X (%s), "
356 "form factor 0x%02X (%s), EEPROM version 0x%02X, "
357 "uploaded firmware '%s'\n",
358 adev->chip_name, adev->radio_type, radio_str,
359 adev->form_factor, form_str, adev->eeprom_version,
360 adev->firmware_version);
362 FN_EXIT0;
366 /***********************************************************************
367 ** acx_e_get_stats, acx_e_get_wireless_stats
370 acx_e_get_stats(struct ieee80211_hw *hw,
371 struct ieee80211_low_level_stats *stats)
373 acx_device_t *adev = ieee2adev(hw);
374 unsigned long flags;
375 acx_lock(adev, flags);
376 memcpy(stats, &adev->ieee_stats, sizeof(*stats));
377 acx_unlock(adev, flags);
378 return 0;
382 /***********************************************************************
383 ** maps acx111 tx descr rate field to acx100 one
385 const u8 acx_bitpos2rate100[] = {
386 RATE100_1, /* 0 */
387 RATE100_2, /* 1 */
388 RATE100_5, /* 2 */
389 RATE100_2, /* 3, should not happen */
390 RATE100_2, /* 4, should not happen */
391 RATE100_11, /* 5 */
392 RATE100_2, /* 6, should not happen */
393 RATE100_2, /* 7, should not happen */
394 RATE100_22, /* 8 */
395 RATE100_2, /* 9, should not happen */
396 RATE100_2, /* 10, should not happen */
397 RATE100_2, /* 11, should not happen */
398 RATE100_2, /* 12, should not happen */
399 RATE100_2, /* 13, should not happen */
400 RATE100_2, /* 14, should not happen */
401 RATE100_2, /* 15, should not happen */
404 u8 acx_rate111to100(u16 r)
406 return acx_bitpos2rate100[highest_bit(r)];
410 /***********************************************************************
411 ** Calculate level like the feb 2003 windows driver seems to do
413 static u8 acx_signal_to_winlevel(u8 rawlevel)
415 /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
416 u8 winlevel = ((4 + (rawlevel * 5)) / 8);
418 if (winlevel > 100)
419 winlevel = 100;
420 return winlevel;
423 u8 acx_signal_determine_quality(u8 signal, u8 noise)
425 int qual;
427 qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2;
429 if (qual > 100)
430 return 100;
431 if (qual < 0)
432 return 0;
433 return qual;
437 /***********************************************************************
438 ** Interrogate/configure commands
441 /* FIXME: the lengths given here probably aren't always correct.
442 * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4",
443 * unless the firmware actually expects a different length than the struct length */
444 static const u16 acx100_ie_len[] = {
446 ACX100_IE_ACX_TIMER_LEN,
447 sizeof(acx100_ie_powersave_t) - 4, /* is that 6 or 8??? */
448 ACX1xx_IE_QUEUE_CONFIG_LEN,
449 ACX100_IE_BLOCK_SIZE_LEN,
450 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
451 ACX1xx_IE_RATE_FALLBACK_LEN,
452 ACX100_IE_WEP_OPTIONS_LEN,
453 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
455 ACX1xx_IE_ASSOC_ID_LEN,
457 ACX111_IE_CONFIG_OPTIONS_LEN,
458 ACX1xx_IE_FWREV_LEN,
459 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
460 ACX1xx_IE_MEDIUM_USAGE_LEN,
461 ACX1xx_IE_RXCONFIG_LEN,
464 sizeof(fw_stats_t) - 4,
466 ACX1xx_IE_FEATURE_CONFIG_LEN,
467 ACX111_IE_KEY_CHOOSE_LEN,
468 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
469 ACX1FF_IE_WONE_CONFIG_LEN,
471 ACX1FF_IE_TID_CONFIG_LEN,
475 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
476 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
477 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
478 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
480 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
481 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
482 ACX1FF_IE_CCA_THRESHOLD_LEN,
483 ACX1FF_IE_EVENT_MASK_LEN,
484 ACX1FF_IE_DTIM_PERIOD_LEN,
486 ACX1FF_IE_ACI_CONFIG_SET_LEN,
493 ACX1FF_IE_EEPROM_VER_LEN,
496 static const u16 acx100_ie_len_dot11[] = {
498 ACX1xx_IE_DOT11_STATION_ID_LEN,
500 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
501 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
502 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
503 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
504 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
505 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
507 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
508 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
510 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
511 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
512 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
513 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
519 static const u16 acx111_ie_len[] = {
521 ACX100_IE_ACX_TIMER_LEN,
522 sizeof(acx111_ie_powersave_t) - 4,
523 ACX1xx_IE_QUEUE_CONFIG_LEN,
524 ACX100_IE_BLOCK_SIZE_LEN,
525 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
526 ACX1xx_IE_RATE_FALLBACK_LEN,
527 ACX100_IE_WEP_OPTIONS_LEN,
528 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
530 ACX1xx_IE_ASSOC_ID_LEN,
532 ACX111_IE_CONFIG_OPTIONS_LEN,
533 ACX1xx_IE_FWREV_LEN,
534 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
535 ACX1xx_IE_MEDIUM_USAGE_LEN,
536 ACX1xx_IE_RXCONFIG_LEN,
539 sizeof(fw_stats_t) - 4,
541 ACX1xx_IE_FEATURE_CONFIG_LEN,
542 ACX111_IE_KEY_CHOOSE_LEN,
543 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
544 ACX1FF_IE_WONE_CONFIG_LEN,
546 ACX1FF_IE_TID_CONFIG_LEN,
550 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
551 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
552 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
553 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
555 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
556 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
557 ACX1FF_IE_CCA_THRESHOLD_LEN,
558 ACX1FF_IE_EVENT_MASK_LEN,
559 ACX1FF_IE_DTIM_PERIOD_LEN,
561 ACX1FF_IE_ACI_CONFIG_SET_LEN,
568 ACX1FF_IE_EEPROM_VER_LEN,
571 static const u16 acx111_ie_len_dot11[] = {
573 ACX1xx_IE_DOT11_STATION_ID_LEN,
575 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
576 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
577 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
578 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
579 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
580 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
582 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
583 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
585 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
586 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
587 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
588 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
595 #undef FUNC
596 #define FUNC "configure"
597 #if !ACX_DEBUG
598 int acx_s_configure(acx_device_t * adev, void *pdr, int type)
600 #else
602 acx_s_configure_debug(acx_device_t * adev, void *pdr, int type,
603 const char *typestr)
605 #endif
606 u16 len;
607 int res;
609 if (type < 0x1000)
610 len = adev->ie_len[type];
611 else
612 len = adev->ie_len_dot11[type - 0x1000];
614 acx_log(LOG_DEBUG, L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
615 if (unlikely(!len)) {
616 acx_log(LOG_DEBUG, L_ANY, "zero-length type %s?!\n", typestr);
619 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
620 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
621 res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4);
622 if (unlikely(OK != res)) {
623 #if ACX_DEBUG
624 acx_log(LOG_WARNING, L_ANY, "%s: " FUNC "(type:%s) FAILED\n",
625 wiphy_name(adev->ieee->wiphy), typestr);
626 #else
627 acx_log(LOG_WARNING, L_ANY, "%s: " FUNC "(type:0x%X) FAILED\n",
628 wiphy_name(adev->ieee->wiphy), type);
629 #endif
630 /* dump_stack() is already done in issue_cmd() */
632 return res;
635 #undef FUNC
636 #define FUNC "interrogate"
637 #if !ACX_DEBUG
638 int acx_s_interrogate(acx_device_t * adev, void *pdr, int type)
640 #else
642 acx_s_interrogate_debug(acx_device_t * adev, void *pdr, int type,
643 const char *typestr)
645 #endif
646 u16 len;
647 int res;
649 FN_ENTER;
651 /* FIXME: no check whether this exceeds the array yet.
652 * We should probably remember the number of entries... */
653 if (type < 0x1000)
654 len = adev->ie_len[type];
655 else
656 len = adev->ie_len_dot11[type - 0x1000];
658 acx_log(LOG_DEBUG, L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
660 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
661 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
662 res = acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, pdr, len + 4);
663 if (unlikely(OK != res)) {
664 #if ACX_DEBUG
665 acx_log(LOG_WARNING, L_ANY, "%s: " FUNC "(type:%s) FAILED\n",
666 wiphy_name(adev->ieee->wiphy), typestr);
667 #else
668 acx_log(LOG_WARNING, L_ANY, "%s: " FUNC "(type:0x%X) FAILED\n",
669 wiphy_name(adev->ieee->wiphy), type);
670 #endif
671 /* dump_stack() is already done in issue_cmd() */
674 FN_EXIT1(res);
675 return res;
678 #if CMD_DISCOVERY
679 void great_inquisitor(acx_device_t * adev)
681 static struct {
682 u16 type;
683 u16 len;
684 /* 0x200 was too large here: */
685 u8 data[0x100 - 4];
686 } __attribute__ ((packed)) ie;
687 u16 type;
689 FN_ENTER;
691 /* 0..0x20, 0x1000..0x1020 */
692 for (type = 0; type <= 0x1020; type++) {
693 if (type == 0x21)
694 type = 0x1000;
695 ie.type = cpu_to_le16(type);
696 ie.len = cpu_to_le16(sizeof(ie) - 4);
697 acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie));
699 FN_EXIT0;
701 #endif
704 #ifdef CONFIG_PROC_FS
705 /***********************************************************************
706 ** /proc files
708 /***********************************************************************
709 ** acx_l_proc_output
710 ** Generate content for our /proc entry
712 ** Arguments:
713 ** buf is a pointer to write output to
714 ** adev is the usual pointer to our private struct acx_device
715 ** Returns:
716 ** number of bytes actually written to buf
717 ** Side effects:
718 ** none
720 static int acx_l_proc_output(char *buf, acx_device_t * adev)
722 char *p = buf;
724 FN_ENTER;
726 p += sprintf(p,
727 "acx driver version:\t\t" ACX_RELEASE "\n"
728 "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n"
729 "chip name:\t\t\t%s (0x%08X)\n"
730 "radio type:\t\t\t0x%02X\n"
731 "form factor:\t\t\t0x%02X\n"
732 "EEPROM version:\t\t\t0x%02X\n"
733 "firmware version:\t\t%s (0x%08X)\n",
734 adev->chip_name, adev->firmware_id,
735 adev->radio_type,
736 adev->form_factor,
737 adev->eeprom_version,
738 adev->firmware_version, adev->firmware_numver);
740 FN_EXIT1(p - buf);
741 return p - buf;
745 /***********************************************************************
747 static int acx_s_proc_diag_output(char *buf, acx_device_t * adev)
749 char *p = buf;
750 unsigned long flags;
751 ssize_t len = 0, partlen;
752 u32 temp1, temp2;
753 u8 *st, *st_end;
754 #ifdef __BIG_ENDIAN
755 u8 *st2;
756 #endif
757 fw_stats_t *fw_stats;
758 char *part_str = NULL;
759 fw_stats_tx_t *tx = NULL;
760 fw_stats_rx_t *rx = NULL;
761 fw_stats_dma_t *dma = NULL;
762 fw_stats_irq_t *irq = NULL;
763 fw_stats_wep_t *wep = NULL;
764 fw_stats_pwr_t *pwr = NULL;
765 fw_stats_mic_t *mic = NULL;
766 fw_stats_aes_t *aes = NULL;
767 fw_stats_event_t *evt = NULL;
769 FN_ENTER;
771 acx_lock(adev, flags);
773 if (IS_PCI(adev))
774 p = acxpci_s_proc_diag_output(p, adev);
776 p += sprintf(p,
777 "\n"
778 "** network status **\n"
779 "dev_state_mask 0x%04X\n"
780 "mode %u, channel %u, "
781 "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
782 adev->dev_state_mask,
783 adev->mode, adev->channel,
784 adev->reg_dom_id, adev->reg_dom_chanmask);
785 p += sprintf(p,
786 "ESSID \"%s\", essid_active %d, essid_len %d, "
787 "essid_for_assoc \"%s\", nick \"%s\"\n"
788 "WEP ena %d, restricted %d, idx %d\n",
789 adev->essid, adev->essid_active, (int)adev->essid_len,
790 adev->essid_for_assoc, adev->nick,
791 adev->wep_enabled, adev->wep_restricted,
792 adev->wep_current_index);
793 p += sprintf(p, "dev_addr " MACSTR "\n", MAC(adev->dev_addr));
794 p += sprintf(p, "bssid " MACSTR "\n", MAC(adev->bssid));
795 p += sprintf(p, "ap_filter " MACSTR "\n", MAC(adev->ap));
797 p += sprintf(p, "\n" "** PHY status **\n"
798 "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
799 "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
800 "rate_basic 0x%04X, rate_oper 0x%04X\n"
801 "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
802 "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
803 adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */
804 adev->sensitivity, adev->antenna, adev->ed_threshold,
805 adev->cca, adev->preamble_mode, adev->rate_basic, adev->rate_oper, adev->rts_threshold,
806 adev->frag_threshold, adev->short_retry, adev->long_retry,
807 adev->msdu_lifetime, adev->listen_interval,
808 adev->beacon_interval);
810 acx_unlock(adev, flags);
812 p += sprintf(p,
813 "\n"
814 "** Firmware **\n"
815 "NOTE: version dependent statistics layout, "
816 "please report if you suspect wrong parsing!\n"
817 "\n" "version \"%s\"\n", adev->firmware_version);
819 /* TODO: may replace kmalloc/memset with kzalloc once
820 * Linux 2.6.14 is widespread */
821 fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL);
822 if (!fw_stats) {
823 FN_EXIT1(0);
824 return 0;
826 memset(fw_stats, 0, sizeof(*fw_stats));
828 st = (u8 *) fw_stats;
830 part_str = "statistics query command";
832 if (OK != acx_s_interrogate(adev, st, ACX1xx_IE_FIRMWARE_STATISTICS))
833 goto fw_stats_end;
835 st += sizeof(u16);
836 len = *(u16 *) st;
838 if (len > sizeof(*fw_stats)) {
839 p += sprintf(p,
840 "firmware version with bigger fw_stats struct detected\n"
841 "(%zu vs. %zu), please report\n", len, sizeof(fw_stats_t));
842 if (len > sizeof(*fw_stats)) {
843 p += sprintf(p, "struct size exceeded allocation!\n");
844 len = sizeof(*fw_stats);
847 st += sizeof(u16);
848 st_end = st - 2 * sizeof(u16) + len;
850 #ifdef __BIG_ENDIAN
851 /* let's make one bold assumption here:
852 * (hopefully!) *all* statistics fields are u32 only,
853 * thus if we need to make endianness corrections
854 * we can simply do them in one go, in advance */
855 st2 = (u8 *) fw_stats;
856 for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4)
857 *(u32 *) st2 = le32_to_cpu(*(u32 *) st2);
858 #endif
860 part_str = "Rx/Tx";
862 /* directly at end of a struct part? --> no error! */
863 if (st == st_end)
864 goto fw_stats_end;
866 tx = (fw_stats_tx_t *) st;
867 st += sizeof(fw_stats_tx_t);
868 rx = (fw_stats_rx_t *) st;
869 st += sizeof(fw_stats_rx_t);
870 partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t);
872 if (IS_ACX100(adev)) {
873 /* at least ACX100 PCI F/W 1.9.8.b
874 * and ACX100 USB F/W 1.0.7-USB
875 * don't have those two fields... */
876 st -= 2 * sizeof(u32);
878 /* our parsing doesn't quite match this firmware yet,
879 * log failure */
880 if (st > st_end)
881 goto fw_stats_fail;
882 temp1 = temp2 = 999999999;
883 } else {
884 if (st > st_end)
885 goto fw_stats_fail;
886 temp1 = rx->rx_aci_events;
887 temp2 = rx->rx_aci_resets;
890 p += sprintf(p,
891 "%s:\n"
892 " tx_desc_overfl %u\n"
893 " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
894 " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n"
895 " rx_aci_events %u, rx_aci_resets %u\n",
896 part_str,
897 tx->tx_desc_of,
898 rx->rx_oom,
899 rx->rx_hdr_of,
900 rx->rx_hw_stuck,
901 rx->rx_dropped_frame,
902 rx->rx_frame_ptr_err, rx->rx_xfr_hint_trig, temp1, temp2);
904 part_str = "DMA";
906 if (st == st_end)
907 goto fw_stats_end;
909 dma = (fw_stats_dma_t *) st;
910 partlen = sizeof(fw_stats_dma_t);
911 st += partlen;
913 if (st > st_end)
914 goto fw_stats_fail;
916 p += sprintf(p,
917 "%s:\n"
918 " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n",
919 part_str,
920 dma->rx_dma_req,
921 dma->rx_dma_err, dma->tx_dma_req, dma->tx_dma_err);
923 part_str = "IRQ";
925 if (st == st_end)
926 goto fw_stats_end;
928 irq = (fw_stats_irq_t *) st;
929 partlen = sizeof(fw_stats_irq_t);
930 st += partlen;
932 if (st > st_end)
933 goto fw_stats_fail;
935 p += sprintf(p,
936 "%s:\n"
937 " cmd_cplt %u, fiq %u\n"
938 " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
939 " irqs %u, tx_procs %u, decrypt_done %u\n"
940 " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
941 " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
942 " host_acks %u, pci_pm %u, acm_wakeups %u\n",
943 part_str,
944 irq->cmd_cplt,
945 irq->fiq,
946 irq->rx_hdrs,
947 irq->rx_cmplt,
948 irq->rx_mem_of,
949 irq->rx_rdys,
950 irq->irqs,
951 irq->tx_procs,
952 irq->decrypt_done,
953 irq->dma_0_done,
954 irq->dma_1_done,
955 irq->tx_exch_complet,
956 irq->commands,
957 irq->rx_procs,
958 irq->hw_pm_mode_changes,
959 irq->host_acks, irq->pci_pm, irq->acm_wakeups);
961 part_str = "WEP";
963 if (st == st_end)
964 goto fw_stats_end;
966 wep = (fw_stats_wep_t *) st;
967 partlen = sizeof(fw_stats_wep_t);
968 st += partlen;
970 if ((IS_PCI(adev) && IS_ACX100(adev))
971 || (IS_USB(adev) && IS_ACX100(adev))
973 /* at least ACX100 PCI F/W 1.9.8.b
974 * and ACX100 USB F/W 1.0.7-USB
975 * don't have those two fields... */
976 st -= 2 * sizeof(u32);
977 if (st > st_end)
978 goto fw_stats_fail;
979 temp1 = temp2 = 999999999;
980 } else {
981 if (st > st_end)
982 goto fw_stats_fail;
983 temp1 = wep->wep_pkt_decrypt;
984 temp2 = wep->wep_decrypt_irqs;
987 p += sprintf(p,
988 "%s:\n"
989 " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
990 " wep_key_not_found %u, wep_decrypt_fail %u\n"
991 " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
992 part_str,
993 wep->wep_key_count,
994 wep->wep_default_key_count,
995 wep->dot11_def_key_mib,
996 wep->wep_key_not_found,
997 wep->wep_decrypt_fail, temp1, temp2);
999 part_str = "power";
1001 if (st == st_end)
1002 goto fw_stats_end;
1004 pwr = (fw_stats_pwr_t *) st;
1005 partlen = sizeof(fw_stats_pwr_t);
1006 st += partlen;
1008 if (st > st_end)
1009 goto fw_stats_fail;
1011 p += sprintf(p,
1012 "%s:\n"
1013 " tx_start_ctr %u, no_ps_tx_too_short %u\n"
1014 " rx_start_ctr %u, no_ps_rx_too_short %u\n"
1015 " lppd_started %u\n"
1016 " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n",
1017 part_str,
1018 pwr->tx_start_ctr,
1019 pwr->no_ps_tx_too_short,
1020 pwr->rx_start_ctr,
1021 pwr->no_ps_rx_too_short,
1022 pwr->lppd_started,
1023 pwr->no_lppd_too_noisy,
1024 pwr->no_lppd_too_short, pwr->no_lppd_matching_frame);
1026 part_str = "MIC";
1028 if (st == st_end)
1029 goto fw_stats_end;
1031 mic = (fw_stats_mic_t *) st;
1032 partlen = sizeof(fw_stats_mic_t);
1033 st += partlen;
1035 if (st > st_end)
1036 goto fw_stats_fail;
1038 p += sprintf(p,
1039 "%s:\n"
1040 " mic_rx_pkts %u, mic_calc_fail %u\n",
1041 part_str, mic->mic_rx_pkts, mic->mic_calc_fail);
1043 part_str = "AES";
1045 if (st == st_end)
1046 goto fw_stats_end;
1048 aes = (fw_stats_aes_t *) st;
1049 partlen = sizeof(fw_stats_aes_t);
1050 st += partlen;
1052 if (st > st_end)
1053 goto fw_stats_fail;
1055 p += sprintf(p,
1056 "%s:\n"
1057 " aes_enc_fail %u, aes_dec_fail %u\n"
1058 " aes_enc_pkts %u, aes_dec_pkts %u\n"
1059 " aes_enc_irq %u, aes_dec_irq %u\n",
1060 part_str,
1061 aes->aes_enc_fail,
1062 aes->aes_dec_fail,
1063 aes->aes_enc_pkts,
1064 aes->aes_dec_pkts, aes->aes_enc_irq, aes->aes_dec_irq);
1066 part_str = "event";
1068 if (st == st_end)
1069 goto fw_stats_end;
1071 evt = (fw_stats_event_t *) st;
1072 partlen = sizeof(fw_stats_event_t);
1073 st += partlen;
1075 if (st > st_end)
1076 goto fw_stats_fail;
1078 p += sprintf(p,
1079 "%s:\n"
1080 " heartbeat %u, calibration %u\n"
1081 " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
1082 " oom_late %u\n"
1083 " phy_tx_err %u, tx_stuck %u\n",
1084 part_str,
1085 evt->heartbeat,
1086 evt->calibration,
1087 evt->rx_mismatch,
1088 evt->rx_mem_empty,
1089 evt->rx_pool,
1090 evt->oom_late, evt->phy_tx_err, evt->tx_stuck);
1092 if (st < st_end)
1093 goto fw_stats_bigger;
1095 goto fw_stats_end;
1097 fw_stats_fail:
1098 st -= partlen;
1099 p += sprintf(p,
1100 "failed at %s part (size %zu), offset %zu (struct size %zu), "
1101 "please report\n", part_str, partlen,
1102 ((void *)st - (void *)fw_stats), len);
1104 fw_stats_bigger:
1105 for (; st < st_end; st += 4)
1106 p += sprintf(p,
1107 "UNKN%3d: %u\n",
1108 (int)((void *)st - (void *)fw_stats), *(u32 *) st);
1110 fw_stats_end:
1111 kfree(fw_stats);
1113 FN_EXIT1(p - buf);
1114 return p - buf;
1118 /***********************************************************************
1120 static int acx_s_proc_phy_output(char *buf, acx_device_t * adev)
1122 char *p = buf;
1123 int i;
1125 FN_ENTER;
1128 if (RADIO_RFMD_11 != adev->radio_type) {
1129 printk("sorry, not yet adapted for radio types "
1130 "other than RFMD, please verify "
1131 "PHY size etc. first!\n");
1132 goto end;
1136 /* The PHY area is only 0x80 bytes long; further pages after that
1137 * only have some page number registers with altered value,
1138 * all other registers remain the same. */
1139 for (i = 0; i < 0x80; i++) {
1140 acx_s_read_phy_reg(adev, i, p++);
1143 FN_EXIT1(p - buf);
1144 return p - buf;
1148 /***********************************************************************
1149 ** acx_e_read_proc_XXXX
1150 ** Handle our /proc entry
1152 ** Arguments:
1153 ** standard kernel read_proc interface
1154 ** Returns:
1155 ** number of bytes written to buf
1156 ** Side effects:
1157 ** none
1159 static int
1160 acx_e_read_proc(char *buf, char **start, off_t offset, int count,
1161 int *eof, void *data)
1163 acx_device_t *adev = (acx_device_t *) data;
1164 unsigned long flags;
1165 int length;
1167 FN_ENTER;
1169 acx_sem_lock(adev);
1170 acx_lock(adev, flags);
1171 /* fill buf */
1172 length = acx_l_proc_output(buf, adev);
1173 acx_unlock(adev, flags);
1174 acx_sem_unlock(adev);
1176 /* housekeeping */
1177 if (length <= offset + count)
1178 *eof = 1;
1179 *start = buf + offset;
1180 length -= offset;
1181 if (length > count)
1182 length = count;
1183 if (length < 0)
1184 length = 0;
1185 FN_EXIT1(length);
1186 return length;
1189 static int
1190 acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count,
1191 int *eof, void *data)
1193 acx_device_t *adev = (acx_device_t *) data;
1194 int length;
1196 FN_ENTER;
1198 acx_sem_lock(adev);
1199 /* fill buf */
1200 length = acx_s_proc_diag_output(buf, adev);
1201 acx_sem_unlock(adev);
1203 /* housekeeping */
1204 if (length <= offset + count)
1205 *eof = 1;
1206 *start = buf + offset;
1207 length -= offset;
1208 if (length > count)
1209 length = count;
1210 if (length < 0)
1211 length = 0;
1212 FN_EXIT1(length);
1213 return length;
1216 static int
1217 acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count,
1218 int *eof, void *data)
1220 acx_device_t *adev = (acx_device_t *) data;
1221 int length;
1223 FN_ENTER;
1225 /* fill buf */
1226 length = 0;
1227 if (IS_PCI(adev)) {
1228 acx_sem_lock(adev);
1229 length = acxpci_proc_eeprom_output(buf, adev);
1230 acx_sem_unlock(adev);
1233 /* housekeeping */
1234 if (length <= offset + count)
1235 *eof = 1;
1236 *start = buf + offset;
1237 length -= offset;
1238 if (length > count)
1239 length = count;
1240 if (length < 0)
1241 length = 0;
1242 FN_EXIT1(length);
1243 return length;
1246 static int
1247 acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count,
1248 int *eof, void *data)
1250 acx_device_t *adev = (acx_device_t *) data;
1251 int length;
1253 FN_ENTER;
1255 acx_sem_lock(adev);
1256 /* fill buf */
1257 length = acx_s_proc_phy_output(buf, adev);
1258 acx_sem_unlock(adev);
1260 /* housekeeping */
1261 if (length <= offset + count)
1262 *eof = 1;
1263 *start = buf + offset;
1264 length -= offset;
1265 if (length > count)
1266 length = count;
1267 if (length < 0)
1268 length = 0;
1269 FN_EXIT1(length);
1270 return length;
1274 /***********************************************************************
1275 ** /proc files registration
1277 static const char *const
1278 proc_files[] = { "", "_diag", "_eeprom", "_phy" };
1280 static read_proc_t *const
1281 proc_funcs[] = {
1282 acx_e_read_proc,
1283 acx_e_read_proc_diag,
1284 acx_e_read_proc_eeprom,
1285 acx_e_read_proc_phy
1288 static int manage_proc_entries(struct ieee80211_hw *hw, int remove)
1290 acx_device_t *adev = ieee2adev(hw);
1291 char procbuf[80];
1292 int i;
1294 FN_ENTER;
1296 for (i = 0; i < ARRAY_SIZE(proc_files); i++) {
1297 snprintf(procbuf, sizeof(procbuf),
1298 "driver/acx%s", proc_files[i]);
1299 acx_log(LOG_INFO, L_INIT, "%sing /proc entry %s\n",
1300 remove ? "remov" : "creat", procbuf);
1301 if (!remove) {
1302 if (!create_proc_read_entry
1303 (procbuf, 0, NULL, proc_funcs[i], adev)) {
1304 acx_log(LOG_WARNING, L_ANY,
1305 "cannot register /proc entry %s\n", procbuf);
1306 FN_EXIT1(NOT_OK);
1307 return NOT_OK;
1309 } else {
1310 remove_proc_entry(procbuf, NULL);
1313 FN_EXIT0;
1314 return OK;
1317 int acx_proc_register_entries(struct ieee80211_hw *ieee)
1319 return manage_proc_entries(ieee, 0);
1322 int acx_proc_unregister_entries(struct ieee80211_hw *ieee)
1324 return manage_proc_entries(ieee, 1);
1326 #endif /* CONFIG_PROC_FS */
1328 /****
1329 ** Gathered From rt2x00 and bcm43xx_mac80211 projects
1331 void acx_free_modes(acx_device_t * adev)
1334 // kfree(adev->modes);
1335 // adev->modes = NULL;
1339 #define RATETAB_ENT(_rate, _rateid, _flags) \
1341 .rate = (_rate), \
1342 .val = (_rateid), \
1343 .val2 = (_rateid), \
1344 .flags = (_flags), \
1348 static struct ieee80211_rate __acx_rates[] = {
1349 { .rate = 10,
1350 .val = RATE111_1,
1351 .flags = IEEE80211_RATE_CCK },
1352 { .rate = 20,
1353 .val = RATE111_2,
1354 .flags = IEEE80211_RATE_CCK },
1355 { .rate = 55,
1356 .val = RATE111_5,
1357 .flags = IEEE80211_RATE_CCK },
1358 { .rate = 110,
1359 .val = RATE111_11,
1360 .flags = IEEE80211_RATE_CCK },
1361 { .rate = 60,
1362 .val = RATE111_6,
1363 .flags = IEEE80211_RATE_OFDM },
1364 { .rate = 90,
1365 .val = RATE111_9,
1366 .flags = IEEE80211_RATE_OFDM },
1367 { .rate = 120,
1368 .val = RATE111_12,
1369 .flags = IEEE80211_RATE_OFDM },
1370 { .rate = 180,
1371 .val = RATE111_18,
1372 .flags = IEEE80211_RATE_OFDM },
1373 { .rate = 240,
1374 .val = RATE111_24,
1375 .flags = IEEE80211_RATE_OFDM },
1376 { .rate = 360,
1377 .val = RATE111_36,
1378 .flags = IEEE80211_RATE_OFDM },
1379 { .rate = 480,
1380 .val = RATE111_48,
1381 .flags = IEEE80211_RATE_OFDM },
1382 { .rate = 540,
1383 .val = RATE111_54,
1384 .flags = IEEE80211_RATE_OFDM },
1387 static struct ieee80211_channel channels[] = {
1388 { .chan = 1,
1389 .freq = 2412},
1390 { .chan = 2,
1391 .freq = 2417},
1392 { .chan = 3,
1393 .freq = 2422},
1394 { .chan = 4,
1395 .freq = 2427},
1396 { .chan = 5,
1397 .freq = 2432},
1398 { .chan = 6,
1399 .freq = 2437},
1400 { .chan = 7,
1401 .freq = 2442},
1402 { .chan = 8,
1403 .freq = 2447},
1404 { .chan = 9,
1405 .freq = 2452},
1406 { .chan = 10,
1407 .freq = 2457},
1408 { .chan = 11,
1409 .freq = 2462},
1410 { .chan = 12,
1411 .freq = 2467},
1412 { .chan = 13,
1413 .freq = 2472},
1416 int acx_setup_modes(acx_device_t * adev)
1418 struct ieee80211_hw *hw = adev->ieee;
1419 struct ieee80211_hw_mode *mode;
1420 int err = -ENOMEM;
1422 FN_ENTER;
1424 if (IS_ACX111(adev)) {
1426 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);
1427 err = acx_setup_modes_gphy(adev);
1429 mode = &adev->modes[0];
1431 /* from the zd1211rw driver: - do we need to do the same? */
1433 memcpy(mode->channels, channels, sizeof(channels));
1434 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1437 mode->mode = MODE_IEEE80211G;
1438 mode->num_channels = ARRAY_SIZE(channels);
1439 mode->num_rates = 12;
1440 mode->rates = __acx_rates;
1441 } else {
1443 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1444 err = acx_setup_modes_bphy(adev);
1446 mode = &adev->modes[1];
1448 /* from the zd1211rw driver: - do we need to do the same? */
1450 memcpy(mode->channels, channels, sizeof(channels));
1451 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1454 mode->mode = MODE_IEEE80211B;
1455 mode->num_channels = ARRAY_SIZE(channels);
1456 mode->num_rates = 4;
1457 mode->rates = __acx_rates;
1460 /* if (err && adev->modes)
1461 kfree(adev->modes);*/
1463 mode->channels = channels;
1464 err = ieee80211_register_hwmode(hw, mode);
1466 FN_EXIT1(err);
1467 return err;
1471 /***********************************************************************
1472 ** acx_fill_beacon_or_proberesp_template
1474 ** Origin: derived from rt2x00 project
1476 static int
1477 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1478 struct acx_template_beacon *templ,
1479 struct sk_buff* skb /* in host order! */)
1481 FN_ENTER;
1483 memcpy(templ,skb->data, skb->len);
1484 FN_EXIT1(skb->len);
1485 return skb->len;
1488 /***********************************************************************
1489 ** acx_s_set_beacon_template
1493 static int
1494 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1496 struct acx_template_beacon bcn;
1497 int len, result;
1499 FN_ENTER;
1500 acx_log(LOG_INFO, L_ANY, "size of template: %08zX, "
1501 "size of beacon: %08X\n",
1502 sizeof(struct acx_template_beacon),skb->len);
1503 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1504 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1506 FN_EXIT1(result);
1507 return result;
1510 /***********************************************************************
1511 ** acx_cmd_join_bssid
1513 ** Common code for both acx100 and acx111.
1515 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1516 static const u8 bitpos2genframe_txrate[] = {
1517 10, /* 0. 1 Mbit/s */
1518 20, /* 1. 2 Mbit/s */
1519 55, /* 2. 5.5 Mbit/s */
1520 0x0B, /* 3. 6 Mbit/s */
1521 0x0F, /* 4. 9 Mbit/s */
1522 110, /* 5. 11 Mbit/s */
1523 0x0A, /* 6. 12 Mbit/s */
1524 0x0E, /* 7. 18 Mbit/s */
1525 220, /* 8. 22 Mbit/s */
1526 0x09, /* 9. 24 Mbit/s */
1527 0x0D, /* 10. 36 Mbit/s */
1528 0x08, /* 11. 48 Mbit/s */
1529 0x0C, /* 12. 54 Mbit/s */
1530 10, /* 13. 1 Mbit/s, should never happen */
1531 10, /* 14. 1 Mbit/s, should never happen */
1532 10, /* 15. 1 Mbit/s, should never happen */
1535 /* Looks scary, eh?
1536 ** Actually, each one compiled into one AND and one SHIFT,
1537 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1538 static inline unsigned int rate111to5bits(unsigned int rate)
1540 return (rate & 0x7)
1541 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1542 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1546 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1548 acx_joinbss_t tmp;
1549 int dtim_interval;
1550 int i;
1552 if (mac_is_zero(bssid))
1553 return;
1555 FN_ENTER;
1557 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1558 1 : adev->dtim_interval;
1560 memset(&tmp, 0, sizeof(tmp));
1562 for (i = 0; i < ETH_ALEN; i++) {
1563 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1566 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1568 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1569 ** are sent with one of these rates */
1570 if (IS_ACX111(adev)) {
1571 /* It was experimentally determined that rates_basic
1572 ** can take 11g rates as well, not only rates
1573 ** defined with JOINBSS_RATES_BASIC111_nnn.
1574 ** Just use RATE111_nnn constants... */
1575 tmp.u.acx111.dtim_interval = dtim_interval;
1576 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1577 acx_log(LOG_INFO, L_ASSOC, "rates_basic:%04X, "
1578 "rates_supported:%04X\n",
1579 adev->rate_basic, adev->rate_oper);
1580 } else {
1581 tmp.u.acx100.dtim_interval = dtim_interval;
1582 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1583 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1584 acx_log(LOG_INFO, L_ASSOC, "rates_basic:%04X->%02X, "
1585 "rates_supported:%04X->%02X\n",
1586 adev->rate_basic, tmp.u.acx100.rates_basic,
1587 adev->rate_oper, tmp.u.acx100.rates_supported);
1590 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1591 ** will be sent (rate/modulation/preamble) */
1592 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1593 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1594 /* we can use short pre *if* all peers can understand it */
1595 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1597 /* we switch fw to STA mode in MONITOR mode, it seems to be
1598 ** the only mode where fw does not emit beacons by itself
1599 ** but allows us to send anything (we really want to retain
1600 ** ability to tx arbitrary frames in MONITOR mode)
1602 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1603 tmp.channel = adev->channel;
1604 tmp.essid_len = adev->essid_len;
1606 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1607 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1609 acx_log(LOG_DEBUG, L_ASSOC, "BSS_Type = %u\n", tmp.macmode);
1610 acx_log(LOG_DEBUG, L_ASSOC, "JoinBSSID MAC:" MACSTR "\n",
1611 adev->bssid, "\n");
1613 /* acx_update_capabilities(adev); */
1614 FN_EXIT0;
1617 /***********************************************************************
1618 ** acxpci_i_set_multicast_list
1619 ** FIXME: most likely needs refinement
1622 void acx_i_set_multicast_list(struct ieee80211_hw *hw,
1623 unsigned int changed_flags,
1624 unsigned int *total_flags,
1625 int mc_count, struct dev_addr_list *mc_list)
1627 acx_device_t *adev = ieee2adev(hw);
1628 unsigned long flags;
1630 FN_ENTER;
1632 acx_lock(adev, flags);
1634 changed_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1635 FIF_CONTROL | FIF_OTHER_BSS);
1636 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1637 FIF_CONTROL | FIF_OTHER_BSS);
1638 /* if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1639 return; */
1641 if (*total_flags) {
1642 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1643 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1644 SET_BIT(adev->set_mask, SET_RXCONFIG);
1645 /* let kernel know in case *we* needed to set promiscuous */
1646 } else {
1647 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1648 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1649 SET_BIT(adev->set_mask, SET_RXCONFIG);
1652 /* cannot update card settings directly here, atomic context */
1653 acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
1655 acx_unlock(adev, flags);
1657 FN_EXIT0;
1660 /***********************************************************************
1661 ** acx111 feature config
1663 ** Obvious
1665 static int
1666 acx111_s_get_feature_config(acx_device_t * adev,
1667 u32 * feature_options, u32 * data_flow_options)
1669 struct acx111_ie_feature_config feat;
1671 FN_ENTER;
1673 if (!IS_ACX111(adev)) {
1674 return NOT_OK;
1677 memset(&feat, 0, sizeof(feat));
1679 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1680 FN_EXIT1(NOT_OK);
1681 return NOT_OK;
1683 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
1684 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1685 feat.feature_options, feat.data_flow_options);
1687 if (feature_options)
1688 *feature_options = le32_to_cpu(feat.feature_options);
1689 if (data_flow_options)
1690 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1692 FN_EXIT0;
1693 return OK;
1697 static int
1698 acx111_s_set_feature_config(acx_device_t * adev,
1699 u32 feature_options, u32 data_flow_options,
1700 unsigned int mode
1701 /* 0 == remove, 1 == add, 2 == set */ )
1703 struct acx111_ie_feature_config feat;
1705 FN_ENTER;
1707 if (!IS_ACX111(adev)) {
1708 FN_EXIT1(NOT_OK);
1709 return NOT_OK;
1712 if ((mode < 0) || (mode > 2)) {
1713 FN_EXIT1(NOT_OK);
1714 return NOT_OK;
1717 if (mode != 2)
1718 /* need to modify old data */
1719 acx111_s_get_feature_config(adev, &feat.feature_options,
1720 &feat.data_flow_options);
1721 else {
1722 /* need to set a completely new value */
1723 feat.feature_options = 0;
1724 feat.data_flow_options = 0;
1727 if (mode == 0) { /* remove */
1728 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1729 CLEAR_BIT(feat.data_flow_options,
1730 cpu_to_le32(data_flow_options));
1731 } else { /* add or set */
1732 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1733 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1736 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
1737 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1738 "new: feature 0x%08X dataflow 0x%08X\n",
1739 feature_options, data_flow_options, mode,
1740 le32_to_cpu(feat.feature_options),
1741 le32_to_cpu(feat.data_flow_options));
1743 if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1744 FN_EXIT1(NOT_OK);
1745 return NOT_OK;
1748 FN_EXIT0;
1749 return OK;
1752 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1754 return acx111_s_set_feature_config(adev, f, d, 0);
1756 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1758 return acx111_s_set_feature_config(adev, f, d, 1);
1760 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1762 return acx111_s_set_feature_config(adev, f, d, 2);
1766 /***********************************************************************
1767 ** acx100_s_init_memory_pools
1769 static int
1770 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1772 acx100_ie_memblocksize_t MemoryBlockSize;
1773 acx100_ie_memconfigoption_t MemoryConfigOption;
1774 int TotalMemoryBlocks;
1775 int RxBlockNum;
1776 int TotalRxBlockSize;
1777 int TxBlockNum;
1778 int TotalTxBlockSize;
1780 FN_ENTER;
1782 /* Let's see if we can follow this:
1783 first we select our memory block size (which I think is
1784 completely arbitrary) */
1785 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1787 /* Then we alert the card to our decision of block size */
1788 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
1789 goto bad;
1792 /* We figure out how many total blocks we can create, using
1793 the block size we chose, and the beginning and ending
1794 memory pointers, i.e.: end-start/size */
1795 TotalMemoryBlocks =
1796 (le32_to_cpu(mmt->PoolEnd) -
1797 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1799 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "TotalMemoryBlocks=%u (%u bytes)\n",
1800 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1802 /* MemoryConfigOption.DMA_config bitmask:
1803 access to ACX memory is to be done:
1804 0x00080000 using PCI conf space?!
1805 0x00040000 using IO instructions?
1806 0x00000000 using memory access instructions
1807 0x00020000 using local memory block linked list (else what?)
1808 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1810 if (IS_PCI(adev)) {
1811 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1812 /* Declare start of the Rx host pool */
1813 MemoryConfigOption.pRxHostDesc =
1814 cpu2acx(adev->rxhostdesc_startphy);
1815 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "pRxHostDesc 0x%08X, "
1816 "rxhostdesc_startphy 0x%lX\n",
1817 acx2cpu(MemoryConfigOption.pRxHostDesc),
1818 (long)adev->rxhostdesc_startphy);
1819 } else {
1820 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1823 /* 50% of the allotment of memory blocks go to tx descriptors */
1824 TxBlockNum = TotalMemoryBlocks / 2;
1825 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1827 /* and 50% go to the rx descriptors */
1828 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1829 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1831 /* size of the tx and rx descriptor queues */
1832 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1833 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1834 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "TxBlockNum %u RxBlockNum %u "
1835 "TotalTxBlockSize %u TotalTxBlockSize %u\n",
1836 TxBlockNum, RxBlockNum, TotalTxBlockSize, TotalRxBlockSize);
1839 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1840 MemoryConfigOption.rx_mem =
1841 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1843 /* align the rx descriptor queue to units of 0x20
1844 * and offset it by the tx descriptor queue */
1845 MemoryConfigOption.tx_mem =
1846 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
1847 0x1f) & ~0x1f);
1848 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "rx_mem %08X rx_mem %08X\n",
1849 MemoryConfigOption.tx_mem, MemoryConfigOption.rx_mem);
1851 /* alert the device to our decision */
1852 if (OK !=
1853 acx_s_configure(adev, &MemoryConfigOption,
1854 ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
1855 goto bad;
1858 /* and tell the device to kick it into gear */
1859 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
1860 goto bad;
1862 FN_EXIT1(OK);
1863 return OK;
1864 bad:
1865 FN_EXIT1(NOT_OK);
1866 return NOT_OK;
1870 /***********************************************************************
1871 ** acx100_s_create_dma_regions
1873 ** Note that this fn messes up heavily with hardware, but we cannot
1874 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1876 /* OLD CODE? - let's rewrite it! */
1877 static int acx100_s_create_dma_regions(acx_device_t * adev)
1879 acx100_ie_queueconfig_t queueconf;
1880 acx_ie_memmap_t memmap;
1881 int res = NOT_OK;
1882 u32 tx_queue_start, rx_queue_start;
1884 FN_ENTER;
1886 /* read out the acx100 physical start address for the queues */
1887 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1888 goto fail;
1891 tx_queue_start = le32_to_cpu(memmap.QueueStart);
1892 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
1894 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "initializing Queue Indicator\n");
1896 memset(&queueconf, 0, sizeof(queueconf));
1898 /* Not needed for PCI, so we can avoid setting them altogether */
1899 if (IS_USB(adev)) {
1900 queueconf.NumTxDesc = USB_TX_CNT;
1901 queueconf.NumRxDesc = USB_RX_CNT;
1904 /* calculate size of queues */
1905 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
1906 RX_CNT * sizeof(rxdesc_t) + 8);
1907 queueconf.NumTxQueues = 1; /* number of tx queues */
1908 /* sets the beginning of the tx descriptor queue */
1909 queueconf.TxQueueStart = memmap.QueueStart;
1910 /* done by memset: queueconf.TxQueuePri = 0; */
1911 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
1912 queueconf.QueueOptions = 1; /* auto reset descriptor */
1913 /* sets the end of the rx descriptor queue */
1914 queueconf.QueueEnd =
1915 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
1917 /* sets the beginning of the next queue */
1918 queueconf.HostQueueEnd =
1919 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
1920 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
1921 goto fail;
1924 if (IS_PCI(adev)) {
1925 /* sets the beginning of the rx descriptor queue, after the tx descrs */
1926 if (OK != acxpci_s_create_hostdesc_queues(adev))
1927 goto fail;
1928 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
1931 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1932 goto fail;
1935 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
1936 0x1f) & ~0x1f);
1938 if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1939 goto fail;
1942 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
1943 goto fail;
1946 res = OK;
1947 goto end;
1949 fail:
1950 acx_s_mwait(1000); /* ? */
1951 if (IS_PCI(adev))
1952 acxpci_free_desc_queues(adev);
1953 end:
1954 FN_EXIT1(res);
1955 return res;
1959 /***********************************************************************
1960 ** acx111_s_create_dma_regions
1962 ** Note that this fn messes heavily with hardware, but we cannot
1963 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1965 #define ACX111_PERCENT(percent) ((percent)/5)
1967 static int acx111_s_create_dma_regions(acx_device_t * adev)
1969 struct acx111_ie_memoryconfig memconf;
1970 struct acx111_ie_queueconfig queueconf;
1971 u32 tx_queue_start, rx_queue_start;
1973 FN_ENTER;
1975 /* Calculate memory positions and queue sizes */
1977 /* Set up our host descriptor pool + data pool */
1978 if (IS_PCI(adev)) {
1979 if (OK != acxpci_s_create_hostdesc_queues(adev))
1980 goto fail;
1983 memset(&memconf, 0, sizeof(memconf));
1984 /* the number of STAs (STA contexts) to support
1985 ** NB: was set to 1 and everything seemed to work nevertheless... */
1986 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
1987 /* specify the memory block size. Default is 256 */
1988 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
1989 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
1990 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
1991 /* set the count of our queues
1992 ** NB: struct acx111_ie_memoryconfig shall be modified
1993 ** if we ever will switch to more than one rx and/or tx queue */
1994 memconf.count_rx_queues = 1;
1995 memconf.count_tx_queues = 1;
1996 /* 0 == Busmaster Indirect Memory Organization, which is what we want
1997 * (using linked host descs with their allocated mem).
1998 * 2 == Generic Bus Slave */
1999 /* done by memset: memconf.options = 0; */
2000 /* let's use 25% for fragmentations and 75% for frame transfers
2001 * (specified in units of 5%) */
2002 memconf.fragmentation = ACX111_PERCENT(75);
2003 /* Rx descriptor queue config */
2004 memconf.rx_queue1_count_descs = RX_CNT;
2005 memconf.rx_queue1_type = 7; /* must be set to 7 */
2006 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2007 if (IS_PCI(adev)) {
2008 memconf.rx_queue1_host_rx_start =
2009 cpu2acx(adev->rxhostdesc_startphy);
2011 /* Tx descriptor queue config */
2012 memconf.tx_queue1_count_descs = TX_CNT;
2013 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2015 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
2016 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2017 ** But it is actually correct wrt IE numbers.
2018 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
2019 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2020 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2021 if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
2022 goto fail;
2025 acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
2027 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2028 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2030 acx_log(LOG_DEBUG, L_INIT, "dump queue head (from card):\n"
2031 "len: %u\n"
2032 "tx_memory_block_address: %X\n"
2033 "rx_memory_block_address: %X\n"
2034 "tx1_queue address: %X\n"
2035 "rx1_queue address: %X\n",
2036 le16_to_cpu(queueconf.len),
2037 le32_to_cpu(queueconf.tx_memory_block_address),
2038 le32_to_cpu(queueconf.rx_memory_block_address),
2039 tx_queue_start, rx_queue_start);
2041 if (IS_PCI(adev))
2042 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2044 FN_EXIT1(OK);
2045 return OK;
2046 fail:
2047 if (IS_PCI(adev))
2048 acxpci_free_desc_queues(adev);
2050 FN_EXIT1(NOT_OK);
2051 return NOT_OK;
2055 /***********************************************************************
2057 static void acx_s_initialize_rx_config(acx_device_t * adev)
2059 struct {
2060 u16 id;
2061 u16 len;
2062 u16 rx_cfg1;
2063 u16 rx_cfg2;
2064 } __attribute__ ((packed)) cfg;
2065 switch (adev->mode) {
2066 case ACX_MODE_MONITOR:
2067 adev->rx_config_1 = (u16) (0
2068 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2069 /* | RX_CFG1_FILTER_SSID */
2070 /* | RX_CFG1_FILTER_BCAST */
2071 /* | RX_CFG1_RCV_MC_ADDR1 */
2072 /* | RX_CFG1_RCV_MC_ADDR0 */
2073 /* | RX_CFG1_FILTER_ALL_MULTI */
2074 /* | RX_CFG1_FILTER_BSSID */
2075 /* | RX_CFG1_FILTER_MAC */
2076 | RX_CFG1_RCV_PROMISCUOUS
2077 | RX_CFG1_INCLUDE_FCS
2078 /* | RX_CFG1_INCLUDE_PHY_HDR */
2080 adev->rx_config_2 = (u16) (0
2081 | RX_CFG2_RCV_ASSOC_REQ
2082 | RX_CFG2_RCV_AUTH_FRAMES
2083 | RX_CFG2_RCV_BEACON_FRAMES
2084 | RX_CFG2_RCV_CONTENTION_FREE
2085 | RX_CFG2_RCV_CTRL_FRAMES
2086 | RX_CFG2_RCV_DATA_FRAMES
2087 | RX_CFG2_RCV_BROKEN_FRAMES
2088 | RX_CFG2_RCV_MGMT_FRAMES
2089 | RX_CFG2_RCV_PROBE_REQ
2090 | RX_CFG2_RCV_PROBE_RESP
2091 | RX_CFG2_RCV_ACK_FRAMES
2092 | RX_CFG2_RCV_OTHER);
2093 break;
2094 default:
2095 adev->rx_config_1 = (u16) (0
2096 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2097 /* | RX_CFG1_FILTER_SSID */
2098 /* | RX_CFG1_FILTER_BCAST */
2099 /* | RX_CFG1_RCV_MC_ADDR1 */
2100 /* | RX_CFG1_RCV_MC_ADDR0 */
2101 /* | RX_CFG1_FILTER_ALL_MULTI */
2102 /* | RX_CFG1_FILTER_BSSID */
2103 /* | RX_CFG1_FILTER_MAC */
2104 | RX_CFG1_RCV_PROMISCUOUS
2105 /* | RX_CFG1_INCLUDE_FCS */
2106 /* | RX_CFG1_INCLUDE_PHY_HDR */
2108 adev->rx_config_2 = (u16) (0
2109 | RX_CFG2_RCV_ASSOC_REQ
2110 | RX_CFG2_RCV_AUTH_FRAMES
2111 | RX_CFG2_RCV_BEACON_FRAMES
2112 | RX_CFG2_RCV_CONTENTION_FREE
2113 | RX_CFG2_RCV_CTRL_FRAMES
2114 | RX_CFG2_RCV_DATA_FRAMES
2115 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2116 | RX_CFG2_RCV_MGMT_FRAMES
2117 | RX_CFG2_RCV_PROBE_REQ
2118 | RX_CFG2_RCV_PROBE_RESP
2119 | RX_CFG2_RCV_ACK_FRAMES
2120 | RX_CFG2_RCV_OTHER);
2121 break;
2123 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2125 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2126 || (adev->firmware_numver >= 0x02000000))
2127 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2128 else
2129 adev->phy_header_len = 0;
2131 acx_log(LOG_DEBUG, L_INIT, "setting RXconfig to %04X:%04X\n",
2132 adev->rx_config_1, adev->rx_config_2);
2134 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2135 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2136 acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
2140 /***********************************************************************
2141 ** FIXME: this should be solved in a general way for all radio types
2142 ** by decoding the radio firmware module,
2143 ** since it probably has some standard structure describing how to
2144 ** set the power level of the radio module which it controls.
2145 ** Or maybe not, since the radio module probably has a function interface
2146 ** instead which then manages Tx level programming :-\
2148 ** Obvious
2150 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2152 struct acx111_ie_tx_level tx_level;
2154 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2155 * 1 (30mW) [15dBm]
2156 * 2 (10mW) [10dBm]
2157 * For now, just assume all other acx111 cards have the same.
2158 * FIXME: Ideally we would query it here, but we first need a
2159 * standard way to query individual configoptions easily.
2160 * Well, now we have proper cfgopt txpower variables, but this still
2161 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2162 if (level_dbm <= 12) {
2163 tx_level.level = 2; /* 10 dBm */
2164 adev->tx_level_dbm = 10;
2165 } else {
2166 tx_level.level = 1; /* 15 dBm */
2167 adev->tx_level_dbm = 15;
2169 if (level_dbm != adev->tx_level_dbm)
2170 acx_log(LOG_WARNING, L_INIT, "acx111 firmware has specific "
2171 "power levels only: adjusted %d dBm to %d dBm!\n",
2172 level_dbm, adev->tx_level_dbm);
2174 return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
2177 static int acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
2179 if (IS_ACX111(adev)) {
2180 return acx111_s_set_tx_level(adev, level_dbm);
2182 if (IS_PCI(adev)) {
2183 return acx100pci_s_set_tx_level(adev, level_dbm);
2186 return OK;
2190 /***********************************************************************
2191 ** acx_s_set_defaults
2193 void acx_s_set_defaults(acx_device_t * adev)
2195 struct ieee80211_conf *conf = &adev->ieee->conf;
2196 unsigned long flags;
2197 u16 default_irq_mask = (IS_ACX111(adev)) ?
2198 ACX111_DEFAULT_IRQ_MASK :
2199 ACX100_DEFAULT_IRQ_MASK;
2201 FN_ENTER;
2203 acx_lock(adev, flags);
2204 /* do it before getting settings, prevent bogus channel 0 warning */
2205 adev->channel = 1;
2207 /* query some settings from the card.
2208 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2209 * query is REQUIRED, otherwise the card won't work correctly! */
2210 adev->get_mask =
2211 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2212 GETSET_REG_DOMAIN;
2213 /* Only ACX100 supports ED and CCA */
2214 if (IS_ACX100(adev))
2215 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2217 acx_unlock(adev, flags);
2219 acx_s_update_card_settings(adev);
2221 acx_lock(adev, flags);
2223 /* set our global interrupt mask */
2224 if (IS_PCI(adev))
2225 adev->irq_mask = default_irq_mask;
2227 adev->led_power = 1; /* LED is active on startup */
2228 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2229 adev->brange_time_last_state_change = jiffies;
2231 /* copy the MAC address we just got from the card
2232 * into our MAC address used during current 802.11 session */
2233 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
2234 MAC_BCAST(adev->ap);
2236 adev->essid_len =
2237 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2238 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2239 adev->essid_active = 1;
2241 /* we have a nick field to waste, so why not abuse it
2242 * to announce the driver version? ;-) */
2243 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2245 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2246 /* first regulatory domain entry in EEPROM == default reg. domain */
2247 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2250 /* 0xffff would be better, but then we won't get a "scan complete"
2251 * interrupt, so our current infrastructure will fail: */
2252 adev->scan_count = 1;
2253 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2254 adev->scan_duration = 100;
2255 adev->scan_probe_delay = 200;
2256 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2257 adev->scan_rate = ACX_SCAN_RATE_1;
2260 adev->mode = ACX_MODE_2_STA;
2261 adev->listen_interval = 100;
2262 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2263 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2265 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2267 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2268 adev->frag_threshold = 2346;
2270 /* use standard default values for retry limits */
2271 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2272 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2274 adev->preamble_mode = 2; /* auto */
2275 adev->fallback_threshold = 3;
2276 adev->stepup_threshold = 10;
2277 adev->rate_bcast = RATE111_1;
2278 adev->rate_bcast100 = RATE100_1;
2279 adev->rate_basic = RATE111_1 | RATE111_2;
2280 adev->rate_auto = 1;
2281 if (IS_ACX111(adev)) {
2282 adev->rate_oper = RATE111_ALL;
2283 } else {
2284 adev->rate_oper = RATE111_ACX100_COMPAT;
2287 /* Supported Rates element - the rates here are given in units of
2288 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2289 acx_l_update_ratevector(adev);
2291 /* set some more defaults */
2292 if (IS_ACX111(adev)) {
2293 /* 30mW (15dBm) is default, at least in my acx111 card: */
2294 adev->tx_level_dbm = 15;
2295 conf->power_level = adev->tx_level_dbm;
2296 acx_unlock(adev, flags);
2297 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2298 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2299 acx_lock(adev, flags);
2300 } else {
2301 /* don't use max. level, since it might be dangerous
2302 * (e.g. WRT54G people experience
2303 * excessive Tx power damage!) */
2304 adev->tx_level_dbm = 18;
2305 conf->power_level = adev->tx_level_dbm;
2306 acx_unlock(adev, flags);
2307 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2308 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2309 acx_lock(adev, flags);
2312 /* adev->tx_level_auto = 1; */
2313 if (IS_ACX111(adev)) {
2314 /* start with sensitivity level 1 out of 3: */
2315 adev->sensitivity = 1;
2318 /* #define ENABLE_POWER_SAVE */
2319 #ifdef ENABLE_POWER_SAVE
2320 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2321 adev->ps_listen_interval = 1;
2322 adev->ps_options =
2323 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2324 adev->ps_hangover_period = 30;
2325 adev->ps_enhanced_transition_time = 0;
2326 #else
2327 adev->ps_wakeup_cfg = 0;
2328 adev->ps_listen_interval = 0;
2329 adev->ps_options = 0;
2330 adev->ps_hangover_period = 0;
2331 adev->ps_enhanced_transition_time = 0;
2332 #endif
2334 /* These settings will be set in fw on ifup */
2335 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2336 /* configure card to do rate fallback when in auto rate mode */
2337 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2338 /* better re-init the antenna value we got above */
2339 | GETSET_ANTENNA
2340 #if POWER_SAVE_80211
2341 | GETSET_POWER_80211
2342 #endif
2345 acx_unlock(adev, flags);
2346 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2348 acx_s_initialize_rx_config(adev);
2350 FN_EXIT0;
2354 /***********************************************************************
2355 ** acx_l_process_rxbuf
2357 ** NB: used by USB code also
2359 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2361 struct ieee80211_hdr *hdr;
2362 u16 fc, buf_len;
2364 FN_ENTER;
2366 hdr = acx_get_wlan_hdr(adev, rxbuf);
2367 fc = le16_to_cpu(hdr->frame_control);
2368 /* length of frame from control field to first byte of FCS */
2369 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2371 acx_log_dump(LOG_DEBUG, L_DATA, hdr, buf_len, "RX: 802.11 buffer:\n");
2373 acx_l_rx(adev, rxbuf);
2374 /* Now check Rx quality level, AFTER processing packet.
2375 * I tried to figure out how to map these levels to dBm
2376 * values, but for the life of me I really didn't
2377 * manage to get it. Either these values are not meant to
2378 * be expressed in dBm, or it's some pretty complicated
2379 * calculation. */
2381 #ifdef FROM_SCAN_SOURCE_ONLY
2382 /* only consider packets originating from the MAC
2383 * address of the device that's managing our BSSID.
2384 * Disable it for now, since it removes information (levels
2385 * from different peers) and slows the Rx path. *//*
2386 if (adev->ap_client && mac_is_equal(hdr->a2, adev->ap_client->address)) {
2388 #endif
2390 FN_EXIT0;
2394 /***********************************************************************
2395 ** acx_l_handle_txrate_auto
2397 ** Theory of operation:
2398 ** client->rate_cap is a bitmask of rates client is capable of.
2399 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2400 ** It is set as a result of iwconfig rate N [auto]
2401 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2402 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2403 ** auto (0x00ff == 18Mbit or any lower value),
2404 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2406 ** client->rate_cur is a value for rate111 field in tx descriptor.
2407 ** It is always set to txrate_cfg sans zero or more most significant
2408 ** bits. This routine handles selection of new rate_cur value depending on
2409 ** outcome of last tx event.
2411 ** client->rate_100 is a precalculated rate value for acx100
2412 ** (we can do without it, but will need to calculate it on each tx).
2414 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2415 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2416 ** In theory you can implement it, but so far it is considered not worth doing.
2418 ** 22Mbit, of course, is PBCC always. */
2420 /* maps acx100 tx descr rate field to acx111 one */
2422 static u16 rate100to111(u8 r)
2424 switch (r) {
2425 case RATE100_1:
2426 return RATE111_1;
2427 case RATE100_2:
2428 return RATE111_2;
2429 case RATE100_5:
2430 case (RATE100_5 | RATE100_PBCC511):
2431 return RATE111_5;
2432 case RATE100_11:
2433 case (RATE100_11 | RATE100_PBCC511):
2434 return RATE111_11;
2435 case RATE100_22:
2436 return RATE111_22;
2437 default:
2438 printk("acx: unexpected acx100 txrate: %u! "
2439 "Please report\n", r);
2440 return RATE111_1;
2447 acx_i_start_xmit(struct ieee80211_hw *hw,
2448 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2450 acx_device_t *adev = ieee2adev(hw);
2451 tx_t *tx;
2452 void *txbuf;
2453 unsigned long flags;
2455 int txresult = NOT_OK;
2457 FN_ENTER;
2459 if (unlikely(!skb)) {
2460 /* indicate success */
2461 txresult = OK;
2462 goto out;
2465 if (unlikely(!adev)) {
2466 goto out;
2469 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2470 goto out;
2472 if (unlikely(!adev->initialized)) {
2473 goto out;
2476 acx_lock(adev, flags);
2478 tx = acx_l_alloc_tx(adev);
2480 if (unlikely(!tx)) {
2481 acx_log_ratelimited(LOG_WARNING, L_ANY, "%s: start_xmit: "
2482 "txdesc ring is full, dropping tx\n",
2483 wiphy_name(adev->ieee->wiphy));
2484 txresult = NOT_OK;
2485 goto out_unlock;
2488 txbuf = acx_l_get_txbuf(adev, tx);
2490 if (unlikely(!txbuf)) {
2491 /* Card was removed */
2492 txresult = NOT_OK;
2493 acx_l_dealloc_tx(adev, tx);
2494 goto out_unlock;
2496 memcpy(txbuf, skb->data, skb->len);
2498 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2500 txresult = OK;
2501 adev->stats.tx_packets++;
2502 adev->stats.tx_bytes += skb->len;
2504 out_unlock:
2505 acx_unlock(adev, flags);
2507 out:
2508 FN_EXIT1(txresult);
2509 return txresult;
2511 /***********************************************************************
2512 ** acx_l_update_ratevector
2514 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2516 const u8 acx_bitpos2ratebyte[] = {
2517 DOT11RATEBYTE_1,
2518 DOT11RATEBYTE_2,
2519 DOT11RATEBYTE_5_5,
2520 DOT11RATEBYTE_6_G,
2521 DOT11RATEBYTE_9_G,
2522 DOT11RATEBYTE_11,
2523 DOT11RATEBYTE_12_G,
2524 DOT11RATEBYTE_18_G,
2525 DOT11RATEBYTE_22,
2526 DOT11RATEBYTE_24_G,
2527 DOT11RATEBYTE_36_G,
2528 DOT11RATEBYTE_48_G,
2529 DOT11RATEBYTE_54_G,
2532 void acx_l_update_ratevector(acx_device_t * adev)
2534 u16 bcfg = adev->rate_basic;
2535 u16 ocfg = adev->rate_oper;
2536 u8 *supp = adev->rate_supported;
2537 const u8 *dot11 = acx_bitpos2ratebyte;
2539 FN_ENTER;
2541 while (ocfg) {
2542 if (ocfg & 1) {
2543 *supp = *dot11;
2544 if (bcfg & 1) {
2545 *supp |= 0x80;
2547 supp++;
2549 dot11++;
2550 ocfg >>= 1;
2551 bcfg >>= 1;
2553 adev->rate_supported_len = supp - adev->rate_supported;
2555 acx_log_dump(LOG_DEBUG, L_ASSOC, adev->rate_supported,
2556 adev->rate_supported_len, "new ratevector:\n");
2558 FN_EXIT0;
2561 /***********************************************************************
2562 ** acx_i_timer
2564 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2566 ** Obvious
2568 void acx_i_timer(unsigned long address)
2570 unsigned long flags;
2571 acx_device_t *adev = (acx_device_t *) address;
2573 FN_ENTER;
2575 acx_lock(adev, flags);
2577 FIXME();
2578 /* We need calibration and stats gather tasks to perform here */
2580 acx_unlock(adev, flags);
2582 FN_EXIT0;
2586 /***********************************************************************
2587 ** acx_set_timer
2589 ** Sets the 802.11 state management timer's timeout.
2591 ** Linux derived
2593 void acx_set_timer(acx_device_t * adev, int timeout_us)
2595 FN_ENTER;
2597 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_IRQ,
2598 "%s(%u ms)\n", __func__, timeout_us / 1000);
2600 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2601 acx_log(LOG_WARNING, L_ANY, "attempt to set the timer "
2602 "when the card interface is not up!\n");
2603 goto end;
2606 /* first check if the timer was already initialized, THEN modify it */
2607 if (adev->mgmt_timer.function) {
2608 mod_timer(&adev->mgmt_timer,
2609 jiffies + (timeout_us * HZ / 1000000));
2611 end:
2612 FN_EXIT0;
2615 /** acx_plcp_get_bitrate_cck
2617 ** Obvious
2619 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2621 switch (plcp) {
2622 case 0x0A:
2623 return ACX_CCK_RATE_1MB;
2624 case 0x14:
2625 return ACX_CCK_RATE_2MB;
2626 case 0x37:
2627 return ACX_CCK_RATE_5MB;
2628 case 0x6E:
2629 return ACX_CCK_RATE_11MB;
2631 return 0;
2634 /* Extract the bitrate out of an OFDM PLCP header. */
2635 /** Obvious **/
2636 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2638 switch (plcp & 0xF) {
2639 case 0xB:
2640 return ACX_OFDM_RATE_6MB;
2641 case 0xF:
2642 return ACX_OFDM_RATE_9MB;
2643 case 0xA:
2644 return ACX_OFDM_RATE_12MB;
2645 case 0xE:
2646 return ACX_OFDM_RATE_18MB;
2647 case 0x9:
2648 return ACX_OFDM_RATE_24MB;
2649 case 0xD:
2650 return ACX_OFDM_RATE_36MB;
2651 case 0x8:
2652 return ACX_OFDM_RATE_48MB;
2653 case 0xC:
2654 return ACX_OFDM_RATE_54MB;
2656 return 0;
2660 /***********************************************************************
2661 ** acx_l_rx
2663 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2664 ** buffer and feeds it to the network stack via netif_rx().
2666 ** Look to bcm43xx or p54
2668 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2671 struct ieee80211_rx_status* status = &adev->rx_status;
2672 struct ieee80211_hdr *w_hdr;
2673 struct sk_buff *skb;
2674 int buflen;
2675 FN_ENTER;
2677 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2678 acx_log_ratelimited(LOG_WARNING, L_ANY,
2679 "asked to receive a packet but interface is down??\n");
2680 goto out;
2683 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2684 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2686 * Allocate our skb
2688 skb = dev_alloc_skb(buflen + 2);
2690 if (!skb) {
2691 acx_log_ratelimited(LOG_WARNING, L_ANY,
2692 "skb allocation FAILED\n");
2693 goto out;
2696 skb_reserve(skb, 2);
2697 skb_put(skb, buflen);
2698 memcpy(skb->data, w_hdr, buflen);
2700 // memset(&status, 0, sizeof(status));
2702 status->mactime = rxbuf->time;
2703 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2704 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr);
2705 status->flag = 0;
2706 status->rate = rxbuf->phy_plcp_signal;
2707 status->antenna = 1;
2708 if (rxbuf->phy_stat_baseband & (1 << 3)) { /* Uses OFDM */
2709 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2710 } else {
2711 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2715 * FIXME: should it really be done here??
2717 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2718 adev->stats.rx_packets++;
2719 adev->stats.rx_bytes += skb->len;
2720 out:
2721 FN_EXIT0;
2726 /***********************************************************************
2727 ** acx_s_read_fw
2729 ** Loads a firmware image
2731 ** Returns:
2732 ** 0 unable to load file
2733 ** pointer to firmware success
2735 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2736 u32 * size)
2738 firmware_image_t *res;
2739 const struct firmware *fw_entry;
2741 res = NULL;
2742 acx_log(LOG_INFO, L_INIT, "requesting firmware image '%s'\n", file);
2743 if (!request_firmware(&fw_entry, file, dev)) {
2744 *size = 8;
2745 if (fw_entry->size >= 8)
2746 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2747 if (fw_entry->size != *size) {
2748 acx_log(LOG_WARNING, L_ANY,
2749 "acx: firmware size does not match "
2750 "firmware header: %d != %d, "
2751 "aborting fw upload\n",
2752 (int)fw_entry->size, (int)*size);
2753 goto release_ret;
2755 res = vmalloc(*size);
2756 if (!res) {
2757 acx_log(LOG_INFO, L_ANY, "acx: no memory for firmware "
2758 "(%u bytes)\n", *size);
2759 goto release_ret;
2761 memcpy(res, fw_entry->data, fw_entry->size);
2762 release_ret:
2763 release_firmware(fw_entry);
2764 return res;
2766 acx_log(LOG_WARNING, L_ANY, "acx: firmware image '%s' was not provided. "
2767 "Check your hotplug scripts\n", file);
2769 /* checksum will be verified in write_fw, so don't bother here */
2770 return res;
2774 /***********************************************************************
2775 ** acx_s_set_wepkey
2777 static void acx100_s_set_wepkey(acx_device_t * adev)
2779 ie_dot11WEPDefaultKey_t dk;
2780 int i;
2782 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2783 if (adev->wep_keys[i].size != 0) {
2784 acx_log(LOG_DEBUG, L_INIT, "setting WEP key: %d with "
2785 "total size: %d\n",
2786 i, (int)adev->wep_keys[i].size);
2787 dk.action = 1;
2788 dk.keySize = adev->wep_keys[i].size;
2789 dk.defaultKeyNum = i;
2790 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2791 acx_s_configure(adev, &dk,
2792 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
2797 static void acx111_s_set_wepkey(acx_device_t * adev)
2799 acx111WEPDefaultKey_t dk;
2800 int i;
2802 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2803 if (adev->wep_keys[i].size != 0) {
2804 acx_log(LOG_DEBUG, L_INIT, "setting WEP key: %d with "
2805 "total size: %d\n", i,
2806 (int)adev->wep_keys[i].size);
2807 memset(&dk, 0, sizeof(dk));
2808 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2809 dk.keySize = adev->wep_keys[i].size;
2811 /* are these two lines necessary? */
2812 dk.type = 0; /* default WEP key */
2813 dk.index = 0; /* ignored when setting default key */
2815 dk.defaultKeyNum = i;
2816 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2817 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2818 sizeof(dk));
2822 /* Obvious */
2823 static void acx_s_set_wepkey(acx_device_t * adev)
2825 if (IS_ACX111(adev))
2826 acx111_s_set_wepkey(adev);
2827 else
2828 acx100_s_set_wepkey(adev);
2832 /***********************************************************************
2833 ** acx100_s_init_wep
2835 ** FIXME: this should probably be moved into the new card settings
2836 ** management, but since we're also modifying the memory map layout here
2837 ** due to the WEP key space we want, we should take care...
2839 static int acx100_s_init_wep(acx_device_t * adev)
2841 acx100_ie_wep_options_t options;
2842 ie_dot11WEPDefaultKeyID_t dk;
2843 acx_ie_memmap_t pt;
2844 int res = NOT_OK;
2846 FN_ENTER;
2848 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2849 goto fail;
2852 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "CodeEnd:%X\n", pt.CodeEnd);
2854 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2855 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2857 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2858 goto fail;
2861 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2862 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2863 options.WEPOption = 0x00;
2865 acx_log(LOG_DEBUG, L_ASSOC, "writing WEP options\n");
2866 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
2868 acx100_s_set_wepkey(adev);
2870 if (adev->wep_keys[adev->wep_current_index].size != 0) {
2871 acx_log(LOG_DEBUG, L_ASSOC,
2872 "setting active default WEP key number: %d\n",
2873 adev->wep_current_index);
2874 dk.KeyID = adev->wep_current_index;
2875 acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
2877 /* FIXME!!! wep_key_struct is filled nowhere! But adev
2878 * is initialized to 0, and we don't REALLY need those keys either */
2879 /* for (i = 0; i < 10; i++) {
2880 if (adev->wep_key_struct[i].len != 0) {
2881 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
2882 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
2883 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
2884 wep_mgmt.Action = cpu_to_le16(1);
2885 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
2886 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
2887 adev->wep_key_struct[i].index = i;
2893 /* now retrieve the updated WEPCacheEnd pointer... */
2894 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2895 acx_log(LOG_WARNING, L_ANY,
2896 "%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
2897 wiphy_name(adev->ieee->wiphy));
2898 goto fail;
2900 /* ...and tell it to start allocating templates at that location */
2901 /* (no endianness conversion needed) */
2902 pt.PacketTemplateStart = pt.WEPCacheEnd;
2904 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2905 acx_log(LOG_WARNING, L_ANY,
2906 "%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
2907 wiphy_name(adev->ieee->wiphy));
2908 goto fail;
2910 res = OK;
2912 fail:
2913 FN_EXIT1(res);
2914 return res;
2918 static int
2919 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
2920 unsigned int cmd)
2922 int res;
2923 union {
2924 acx_template_nullframe_t null;
2925 acx_template_beacon_t b;
2926 acx_template_tim_t tim;
2927 acx_template_probereq_t preq;
2928 acx_template_proberesp_t presp;
2929 } templ;
2931 memset(&templ, 0, len);
2932 templ.null.size = cpu_to_le16(len - 2);
2933 res = acx_s_issue_cmd(adev, cmd, &templ, len);
2934 return res;
2937 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
2939 return acx_s_init_max_template_generic(adev,
2940 sizeof(acx_template_nullframe_t),
2941 ACX1xx_CMD_CONFIG_NULL_DATA);
2944 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
2946 return acx_s_init_max_template_generic(adev,
2947 sizeof(acx_template_beacon_t),
2948 ACX1xx_CMD_CONFIG_BEACON);
2951 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
2953 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
2954 ACX1xx_CMD_CONFIG_TIM);
2957 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
2959 return acx_s_init_max_template_generic(adev,
2960 sizeof(acx_template_proberesp_t),
2961 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
2964 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
2966 return acx_s_init_max_template_generic(adev,
2967 sizeof(acx_template_probereq_t),
2968 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
2971 /***********************************************************************
2972 ** acx_s_set_tim_template
2974 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
2975 ** by calling this function
2976 ** (it can be done by irq handler on each DTIM irq or by timer...)
2978 [802.11 7.3.2.6] TIM information element:
2979 - 1 EID
2980 - 1 Length
2981 1 1 DTIM Count
2982 indicates how many beacons (including this) appear before next DTIM
2983 (0=this one is a DTIM)
2984 2 1 DTIM Period
2985 number of beacons between successive DTIMs
2986 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
2987 3 1 Bitmap Control
2988 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
2989 set to 1 in TIM elements with a value of 0 in the DTIM Count field
2990 when one or more broadcast or multicast frames are buffered at the AP.
2991 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
2992 4 n Partial Virtual Bitmap
2993 Visible part of traffic-indication bitmap.
2994 Full bitmap consists of 2008 bits (251 octets) such that bit number N
2995 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
2996 in octet number N/8 where the low-order bit of each octet is bit0,
2997 and the high order bit is bit7.
2998 Each set bit in virtual bitmap corresponds to traffic buffered by AP
2999 for a specific station (with corresponding AID?).
3000 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
3001 Bitmap Offset is a number of skipped zero octets (see above).
3002 'Missing' octets at the tail are also assumed to be zero.
3003 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
3004 This means that traffic-indication bitmap is:
3005 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
3006 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
3008 static int acx_s_set_tim_template(acx_device_t * adev)
3010 /* For now, configure smallish test bitmap, all zero ("no pending data") */
3011 enum { bitmap_size = 5 };
3013 acx_template_tim_t t;
3014 int result;
3016 FN_ENTER;
3018 memset(&t, 0, sizeof(t));
3019 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3020 t.tim_eid = WLAN_EID_TIM;
3021 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3022 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3023 FN_EXIT1(result);
3024 return result;
3030 #if POWER_SAVE_80211
3031 /***********************************************************************
3032 ** acx_s_set_null_data_template
3034 static int acx_s_set_null_data_template(acx_device_t * adev)
3036 struct acx_template_nullframe b;
3037 int result;
3039 FN_ENTER;
3041 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3043 b.size = cpu_to_le16(sizeof(b) - 2);
3044 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3045 b.hdr.dur = 0;
3046 MAC_BCAST(b.hdr.a1);
3047 MAC_COPY(b.hdr.a2, adev->dev_addr);
3048 MAC_COPY(b.hdr.a3, adev->bssid);
3049 b.hdr.seq = 0;
3051 result =
3052 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3054 FN_EXIT1(result);
3055 return result;
3057 #endif
3064 /***********************************************************************
3065 ** acx_s_init_packet_templates()
3067 ** NOTE: order is very important here, to have a correct memory layout!
3068 ** init templates: max Probe Request (station mode), max NULL data,
3069 ** max Beacon, max TIM, max Probe Response.
3071 static int acx_s_init_packet_templates(acx_device_t * adev)
3073 acx_ie_memmap_t mm; /* ACX100 only */
3074 int result = NOT_OK;
3076 FN_ENTER;
3078 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_INIT,
3079 "initializing max packet templates\n");
3081 if (OK != acx_s_init_max_probe_request_template(adev))
3082 goto failed;
3084 if (OK != acx_s_init_max_null_data_template(adev))
3085 goto failed;
3087 if (OK != acx_s_init_max_beacon_template(adev))
3088 goto failed;
3090 if (OK != acx_s_init_max_tim_template(adev))
3091 goto failed;
3093 if (OK != acx_s_init_max_probe_response_template(adev))
3094 goto failed;
3096 if (IS_ACX111(adev)) {
3097 /* ACX111 doesn't need the memory map magic below,
3098 * and the other templates will be set later (acx_start) */
3099 result = OK;
3100 goto success;
3103 /* ACX100 will have its TIM template set,
3104 * and we also need to update the memory map */
3106 if (OK != acx_s_set_tim_template(adev))
3107 goto failed_acx100;
3109 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
3110 "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3112 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3113 goto failed_acx100;
3115 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3116 if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3117 goto failed_acx100;
3119 result = OK;
3120 goto success;
3122 failed_acx100:
3123 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_INIT,
3124 /* "cb=0x%X\n" */
3125 "ACXMemoryMap:\n"
3126 ".CodeStart=0x%X\n"
3127 ".CodeEnd=0x%X\n"
3128 ".WEPCacheStart=0x%X\n"
3129 ".WEPCacheEnd=0x%X\n"
3130 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3131 /* len, */
3132 le32_to_cpu(mm.CodeStart),
3133 le32_to_cpu(mm.CodeEnd),
3134 le32_to_cpu(mm.WEPCacheStart),
3135 le32_to_cpu(mm.WEPCacheEnd),
3136 le32_to_cpu(mm.PacketTemplateStart),
3137 le32_to_cpu(mm.PacketTemplateEnd));
3139 failed:
3140 acx_log(LOG_WARNING, L_ANY, "%s: %s() FAILED\n",
3141 wiphy_name(adev->ieee->wiphy), __func__);
3143 success:
3144 FN_EXIT1(result);
3145 return result;
3150 /***********************************************************************
3151 ** acx_s_init_mac
3153 int acx_s_init_mac(acx_device_t * adev)
3155 int result = NOT_OK;
3157 FN_ENTER;
3159 if (IS_ACX111(adev)) {
3160 adev->ie_len = acx111_ie_len;
3161 adev->ie_len_dot11 = acx111_ie_len_dot11;
3162 } else {
3163 adev->ie_len = acx100_ie_len;
3164 adev->ie_len_dot11 = acx100_ie_len_dot11;
3167 if (IS_PCI(adev)) {
3168 adev->memblocksize = 256; /* 256 is default */
3169 /* try to load radio for both ACX100 and ACX111, since both
3170 * chips have at least some firmware versions making use of an
3171 * external radio module */
3172 acxpci_s_upload_radio(adev);
3173 } else {
3174 adev->memblocksize = 128;
3177 if (IS_ACX111(adev)) {
3178 /* for ACX111, the order is different from ACX100
3179 1. init packet templates
3180 2. create station context and create dma regions
3181 3. init wep default keys
3183 if (OK != acx_s_init_packet_templates(adev))
3184 goto fail;
3185 if (OK != acx111_s_create_dma_regions(adev)) {
3186 acx_log(LOG_WARNING, L_ANY,
3187 "%s: acx111_create_dma_regions FAILED\n",
3188 wiphy_name(adev->ieee->wiphy));
3189 goto fail;
3191 } else {
3192 if (OK != acx100_s_init_wep(adev))
3193 goto fail;
3194 if (OK != acx_s_init_packet_templates(adev))
3195 goto fail;
3196 if (OK != acx100_s_create_dma_regions(adev)) {
3197 acx_log(LOG_WARNING, L_ANY,
3198 "%s: acx100_create_dma_regions FAILED\n",
3199 wiphy_name(adev->ieee->wiphy));
3200 goto fail;
3204 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3205 result = OK;
3207 fail:
3208 if (result)
3209 acx_log(LOG_WARNING, L_ANY, "init_mac() FAILED\n");
3210 FN_EXIT1(result);
3211 return result;
3216 #if POWER_SAVE_80211
3217 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3219 /* merge both structs in a union to be able to have common code */
3220 union {
3221 acx111_ie_powersave_t acx111;
3222 acx100_ie_powersave_t acx100;
3223 } pm;
3225 /* change 802.11 power save mode settings */
3226 acx_log(LOG_DEBUG, L_INIT, "updating 802.11 power save mode settings: "
3227 "wakeup_cfg 0x%02X, listen interval %u, "
3228 "options 0x%02X, hangover period %u, "
3229 "enhanced_ps_transition_time %u\n",
3230 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3231 adev->ps_options, adev->ps_hangover_period,
3232 adev->ps_enhanced_transition_time);
3233 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3234 acx_log(LOG_DEBUG, L_INIT, "Previous PS mode settings: "
3235 "wakeup_cfg 0x%02X, "
3236 "listen interval %u, options 0x%02X, "
3237 "hangover period %u, "
3238 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3239 pm.acx111.wakeup_cfg,
3240 pm.acx111.listen_interval,
3241 pm.acx111.options,
3242 pm.acx111.hangover_period,
3243 IS_ACX111(adev) ?
3244 pm.acx111.enhanced_ps_transition_time
3245 : pm.acx100.enhanced_ps_transition_time,
3246 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3247 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3248 pm.acx111.listen_interval = adev->ps_listen_interval;
3249 pm.acx111.options = adev->ps_options;
3250 pm.acx111.hangover_period = adev->ps_hangover_period;
3251 if (IS_ACX111(adev)) {
3252 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3253 pm.acx111.enhanced_ps_transition_time =
3254 cpu_to_le32(adev->ps_enhanced_transition_time);
3255 } else {
3256 pm.acx100.enhanced_ps_transition_time =
3257 cpu_to_le16(adev->ps_enhanced_transition_time);
3259 acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT);
3260 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3261 acx_log(LOG_DEBUG, L_INIT, "wakeup_cfg: 0x%02X\n",
3262 pm.acx111.wakeup_cfg);
3263 acx_s_mwait(40);
3264 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3265 acx_log(LOG_DEBUG, L_INIT, "wakeup_cfg: 0x%02X\n",
3266 pm.acx111.wakeup_cfg);
3267 acx_log(LOG_DEBUG, L_INIT, "power save mode change %s\n",
3268 (pm.acx111.wakeup_cfg & PS_CFG_PENDING) ?
3269 "FAILED" : "was successful");
3270 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3271 * that power save mode change was successful. */
3272 /* FIXME: we shouldn't trigger a scan immediately after
3273 * fiddling with power save mode (since the firmware is sending
3274 * a NULL frame then). */
3276 #endif
3279 /***********************************************************************
3280 ** acx_s_update_card_settings
3282 ** Applies accumulated changes in various adev->xxxx members
3283 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3284 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3286 void acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
3288 unsigned mask;
3290 unsigned int i;
3292 for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
3293 if (acx_reg_domain_ids[i] == adev->reg_dom_id)
3294 break;
3296 if (sizeof(acx_reg_domain_ids) == i) {
3297 acx_log(LOG_WARNING, L_INIT,
3298 "Invalid or unsupported regulatory domain"
3299 " 0x%02X specified, falling back to FCC (USA)!"
3300 " Please report if this sounds fishy!\n",
3301 adev->reg_dom_id);
3302 i = 0;
3303 adev->reg_dom_id = acx_reg_domain_ids[i];
3305 /* since there was a mismatch, we need to force updating */
3306 do_set = 1;
3309 if (do_set) {
3310 acx_ie_generic_t dom;
3311 dom.m.bytes[0] = adev->reg_dom_id;
3312 acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3315 adev->reg_dom_chanmask = reg_domain_channel_masks[i];
3317 mask = (1 << (adev->channel - 1));
3320 * Check our channels wrt the current regulatory domain
3322 if (adev->reg_dom_chanmask & mask)
3323 return;
3326 * Hmm nope, need to adjust channels!
3329 mask = 1;
3330 for (i = 1; i <= 14; i++) {
3331 if (!(adev->reg_dom_chanmask & mask)) {
3332 mask <<= 1;
3333 continue;
3335 acx_log(LOG_INFO, L_ANY, "%s: adjusting selected channel "
3336 "from %d to %d due to new regulatory domain\n",
3337 wiphy_name(adev->ieee->wiphy), adev->channel, i);
3338 adev->channel = i;
3339 break;
3343 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3345 u32 feature1, feature2;
3347 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3348 acx_log(LOG_WARNING, L_ANY,
3349 "%s: invalid sensitivity setting (1..3), "
3350 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3351 adev->sensitivity = 1;
3353 acx111_s_get_feature_config(adev, &feature1, &feature2);
3354 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3355 if (adev->sensitivity > 1)
3356 SET_BIT(feature1, FEATURE1_LOW_RX);
3357 if (adev->sensitivity > 2)
3358 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3359 acx111_s_feature_set(adev, feature1, feature2);
3363 void acx_s_update_card_settings(acx_device_t *adev)
3365 unsigned long flags;
3366 unsigned int start_scan = 0;
3367 int i;
3369 FN_ENTER;
3371 acx_log(LOG_DEBUG, L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3372 adev->get_mask, adev->set_mask);
3374 /* Track dependencies betweed various settings */
3376 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3377 acx_log(LOG_DEBUG, L_INIT,
3378 "important setting has been changed. "
3379 "Need to update packet templates, too\n");
3380 SET_BIT(adev->set_mask, SET_TEMPLATES);
3382 if (adev->set_mask & GETSET_CHANNEL) {
3383 /* This will actually tune RX/TX to the channel */
3384 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3385 switch (adev->mode) {
3386 case ACX_MODE_0_ADHOC:
3387 case ACX_MODE_3_AP:
3388 /* Beacons contain channel# - update them */
3389 SET_BIT(adev->set_mask, SET_TEMPLATES);
3392 switch (adev->mode) {
3393 case ACX_MODE_0_ADHOC:
3394 case ACX_MODE_2_STA:
3395 start_scan = 1;
3399 /* Apply settings */
3402 if (adev->get_mask & GETSET_STATION_ID) {
3403 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3404 const u8 *paddr;
3406 acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3407 paddr = &stationID[4];
3408 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3409 for (i = 0; i < ETH_ALEN; i++) {
3410 /* we copy the MAC address (reversed in
3411 * the card) to the netdevice's MAC
3412 * address, and on ifup it will be
3413 * copied into iwadev->dev_addr */
3414 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3416 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3417 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3420 if (adev->get_mask & GETSET_SENSITIVITY) {
3421 if ((RADIO_RFMD_11 == adev->radio_type)
3422 || (RADIO_MAXIM_0D == adev->radio_type)
3423 || (RADIO_RALINK_15 == adev->radio_type)) {
3424 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3425 } else {
3426 acx_log(LOG_WARNING, L_INIT,
3427 "don't know how to get sensitivity "
3428 "for radio type 0x%02X\n", adev->radio_type);
3429 adev->sensitivity = 0;
3431 acx_log(LOG_DEBUG, L_INIT, "got sensitivity value %u\n",
3432 adev->sensitivity);
3434 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3437 if (adev->get_mask & GETSET_ANTENNA) {
3438 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3440 memset(antenna, 0, sizeof(antenna));
3441 acx_s_interrogate(adev, antenna,
3442 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3443 adev->antenna = antenna[4];
3444 acx_log(LOG_INFO, L_INIT, "got antenna value 0x%02X\n",
3445 adev->antenna);
3446 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3449 if (adev->get_mask & GETSET_ED_THRESH) {
3450 if (IS_ACX100(adev)) {
3451 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3453 memset(ed_threshold, 0, sizeof(ed_threshold));
3454 acx_s_interrogate(adev, ed_threshold,
3455 ACX100_IE_DOT11_ED_THRESHOLD);
3456 adev->ed_threshold = ed_threshold[4];
3457 } else {
3458 acx_log(LOG_WARNING, L_INIT,
3459 "acx111 doesn't support ED\n");
3460 adev->ed_threshold = 0;
3462 acx_log(LOG_INFO, L_INIT,
3463 "got Energy Detect (ED) threshold %u\n",
3464 adev->ed_threshold);
3465 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3468 if (adev->get_mask & GETSET_CCA) {
3469 if (IS_ACX100(adev)) {
3470 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3472 memset(cca, 0, sizeof(adev->cca));
3473 acx_s_interrogate(adev, cca,
3474 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3475 adev->cca = cca[4];
3476 } else {
3477 acx_log(LOG_WARNING, L_INIT,
3478 "acx111 doesn't support CCA\n");
3479 adev->cca = 0;
3481 acx_log(LOG_INFO, L_INIT,
3482 "got Channel Clear Assessment (CCA) value %u\n",
3483 adev->cca);
3484 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3487 if (adev->get_mask & GETSET_REG_DOMAIN) {
3488 acx_ie_generic_t dom;
3490 acx_s_interrogate(adev, &dom,
3491 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3492 adev->reg_dom_id = dom.m.bytes[0];
3493 acx_s_set_sane_reg_domain(adev, 0);
3494 acx_log(LOG_INFO, L_INIT,
3495 "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3496 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3499 if (adev->set_mask & GETSET_STATION_ID) {
3500 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3501 u8 *paddr;
3503 paddr = &stationID[4];
3504 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3505 for (i = 0; i < ETH_ALEN; i++) {
3506 /* copy the MAC address we obtained when we noticed
3507 * that the ethernet iface's MAC changed
3508 * to the card (reversed in
3509 * the card!) */
3510 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3512 acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3513 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3516 if (adev->set_mask & SET_STA_LIST) {
3517 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3519 if (adev->set_mask & SET_RATE_FALLBACK) {
3520 u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
3522 /* configure to not do fallbacks when not in auto rate mode */
3523 rate[4] =
3524 (adev->
3525 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3526 acx_log(LOG_DEBUG, L_INIT,
3527 "updating Tx fallback to %u retries\n", rate[4]);
3528 acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK);
3529 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3531 if (adev->set_mask & GETSET_TXPOWER) {
3532 acx_log(LOG_DEBUG, L_INIT, "updating transmit power: %u dBm\n",
3533 adev->tx_level_dbm);
3534 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3535 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3538 if (adev->set_mask & GETSET_SENSITIVITY) {
3539 acx_log(LOG_DEBUG, L_INIT, "updating sensitivity value: %u\n",
3540 adev->sensitivity);
3541 switch (adev->radio_type) {
3542 case RADIO_RFMD_11:
3543 case RADIO_MAXIM_0D:
3544 case RADIO_RALINK_15:
3545 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3546 break;
3547 case RADIO_RADIA_16:
3548 case RADIO_UNKNOWN_17:
3549 acx111_s_sens_radio_16_17(adev);
3550 break;
3551 default:
3552 acx_log(LOG_WARNING, L_INIT,
3553 "don't know how to modify sensitivity "
3554 "for radio type 0x%02X\n", adev->radio_type);
3556 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3559 if (adev->set_mask & GETSET_ANTENNA) {
3560 /* antenna */
3561 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3563 memset(antenna, 0, sizeof(antenna));
3564 antenna[4] = adev->antenna;
3565 acx_log(LOG_DEBUG, L_INIT, "updating antenna value: 0x%02X\n",
3566 adev->antenna);
3567 acx_s_configure(adev, &antenna,
3568 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3569 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3572 if (adev->set_mask & GETSET_ED_THRESH) {
3573 /* ed_threshold */
3574 acx_log(LOG_INFO, L_INIT,
3575 "updating Energy Detect (ED) threshold: %u\n",
3576 adev->ed_threshold);
3577 if (IS_ACX100(adev)) {
3578 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3580 memset(ed_threshold, 0, sizeof(ed_threshold));
3581 ed_threshold[4] = adev->ed_threshold;
3582 acx_s_configure(adev, &ed_threshold,
3583 ACX100_IE_DOT11_ED_THRESHOLD);
3584 } else
3585 acx_log(LOG_WARNING, L_INIT,
3586 "acx111 doesn't support ED!\n");
3587 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3590 if (adev->set_mask & GETSET_CCA) {
3591 /* CCA value */
3592 acx_log(LOG_DEBUG, L_INIT,
3593 "updating Channel Clear Assessment (CCA) value: "
3594 "0x%02X\n", adev->cca);
3595 if (IS_ACX100(adev)) {
3596 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3598 memset(cca, 0, sizeof(cca));
3599 cca[4] = adev->cca;
3600 acx_s_configure(adev, &cca,
3601 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3602 } else
3603 acx_log(LOG_WARNING, L_INIT,
3604 "acx111 doesn't support CCA!\n");
3605 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3608 if (adev->set_mask & GETSET_LED_POWER) {
3609 /* Enable Tx */
3610 acx_log(LOG_INFO, L_INIT,
3611 "updating power LED status: %u\n", adev->led_power);
3613 acx_lock(adev, flags); /* acxpci_l_power_led expects that the lock is already taken! */
3614 if (IS_PCI(adev))
3615 acxpci_l_power_led(adev, adev->led_power);
3616 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3617 acx_unlock(adev, flags);
3620 if (adev->set_mask & GETSET_POWER_80211) {
3621 #if POWER_SAVE_80211
3622 acx_s_update_80211_powersave_mode(adev);
3623 #endif
3624 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3627 if (adev->set_mask & GETSET_CHANNEL) {
3628 /* channel */
3629 acx_log(LOG_INFO, L_INIT, "updating channel to: %u\n",
3630 adev->channel);
3631 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3634 if (adev->set_mask & GETSET_TX) {
3635 /* set Tx */
3636 acx_log(LOG_INFO, L_INIT, "updating: %s Tx\n",
3637 adev->tx_disabled ? "disable" : "enable");
3638 if (adev->tx_disabled)
3639 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3640 else {
3641 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3642 &adev->channel, 1);
3643 FIXME();
3644 /* This needs to be keyed on WEP? */
3645 /* acx111_s_feature_on(adev, 0,
3646 FEATURE2_NO_TXCRYPT |
3647 FEATURE2_SNIFFER); */
3648 acx_wake_queue(adev->ieee, NULL);
3650 CLEAR_BIT(adev->set_mask, GETSET_TX);
3653 if (adev->set_mask & GETSET_RX) {
3654 /* Enable Rx */
3655 acx_log(LOG_INFO, L_INIT,
3656 "updating: enable Rx on channel: %u\n", adev->channel);
3657 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3658 CLEAR_BIT(adev->set_mask, GETSET_RX);
3661 if (adev->set_mask & GETSET_RETRY) {
3662 u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
3663 u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
3665 acx_log(LOG_INFO, L_INIT,
3666 "updating short retry limit: %u, "
3667 "long retry limit: %u\n",
3668 adev->short_retry, adev->long_retry);
3669 short_retry[0x4] = adev->short_retry;
3670 long_retry[0x4] = adev->long_retry;
3671 acx_s_configure(adev, &short_retry,
3672 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
3673 acx_s_configure(adev, &long_retry,
3674 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
3675 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3678 if (adev->set_mask & SET_MSDU_LIFETIME) {
3679 u8 xmt_msdu_lifetime[4 +
3680 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3682 acx_log(LOG_DEBUG, L_INIT, "updating tx MSDU lifetime: %u\n",
3683 adev->msdu_lifetime);
3684 *(u32 *) & xmt_msdu_lifetime[4] =
3685 cpu_to_le32((u32) adev->msdu_lifetime);
3686 acx_s_configure(adev, &xmt_msdu_lifetime,
3687 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
3688 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3691 if (adev->set_mask & GETSET_REG_DOMAIN) {
3692 acx_log(LOG_INFO, L_INIT,
3693 "updating regulatory domain: 0x%02X\n",
3694 adev->reg_dom_id);
3695 acx_s_set_sane_reg_domain(adev, 1);
3696 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3698 if (adev->set_mask & GETSET_MODE ) {
3699 acx111_s_feature_on(adev, 0,
3700 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3701 switch (adev->mode) {
3702 case ACX_MODE_3_AP:
3703 adev->aid = 0;
3704 //acx111_s_feature_off(adev, 0,
3705 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3706 MAC_COPY(adev->bssid, adev->dev_addr);
3707 acx_s_cmd_join_bssid(adev, adev->dev_addr);
3708 break;
3709 case ACX_MODE_MONITOR:
3710 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3711 break;
3712 case ACX_MODE_0_ADHOC:
3713 case ACX_MODE_2_STA:
3714 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3715 break;
3716 default:
3717 break;
3719 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3721 if (adev->set_mask & SET_TEMPLATES) {
3722 switch (adev->mode)
3724 case ACX_MODE_3_AP:
3725 acx_s_set_tim_template(adev);
3726 break;
3727 default:
3728 break;
3730 if (adev->beacon_cache)
3732 acx_s_set_beacon_template(adev, adev->beacon_cache);
3733 dev_kfree_skb(adev->beacon_cache);
3734 adev->beacon_cache = NULL;
3736 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3739 if (adev->set_mask & SET_RXCONFIG) {
3740 acx_s_initialize_rx_config(adev);
3741 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3744 if (adev->set_mask & GETSET_RESCAN) {
3745 /* switch (adev->mode) {
3746 case ACX_MODE_0_ADHOC:
3747 case ACX_MODE_2_STA:
3748 start_scan = 1;
3749 break;
3751 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3754 if (adev->set_mask & GETSET_WEP) {
3755 /* encode */
3757 ie_dot11WEPDefaultKeyID_t dkey;
3758 #ifdef DEBUG_WEP
3759 struct {
3760 u16 type;
3761 u16 len;
3762 u8 val;
3763 } __attribute__ ((packed)) keyindic;
3764 #endif
3765 acx_log(LOG_DEBUG, L_INIT, "updating WEP key settings\n");
3767 acx_s_set_wepkey(adev);
3768 if (adev->wep_enabled) {
3769 dkey.KeyID = adev->wep_current_index;
3770 acx_log(LOG_DEBUG, L_INIT,
3771 "setting WEP key %u as default\n",
3772 dkey.KeyID);
3773 acx_s_configure(adev, &dkey,
3774 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
3775 #ifdef DEBUG_WEP
3776 keyindic.val = 3;
3777 acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
3778 #endif
3781 // start_scan = 1;
3782 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3785 if (adev->set_mask & SET_WEP_OPTIONS) {
3786 acx100_ie_wep_options_t options;
3788 if (IS_ACX111(adev)) {
3789 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
3790 "setting WEP Options for acx111 "
3791 "is not supported\n");
3792 } else {
3793 acx_log(LOG_DEBUG, L_INIT, "setting WEP Options\n");
3795 /* let's choose maximum setting: 4 default keys,
3796 * plus 10 other keys: */
3797 options.NumKeys =
3798 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3799 /* don't decrypt default key only,
3800 * don't override decryption: */
3801 options.WEPOption = 0;
3802 if (adev->mode == ACX_MODE_3_AP) {
3803 /* don't decrypt default key only,
3804 * override decryption mechanism: */
3805 options.WEPOption = 2;
3808 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3810 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3814 /* debug, rate, and nick don't need any handling */
3815 /* what about sniffing mode?? */
3817 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3818 adev->get_mask, adev->set_mask);
3820 /* end: */
3821 FN_EXIT0;
3824 #if 0
3825 /***********************************************************************
3826 ** acx_e_after_interrupt_task
3828 static int acx_s_recalib_radio(acx_device_t * adev)
3830 if (IS_ACX111(adev)) {
3831 acx111_cmd_radiocalib_t cal;
3833 /* automatic recalibration, choose all methods: */
3834 cal.methods = cpu_to_le32(0x8000000f);
3835 /* automatic recalibration every 60 seconds (value in TUs)
3836 * I wonder what the firmware default here is? */
3837 cal.interval = cpu_to_le32(58594);
3838 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3839 &cal, sizeof(cal),
3840 CMD_TIMEOUT_MS(100));
3841 } else {
3842 /* On ACX100, we need to recalibrate the radio
3843 * by issuing a GETSET_TX|GETSET_RX */
3844 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3845 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3846 (OK ==
3847 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3848 &adev->channel, 1))
3849 && (OK ==
3850 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3851 &adev->channel, 1)))
3852 return OK;
3853 return NOT_OK;
3856 #endif // if 0
3857 #if 0
3858 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3860 int res;
3862 /* this helps with ACX100 at least;
3863 * hopefully ACX111 also does a
3864 * recalibration here */
3866 /* clear flag beforehand, since we want to make sure
3867 * it's cleared; then only set it again on specific circumstances */
3868 CLEAR_BIT(adev->after_interrupt_jobs, ACX_TASKLET_CMD_RADIO_RECALIB);
3870 /* better wait a bit between recalibrations to
3871 * prevent overheating due to torturing the card
3872 * into working too long despite high temperature
3873 * (just a safety measure) */
3874 if (adev->recalib_time_last_success
3875 && time_before(jiffies, adev->recalib_time_last_success
3876 + RECALIB_PAUSE * 60 * HZ)) {
3877 if (adev->recalib_msg_ratelimit <= 4) {
3878 printk("%s: less than " STRING(RECALIB_PAUSE)
3879 " minutes since last radio recalibration, "
3880 "not recalibrating (maybe card is too hot?)\n",
3881 wiphy_name(adev->ieee->wiphy));
3882 adev->recalib_msg_ratelimit++;
3883 if (adev->recalib_msg_ratelimit == 5)
3884 printk("disabling above message until next recalib\n");
3886 return;
3889 adev->recalib_msg_ratelimit = 0;
3891 /* note that commands sometimes fail (card busy),
3892 * so only clear flag if we were fully successful */
3893 res = acx_s_recalib_radio(adev);
3894 if (res == OK) {
3895 printk("%s: successfully recalibrated radio\n",
3896 wiphy_name(adev->ieee->wiphy));
3897 adev->recalib_time_last_success = jiffies;
3898 adev->recalib_failure_count = 0;
3899 } else {
3900 /* failed: resubmit, but only limited
3901 * amount of times within some time range
3902 * to prevent endless loop */
3904 adev->recalib_time_last_success = 0; /* we failed */
3906 /* if some time passed between last
3907 * attempts, then reset failure retry counter
3908 * to be able to do next recalib attempt */
3909 if (time_after
3910 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3911 adev->recalib_failure_count = 0;
3913 if (adev->recalib_failure_count < 5) {
3914 /* increment inside only, for speedup of outside path */
3915 adev->recalib_failure_count++;
3916 adev->recalib_time_last_attempt = jiffies;
3917 acx_schedule_task(adev,
3918 ACX_TASKLET_CMD_RADIO_RECALIB);
3922 #endif // if 0
3924 void acx_e_after_interrupt_task(struct work_struct *work)
3926 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
3927 unsigned long flags;
3929 FN_ENTER;
3931 acx_lock(adev, flags);
3933 if (!adev->after_interrupt_jobs || !adev->initialized)
3934 goto end; /* no jobs to do */
3936 /* we see lotsa tx errors */
3937 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_RADIO_RECALIB) {
3938 acx_log_ratelimited(LOG_WARNING, L_ANY,
3939 "too many TX errors??\n");
3940 // acx_s_after_interrupt_recalib(adev);
3943 /* a poor interrupt code wanted to do update_card_settings() */
3944 if (adev->after_interrupt_jobs & ACX_TASKLET_UPDATE_CARD_CFG) {
3945 if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
3946 acx_unlock(adev, flags);
3947 acx_s_update_card_settings(adev);
3948 acx_lock(adev, flags);
3950 CLEAR_BIT(adev->after_interrupt_jobs,
3951 ACX_TASKLET_UPDATE_CARD_CFG);
3954 /* 1) we detected that no Scan_Complete IRQ came from fw, or
3955 ** 2) we found too many STAs */
3956 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_STOP_SCAN) {
3957 acx_log(LOG_DEBUG, L_IRQ, "sending a stop scan cmd...\n");
3958 acx_unlock(adev, flags);
3959 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
3960 acx_lock(adev, flags);
3961 /* HACK: set the IRQ bit, since we won't get a
3962 * scan complete IRQ any more on ACX111 (works on ACX100!),
3963 * since _we_, not a fw, have stopped the scan */
3964 SET_BIT(adev->irq_status, ACX_IRQ_SCAN_COMPLETE);
3965 CLEAR_BIT(adev->after_interrupt_jobs,
3966 ACX_TASKLET_CMD_STOP_SCAN);
3969 /* either fw sent Scan_Complete or we detected that
3970 ** no Scan_Complete IRQ came from fw. Finish scanning,
3971 ** pick join partner if any */
3972 if (adev->after_interrupt_jobs & ACX_TASKLET_COMPLETE_SCAN) {
3973 /* + scan kills current join status - restore it
3974 ** (do we need it for STA?) */
3975 /* + does it happen only with active scans?
3976 ** active and passive scans? ALL scans including
3977 ** background one? */
3978 /* + was not verified that everything is restored
3979 ** (but at least we start to emit beacons again) */
3980 CLEAR_BIT(adev->after_interrupt_jobs,
3981 ACX_TASKLET_COMPLETE_SCAN);
3984 /* STA auth or assoc timed out, start over again */
3986 if (adev->after_interrupt_jobs & ACX_TASKLET_RESTART_SCAN) {
3987 acx_log(LOG_DEBUG, L_IRQ, "sending a start_scan cmd...\n");
3988 CLEAR_BIT(adev->after_interrupt_jobs,
3989 ACX_TASKLET_RESTART_SCAN);
3992 /* whee, we got positive assoc response! 8) */
3993 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_ASSOCIATE) {
3994 CLEAR_BIT(adev->after_interrupt_jobs,
3995 ACX_TASKLET_CMD_ASSOCIATE);
3997 end:
3998 if(adev->after_interrupt_jobs)
4000 acx_log(LOG_DEBUG, L_ANY, "Jobs still to be run: %x\n",
4001 adev->after_interrupt_jobs);
4002 adev->after_interrupt_jobs = 0;
4004 acx_unlock(adev, flags);
4005 // acx_sem_unlock(adev);
4006 FN_EXIT0;
4010 /***********************************************************************
4011 ** acx_schedule_task
4013 ** Schedule the call of the after_interrupt method after leaving
4014 ** the interrupt context.
4016 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
4018 if (!adev->after_interrupt_jobs)
4020 SET_BIT(adev->after_interrupt_jobs, set_flag);
4021 schedule_work(&adev->after_interrupt_task);
4026 /***********************************************************************
4028 void acx_init_task_scheduler(acx_device_t * adev)
4030 /* configure task scheduler */
4031 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4035 /***********************************************************************
4036 ** acx_s_start
4038 void acx_s_start(acx_device_t * adev)
4040 FN_ENTER;
4043 * Ok, now we do everything that can possibly be done with ioctl
4044 * calls to make sure that when it was called before the card
4045 * was up we get the changes asked for
4048 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4049 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4050 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4051 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4053 acx_log(LOG_INFO, L_INIT,
4054 "updating initial settings on iface activation\n");
4055 acx_s_update_card_settings(adev);
4057 FN_EXIT0;
4061 /***********************************************************************
4062 ** acx_update_capabilities
4063 *//*
4064 void acx_update_capabilities(acx_device_t * adev)
4066 u16 cap = 0;
4068 switch (adev->mode) {
4069 case ACX_MODE_3_AP:
4070 SET_BIT(cap, WF_MGMT_CAP_ESS);
4071 break;
4072 case ACX_MODE_0_ADHOC:
4073 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4074 break;
4075 */ /* other types of stations do not emit beacons */
4076 /* }
4078 if (adev->wep_restricted) {
4079 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4081 if (adev->cfgopt_dot11ShortPreambleOption) {
4082 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4084 if (adev->cfgopt_dot11PBCCOption) {
4085 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4087 if (adev->cfgopt_dot11ChannelAgility) {
4088 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4090 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4091 adev->capabilities, cap);
4092 adev->capabilities = cap;
4096 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4099 static void acx_s_select_opmode(acx_device_t * adev)
4101 int changed = 0;
4102 FN_ENTER;
4104 if (adev->interface.operating) {
4105 switch (adev->interface.type) {
4106 case IEEE80211_IF_TYPE_AP:
4107 if (adev->mode != ACX_MODE_3_AP)
4109 adev->mode = ACX_MODE_3_AP;
4110 changed = 1;
4112 break;
4113 case IEEE80211_IF_TYPE_IBSS:
4114 if (adev->mode != ACX_MODE_0_ADHOC)
4116 adev->mode = ACX_MODE_0_ADHOC;
4117 changed = 1;
4119 break;
4120 case IEEE80211_IF_TYPE_STA:
4121 if (adev->mode != ACX_MODE_2_STA)
4123 adev->mode = ACX_MODE_2_STA;
4124 changed = 1;
4126 break;
4127 case IEEE80211_IF_TYPE_WDS:
4128 default:
4129 if (adev->mode != ACX_MODE_OFF)
4131 adev->mode = ACX_MODE_OFF;
4132 changed = 1;
4134 break;
4136 } else {
4137 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4139 if (adev->mode != ACX_MODE_MONITOR)
4141 adev->mode = ACX_MODE_MONITOR;
4142 changed = 1;
4145 else
4147 if (adev->mode != ACX_MODE_OFF)
4149 adev->mode = ACX_MODE_OFF;
4150 changed = 1;
4154 if (changed)
4156 SET_BIT(adev->set_mask, GETSET_MODE);
4157 acx_s_update_card_settings(adev);
4158 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4161 FN_EXIT0;
4165 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4169 int acx_add_interface(struct ieee80211_hw *ieee,
4170 struct ieee80211_if_init_conf *conf)
4172 acx_device_t *adev = ieee2adev(ieee);
4173 unsigned long flags;
4174 int err = -EOPNOTSUPP;
4176 DECLARE_MAC_BUF(mac);
4178 FN_ENTER;
4179 acx_lock(adev, flags);
4181 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4182 adev->interface.monitor++;
4183 } else {
4184 if (adev->interface.operating)
4185 goto out_unlock;
4186 adev->interface.operating = 1;
4187 adev->interface.type = conf->type;
4189 // adev->mode = conf->type;
4191 acx_unlock(adev, flags);
4193 if (adev->initialized)
4194 acx_s_select_opmode(adev);
4196 acx_lock(adev, flags);
4198 err = 0;
4200 acx_log(LOG_INFO, L_ANY, "Virtual interface added "
4201 "(type: 0x%08X, MAC: %s)\n",
4202 conf->type,
4203 print_mac(mac, conf->mac_addr));
4205 out_unlock:
4206 acx_unlock(adev, flags);
4208 FN_EXIT0;
4209 return err;
4212 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4216 void acx_remove_interface(struct ieee80211_hw *hw,
4217 struct ieee80211_if_init_conf *conf)
4219 acx_device_t *adev = ieee2adev(hw);
4221 DECLARE_MAC_BUF(mac);
4223 FN_ENTER;
4225 acx_sem_lock(adev);
4226 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4227 adev->interface.monitor--;
4228 // assert(bcm->interface.monitor >= 0);
4229 } else {
4230 adev->interface.operating = 0;
4233 acx_log(LOG_INFO, L_ANY, "Removing interface: %d %d\n",
4234 adev->interface.operating, conf->type);
4235 acx_sem_unlock(adev);
4237 if (adev->initialized)
4238 acx_s_select_opmode(adev);
4239 flush_scheduled_work();
4241 acx_log(LOG_INFO, L_ANY, "Virtual interface removed "
4242 "(type: 0x%08X, MAC: %s)\n",
4243 conf->type, print_mac(mac, conf->mac_addr));
4245 FN_EXIT0;
4248 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4252 int acx_net_reset(struct ieee80211_hw *ieee)
4254 acx_device_t *adev = ieee2adev(ieee);
4255 FN_ENTER;
4256 if (IS_PCI(adev))
4257 acxpci_s_reset_dev(adev);
4258 else
4259 TODO();
4261 FN_EXIT0;
4262 return 0;
4266 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4269 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4271 int result;
4273 FN_ENTER;
4275 acx_sem_lock(adev);
4276 adev->rx_status.channel = channel;
4277 adev->rx_status.freq = freq;
4279 adev->channel = channel;
4280 /* hmm, the following code part is strange, but this is how
4281 * it was being done before... */
4282 acx_log(LOG_DEBUG, L_IOCTL, "Changing to channel %d\n", channel);
4283 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4284 result = -EINPROGRESS; /* need to call commit handler */
4286 acx_sem_unlock(adev);
4287 FN_EXIT1(result);
4288 return result;
4292 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4295 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4297 acx_device_t *adev = ieee2adev(hw);
4298 unsigned long flags;
4300 FN_ENTER;
4302 acx_lock(adev, flags);
4303 //FIXME();
4304 if (!adev->initialized) {
4305 acx_unlock(adev, flags);
4306 return 0;
4308 if (conf->beacon_int != adev->beacon_interval)
4309 adev->beacon_interval = conf->beacon_int;
4310 if (conf->channel != adev->channel) {
4311 acx_unlock(adev, flags);
4312 acx_selectchannel(adev, conf->channel,conf->freq);
4313 acx_lock(adev, flags);
4314 /* acx_schedule_task(adev,
4315 ACX_TASKLET_UPDATE_CARD_CFG
4316 */ /*+ ACX_TASKLET_RESTART_SCAN */ /*);*/
4319 if (conf->short_slot_time != adev->short_slot) {
4320 // assert(phy->type == BCM43xx_PHYTYPE_G);
4321 if (conf->short_slot_time)
4322 acx_short_slot_timing_enable(adev);
4323 else
4324 acx_short_slot_timing_disable(adev);
4325 acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4328 adev->tx_disabled = !conf->radio_enabled;
4329 /* if (conf->power_level != 0){
4330 adev->tx_level_dbm = conf->power_level;
4331 acx_s_set_tx_level(adev, adev->tx_level_dbm);
4332 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4333 //acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4336 //FIXME: This does not seem to wake up:
4337 #if 0
4338 if (conf->power_level == 0) {
4339 if (radio->enabled)
4340 bcm43xx_radio_turn_off(bcm);
4341 } else {
4342 if (!radio->enabled)
4343 bcm43xx_radio_turn_on(bcm);
4345 #endif
4347 //TODO: phymode
4348 //TODO: antennas
4349 if (adev->set_mask > 0) {
4350 acx_unlock(adev, flags);
4351 acx_s_update_card_settings(adev);
4352 acx_lock(adev, flags);
4354 acx_unlock(adev, flags);
4356 FN_EXIT0;
4357 return 0;
4361 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4365 extern int acx_config_interface(struct ieee80211_hw* ieee,
4366 struct ieee80211_vif *vif,
4367 struct ieee80211_if_conf *conf)
4369 acx_device_t *adev = ieee2adev(ieee);
4370 unsigned long flags;
4371 int err = -ENODEV;
4372 FN_ENTER;
4373 if (!adev->interface.operating)
4374 goto err_out;
4376 if (adev->initialized)
4377 acx_s_select_opmode(adev);
4379 acx_lock(adev, flags);
4381 if ((conf->type == IEEE80211_IF_TYPE_AP)
4382 && (adev->vif == vif)) {
4383 if ((conf->ssid_len > 0) && conf->ssid)
4385 adev->essid_len = conf->ssid_len;
4386 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4387 SET_BIT(adev->set_mask, SET_TEMPLATES);
4390 if (conf->beacon != 0)
4392 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4393 adev->beacon_cache = conf->beacon;
4394 SET_BIT(adev->set_mask, SET_TEMPLATES);
4397 acx_unlock(adev, flags);
4399 if (adev->set_mask != 0)
4400 acx_s_update_card_settings(adev);
4401 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4402 err = 0;
4403 err_out:
4404 FN_EXIT1(err);
4405 return err;
4409 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4413 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4414 struct ieee80211_tx_queue_stats *stats)
4416 // acx_device_t *adev = ndev2adev(net_dev);
4417 struct ieee80211_tx_queue_stats_data *data;
4418 int err = -ENODEV;
4420 FN_ENTER;
4422 // acx_lock(adev, flags);
4423 data = &(stats->data[0]);
4424 data->len = 0;
4425 data->limit = TX_CNT;
4426 data->count = 0;
4427 // acx_unlock(adev, flags);
4429 FN_EXIT0;
4430 return err;
4433 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4437 int acx_net_conf_tx(struct ieee80211_hw *hw,
4438 int queue, const struct ieee80211_tx_queue_params *params)
4440 FN_ENTER;
4441 // TODO();
4442 FN_EXIT0;
4443 return 0;
4446 static void keymac_write(acx_device_t * adev, u16 index, const u32 * addr)
4448 /* for keys 0-3 there is no associated mac address */
4449 if (index < 4)
4450 return;
4452 index -= 4;
4453 if (1) {
4454 TODO();
4456 bcm43xx_shm_write32(bcm,
4457 BCM43xx_SHM_HWMAC,
4458 index * 2,
4459 cpu_to_be32(*addr));
4460 bcm43xx_shm_write16(bcm,
4461 BCM43xx_SHM_HWMAC,
4462 (index * 2) + 1,
4463 cpu_to_be16(*((u16 *)(addr + 1))));
4465 } else {
4466 if (index < 8) {
4467 TODO(); /* Put them in the macaddress filter */
4468 } else {
4469 TODO();
4470 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4471 Keep in mind to update the count of keymacs in 0x003 */
4477 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4481 int acx_clear_keys(acx_device_t * adev)
4483 static const u32 zero_mac[2] = { 0 };
4484 unsigned int i, j, nr_keys = 54;
4485 u16 offset;
4487 /* FixMe:Check for Number of Keys available */
4489 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4491 for (i = 0; i < nr_keys; i++) {
4492 adev->key[i].enabled = 0;
4493 /* returns for i < 4 immediately */
4494 keymac_write(adev, i, zero_mac);
4496 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4497 0x100 + (i * 2), 0x0000);
4499 for (j = 0; j < 8; j++) {
4500 offset =
4501 adev->security_offset + (j * 4) +
4502 (i * ACX_SEC_KEYSIZE);
4504 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4505 offset, 0x0000);
4509 return 1;
4513 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4517 int acx_key_write(acx_device_t * adev,
4518 u16 index, u8 algorithm,
4519 const struct ieee80211_key_conf *key, const u8 * mac_addr)
4521 // struct iw_point *dwrq = &wrqu->encoding;
4522 int result;
4524 FN_ENTER;
4526 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4527 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4529 // acx_sem_lock(adev);
4531 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4532 if (key->keylen > 0) {
4533 /* if index is 0 or invalid, use default key */
4534 if (index > 3)
4535 index = (int)adev->wep_current_index;
4536 if ((algorithm == ACX_SEC_ALGO_WEP) ||
4537 (algorithm == ACX_SEC_ALGO_WEP104)) {
4538 switch(key->keylen) {
4539 case 40 / 8:
4540 /* WEP 40-bit =
4541 40-bit entered key + 24 bit IV = 64-bit */
4542 adev->wep_keys[index].size = 13;
4543 break;
4544 case 104 / 8:
4545 /* WEP 104-bit =
4546 104-bit entered key + 24-bit IV = 128-bit */
4547 adev->wep_keys[index].size = 29;
4548 break;
4549 case 128 / 8:
4550 /* WEP 128-bit =
4551 128-bit entered key + 24 bit IV = 152-bit */
4552 adev->wep_keys[index].size = 16;
4553 break;
4554 default:
4555 adev->wep_keys[index].size = 0;
4556 return -EINVAL; /* shouldn't happen */
4559 memset(adev->wep_keys[index].key, 0,
4560 sizeof(adev->wep_keys[index].key));
4561 memcpy(adev->wep_keys[index].key, key, key->keylen);
4562 } else {
4563 /* set transmit key */
4564 if (index <= 3)
4565 adev->wep_current_index = index;
4566 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4567 /* complain if we were not just setting
4568 * the key mode */
4569 // result = -EINVAL;
4570 // goto end_unlock;
4571 // }
4575 adev->wep_enabled = (algorithm == ALG_WEP);
4577 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4579 if (algorithm & IW_ENCODE_OPEN) {
4580 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4581 adev->wep_restricted = 0;
4583 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4584 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4585 adev->wep_restricted = 1;
4588 // adev->auth_alg = algorithm;
4589 /* set flag to make sure the card WEP settings get updated */
4590 if (adev->wep_enabled) {
4591 SET_BIT(adev->set_mask, GETSET_WEP);
4592 acx_s_update_card_settings(adev);
4593 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4596 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4597 dwrq->length, extra, dwrq->flags);
4598 for (index = 0; index <= 3; index++) {
4599 if (adev->wep_keys[index].size) {
4600 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4601 adev->wep_keys[index].index,
4602 (int) adev->wep_keys[index].size,
4603 adev->wep_keys[index].key);
4607 result = -EINPROGRESS;
4608 // acx_sem_unlock(adev);
4610 FN_EXIT1(result);
4611 return result;
4617 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4621 int acx_net_set_key(struct ieee80211_hw *ieee,
4622 enum set_key_cmd cmd, const u8 *local_addr,
4623 const u8 * addr, struct ieee80211_key_conf *key)
4625 // return 0;
4626 struct acx_device *adev = ieee2adev(ieee);
4627 unsigned long flags;
4628 u8 algorithm;
4629 u16 index;
4630 int err = -EINVAL;
4631 FN_ENTER;
4632 // TODO();
4633 switch (key->alg) {
4634 default:
4635 /* case ALG_NONE:
4636 case ALG_NULL:
4637 algorithm = ACX_SEC_ALGO_NONE;
4638 break;
4639 */ case ALG_WEP:
4640 if (key->keylen == 5)
4641 algorithm = ACX_SEC_ALGO_WEP;
4642 else
4643 algorithm = ACX_SEC_ALGO_WEP104;
4644 break;
4645 case ALG_TKIP:
4646 algorithm = ACX_SEC_ALGO_TKIP;
4647 break;
4648 case ALG_CCMP:
4649 algorithm = ACX_SEC_ALGO_AES;
4650 break;
4653 index = (u8) (key->keyidx);
4654 if (index >= ARRAY_SIZE(adev->key))
4655 goto out;
4656 acx_lock(adev, flags);
4657 switch (cmd) {
4658 case SET_KEY:
4659 err = acx_key_write(adev, index, algorithm, key, addr);
4660 if (err)
4661 goto out_unlock;
4662 key->hw_key_idx = index;
4663 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4664 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4665 adev->default_key_idx = index;*/
4666 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4667 adev->key[index].enabled = 1;
4668 break;
4669 case DISABLE_KEY:
4670 adev->key[index].enabled = 0;
4671 err = 0;
4672 break;
4673 /* case ENABLE_COMPRESSION:
4674 case DISABLE_COMPRESSION:
4675 err = 0;
4676 break; */
4678 out_unlock:
4679 acx_unlock(adev, flags);
4680 out:
4681 FN_EXIT0;
4682 return err;
4687 /***********************************************************************
4688 ** Common function to parse ALL configoption struct formats
4689 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4690 ** FIXME: logging should be removed here and added to a /proc file instead
4692 ** Look into bcm43xx
4694 void
4695 acx_s_parse_configoption(acx_device_t * adev,
4696 const acx111_ie_configoption_t * pcfg)
4698 const u8 *pEle;
4699 int i;
4700 int is_acx111 = IS_ACX111(adev);
4702 acx_log_dump(LOG_DEBUG, L_REALLYVERBOSE, pcfg, sizeof(*pcfg),
4703 "configoption struct content:\n");
4705 if ((is_acx111 && (adev->eeprom_version == 5))
4706 || (!is_acx111 && (adev->eeprom_version == 4))
4707 || (!is_acx111 && (adev->eeprom_version == 5))) {
4708 /* these versions are known to be supported */
4709 } else {
4710 acx_log(LOG_WARNING, L_ANY,
4711 "unknown chip and EEPROM version combination "
4712 "(%s, v%d), "
4713 "don't know how to parse config options yet. "
4714 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4715 adev->eeprom_version);
4716 return;
4719 /* first custom-parse the first part which has chip-specific layout */
4721 pEle = (const u8 *)pcfg;
4723 pEle += 4; /* skip (type,len) header */
4725 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4726 pEle += sizeof(adev->cfgopt_NVSv);
4728 if (is_acx111) {
4729 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4730 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4732 adev->cfgopt_probe_delay = 200; /* good default value? */
4733 pEle += 2; /* FIXME: unknown, value 0x0001 */
4734 } else {
4735 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4736 pEle += sizeof(adev->cfgopt_MAC);
4738 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4739 pEle += sizeof(adev->cfgopt_probe_delay);
4740 if ((adev->cfgopt_probe_delay < 100)
4741 || (adev->cfgopt_probe_delay > 500)) {
4742 acx_log(LOG_WARNING, L_ANY,
4743 "strange probe_delay value %d, "
4744 "tweaking to 200\n", adev->cfgopt_probe_delay);
4745 adev->cfgopt_probe_delay = 200;
4749 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4750 pEle += sizeof(adev->cfgopt_eof_memory);
4752 acx_log(LOG_INFO, L_ANY, "NVS_vendor_offs:%04X probe_delay:%d "
4753 "eof_memory:%d\n",
4754 adev->cfgopt_NVS_vendor_offs, adev->cfgopt_probe_delay,
4755 adev->cfgopt_eof_memory);
4757 adev->cfgopt_dot11CCAModes = *pEle++;
4758 adev->cfgopt_dot11Diversity = *pEle++;
4759 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4760 adev->cfgopt_dot11PBCCOption = *pEle++;
4761 adev->cfgopt_dot11ChannelAgility = *pEle++;
4762 adev->cfgopt_dot11PhyType = *pEle++;
4763 adev->cfgopt_dot11TempType = *pEle++;
4764 acx_log(LOG_INFO, L_ANY,
4765 "CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4766 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4767 adev->cfgopt_dot11CCAModes, adev->cfgopt_dot11Diversity,
4768 adev->cfgopt_dot11ShortPreambleOption,
4769 adev->cfgopt_dot11PBCCOption, adev->cfgopt_dot11ChannelAgility,
4770 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4772 /* then use common parsing for next part which has common layout */
4774 pEle++; /* skip table_count (6) */
4776 adev->cfgopt_antennas.type = pEle[0];
4777 adev->cfgopt_antennas.len = pEle[1];
4780 * FIXME: a candidate for acx_log_dump(), but the code is bizarre
4782 acx_log(LOG_INFO, L_ANY, "AntennaID:%02X Len:%02X Data:",
4783 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4784 for (i = 0; i < pEle[1]; i++) {
4785 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4786 printk("%02X ", pEle[i + 2]);
4788 printk("\n");
4790 pEle += pEle[1] + 2;
4791 adev->cfgopt_power_levels.type = pEle[0];
4792 adev->cfgopt_power_levels.len = pEle[1];
4795 * FIXME: see above
4797 acx_log(LOG_INFO, L_ANY, "PowerLevelID:%02X Len:%02X Data:",
4798 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4799 for (i = 0; i < pEle[1]; i++) {
4800 adev->cfgopt_power_levels.list[i] =
4801 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4802 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4804 printk("\n");
4806 pEle += pEle[1] * 2 + 2;
4807 adev->cfgopt_data_rates.type = pEle[0];
4808 adev->cfgopt_data_rates.len = pEle[1];
4811 * FIXME again
4813 acx_log(LOG_INFO, L_ANY, "DataRatesID:%02X Len:%02X Data:",
4814 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4815 for (i = 0; i < pEle[1]; i++) {
4816 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4817 printk("%02X ", pEle[i + 2]);
4819 printk("\n");
4821 pEle += pEle[1] + 2;
4822 adev->cfgopt_domains.type = pEle[0];
4823 adev->cfgopt_domains.len = pEle[1];
4826 * And again
4828 acx_log(LOG_INFO, L_ANY, "DomainID:%02X Len:%02X Data:",
4829 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4830 for (i = 0; i < pEle[1]; i++) {
4831 adev->cfgopt_domains.list[i] = pEle[i + 2];
4832 printk("%02X ", pEle[i + 2]);
4834 printk("\n");
4836 pEle += pEle[1] + 2;
4837 adev->cfgopt_product_id.type = pEle[0];
4838 adev->cfgopt_product_id.len = pEle[1];
4839 for (i = 0; i < pEle[1]; i++) {
4840 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4842 acx_log(LOG_INFO, L_ANY, "ProductID:%02X Len:%02X Data:%.*s\n",
4843 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4844 adev->cfgopt_product_id.len,
4845 (char *)adev->cfgopt_product_id.list);
4847 pEle += pEle[1] + 2;
4848 adev->cfgopt_manufacturer.type = pEle[0];
4849 adev->cfgopt_manufacturer.len = pEle[1];
4850 for (i = 0; i < pEle[1]; i++) {
4851 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4853 acx_log(LOG_INFO, L_ANY, "ManufacturerID:%02X Len:%02X Data:%.*s\n",
4854 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4855 adev->cfgopt_manufacturer.len,
4856 (char *)adev->cfgopt_manufacturer.list);
4858 printk("EEPROM part:\n");
4859 for (i=0; i<58; i++) {
4860 printk("%02X =======> 0x%02X\n",
4861 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4867 /***********************************************************************
4868 ** Linux Kernel Specific
4870 static int __init acx_e_init_module(void)
4872 int r1, r2;
4874 acx_struct_size_check();
4876 acx_log(LOG_INFO, L_ANY, "this driver is still EXPERIMENTAL\n");
4877 acx_log(LOG_INFO, L_ANY, "acx: reading README file and/or "
4878 "Craig's HOWTO is recommended, "
4879 "visit http://acx100.sourceforge.net/wiki in case "
4880 "of further questions/discussion\n");
4882 #if defined(CONFIG_ACX_MAC80211_PCI)
4883 r1 = acxpci_e_init_module();
4884 #else
4885 r1 = -EINVAL;
4886 #endif
4887 #if defined(CONFIG_ACX_MAC80211_USB)
4888 r2 = acxusb_e_init_module();
4889 #else
4890 r2 = -EINVAL;
4891 #endif
4892 if (r2 && r1) /* both failed! */
4893 return r2 ? r2 : r1;
4894 /* return success if at least one succeeded */
4895 return 0;
4898 static void __exit acx_e_cleanup_module(void)
4900 #if defined(CONFIG_ACX_MAC80211_PCI)
4901 acxpci_e_cleanup_module();
4902 #endif
4903 #if defined(CONFIG_ACX_MAC80211_USB)
4904 acxusb_e_cleanup_module();
4905 #endif
4908 module_init(acx_e_init_module)
4909 module_exit(acx_e_cleanup_module)