Get rid of the ACX_PACKED macro
[acx-mac80211.git] / common.c
blobeb6b9b46430eee7da16de65573893bbfcbab3992
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 /***********************************************************************
40 #if ACX_DEBUG
41 unsigned int acx_debug /* will add __read_mostly later */ = ACX_DEFAULT_MSG;
42 /* parameter is 'debug', corresponding var is acx_debug */
43 module_param_named(debug, acx_debug, uint, 0);
44 MODULE_PARM_DESC(debug, "Debug level mask (see L_xxx constants)");
45 #endif
47 MODULE_LICENSE("GPL");
48 /* USB had this: MODULE_AUTHOR("Martin Wawro <martin.wawro AT uni-dortmund.de>"); */
49 MODULE_AUTHOR("ACX100 Open Source Driver development team");
50 MODULE_DESCRIPTION
51 ("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)");
53 MODULE_VERSION(ACX_RELEASE);
55 /***********************************************************************
57 /* Probably a number of acx's intermediate buffers for USB transfers,
58 ** not to be confused with number of descriptors in tx/rx rings
59 ** (which are not directly accessible to host in USB devices) */
60 #define USB_RX_CNT 10
61 #define USB_TX_CNT 10
64 /***********************************************************************
67 /* minutes to wait until next radio recalibration: */
68 #define RECALIB_PAUSE 5
70 /* Please keep acx_reg_domain_ids_len in sync... */
71 const u8 acx_reg_domain_ids[acx_reg_domain_ids_len] =
72 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 };
73 static const u16 reg_domain_channel_masks[acx_reg_domain_ids_len] =
74 { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc };
75 const char *const
76 acx_reg_domain_strings[] = {
77 /* 0 */ " 1-11 FCC (USA)",
78 /* 1 */ " 1-11 DOC/IC (Canada)",
79 /* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */
80 /* 2 */ " 1-13 ETSI (Europe)",
81 /* 3 */ "10-11 Spain",
82 /* 4 */ "10-13 France",
83 /* 5 */ " 14 MKK (Japan)",
84 /* 6 */ " 1-14 MKK1",
85 /* 7 */ " 3-9 Israel (not all firmware versions)",
86 NULL /* needs to remain as last entry */
91 /***********************************************************************
92 ** Debugging support
94 #ifdef PARANOID_LOCKING
95 static unsigned max_lock_time;
96 static unsigned max_sem_time;
98 /* Obvious or linux kernel specific derived code follows: */
100 void acx_lock_unhold()
102 max_lock_time = 0;
105 void acx_sem_unhold()
107 max_sem_time = 0;
110 static inline const char *sanitize_str(const char *s)
112 const char *t = strrchr(s, '/');
113 if (t)
114 return t + 1;
115 return s;
118 void acx_lock_debug(acx_device_t * adev, const char *where)
120 unsigned int count = 100 * 1000 * 1000;
121 where = sanitize_str(where);
122 while (--count) {
123 if (!spin_is_locked(&adev->spinlock))
124 break;
125 cpu_relax();
127 if (!count) {
128 printk(KERN_EMERG "LOCKUP: already taken at %s!\n",
129 adev->last_lock);
130 BUG();
132 adev->last_lock = where;
133 rdtscl(adev->lock_time);
136 void acx_unlock_debug(acx_device_t * adev, const char *where)
138 #ifdef SMP
139 if (!spin_is_locked(&adev->spinlock)) {
140 where = sanitize_str(where);
141 printk(KERN_EMERG "STRAY UNLOCK at %s!\n", where);
142 BUG();
144 #endif
145 if (acx_debug & L_LOCK) {
146 unsigned long diff;
147 rdtscl(diff);
148 diff -= adev->lock_time;
149 if (diff > max_lock_time) {
150 where = sanitize_str(where);
151 acx_log(LOG_DEBUG, L_LOCK, "max lock hold time "
152 "%ld CPU ticks from %s to %s\n", diff,
153 adev->last_lock, where);
154 max_lock_time = diff;
158 #endif /* PARANOID_LOCKING */
162 /***********************************************************************
163 ** Basically a mdelay/msleep with logging
165 void acx_s_mwait(int ms)
167 FN_ENTER;
168 #ifdef CONFIG_X86
169 mdelay(ms);
170 #else
171 msleep(ms);
172 #endif
173 FN_EXIT0;
177 /***********************************************************************
178 ** Not inlined: it's larger than it seems
180 void acx_print_mac(const char *head, const u8 * mac, const char *tail)
182 printk("%s" MACSTR "%s", head, MAC(mac), tail);
188 /***********************************************************************
189 ** acx_cmd_status_str
191 const char *acx_cmd_status_str(unsigned int state)
193 static const char *const cmd_error_strings[] = {
194 "Idle",
195 "Success",
196 "Unknown Command",
197 "Invalid Information Element",
198 "Channel rejected",
199 "Channel invalid in current regulatory domain",
200 "MAC invalid",
201 "Command rejected (read-only information element)",
202 "Command rejected",
203 "Already asleep",
204 "TX in progress",
205 "Already awake",
206 "Write only",
207 "RX in progress",
208 "Invalid parameter",
209 "Scan in progress",
210 "Failed"
212 return state < ARRAY_SIZE(cmd_error_strings) ?
213 cmd_error_strings[state] : "?";
216 /***********************************************************************
217 ** acx_s_get_firmware_version
219 ** Obvious
221 void acx_s_get_firmware_version(acx_device_t * adev)
223 fw_ver_t fw;
224 u8 hexarr[4] = { 0, 0, 0, 0 };
225 int hexidx = 0, val = 0;
226 const char *num;
227 char c;
229 FN_ENTER;
231 memset(fw.fw_id, 'E', FW_ID_SIZE);
232 acx_s_interrogate(adev, &fw, ACX1xx_IE_FWREV);
233 memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE);
234 adev->firmware_version[FW_ID_SIZE] = '\0';
236 acx_log(LOG_DEBUG, L_ANY, "fw_ver: fw_id='%s' hw_id=%08X\n",
237 adev->firmware_version, fw.hw_id);
239 if (strncmp(fw.fw_id, "Rev ", 4) != 0) {
240 acx_log(LOG_WARNING, L_ANY, "acx: strange firmware version string "
241 "'%s', please report\n", adev->firmware_version);
242 adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */
243 } else {
244 num = &fw.fw_id[4];
245 while (1) {
246 c = *num++;
247 if ((c == '.') || (c == '\0')) {
248 hexarr[hexidx++] = val;
249 if ((hexidx > 3) || (c == '\0')) /* end? */
250 break;
251 val = 0;
252 continue;
254 if ((c >= '0') && (c <= '9'))
255 c -= '0';
256 else
257 c = c - 'a' + (char)10;
258 val = val * 16 + c;
261 adev->firmware_numver = (u32) ((hexarr[0] << 24) |
262 (hexarr[1] << 16)
263 | (hexarr[2] << 8) | hexarr[3]);
264 acx_log(LOG_DEBUG, L_ANY, "firmware_numver 0x%08X\n",
265 adev->firmware_numver);
267 if (IS_ACX111(adev)) {
268 if (adev->firmware_numver == 0x00010011) {
269 /* This one does not survive floodpinging */
270 acx_log(LOG_WARNING, L_ANY, "firmware '%s' is known "
271 "to be buggy, please upgrade\n",
272 adev->firmware_version);
276 adev->firmware_id = le32_to_cpu(fw.hw_id);
278 /* we're able to find out more detailed chip names now */
279 switch (adev->firmware_id & 0xffff0000) {
280 case 0x01010000:
281 case 0x01020000:
282 adev->chip_name = "TNETW1100A";
283 break;
284 case 0x01030000:
285 adev->chip_name = "TNETW1100B";
286 break;
287 case 0x03000000:
288 case 0x03010000:
289 adev->chip_name = "TNETW1130";
290 break;
291 case 0x04030000: /* 0x04030101 is TNETW1450 */
292 adev->chip_name = "TNETW1450";
293 break;
294 default:
295 acx_log(LOG_WARNING, L_ANY,"unknown chip ID 0x%08X, "
296 "please report\n", adev->firmware_id);
297 break;
300 FN_EXIT0;
304 /***********************************************************************
305 ** acx_display_hardware_details
307 ** Displays hw/fw version, radio type etc...
309 ** Obvious
311 void acx_display_hardware_details(acx_device_t * adev)
313 const char *radio_str, *form_str;
315 FN_ENTER;
317 switch (adev->radio_type) {
318 case RADIO_MAXIM_0D:
319 radio_str = "Maxim";
320 break;
321 case RADIO_RFMD_11:
322 radio_str = "RFMD";
323 break;
324 case RADIO_RALINK_15:
325 radio_str = "Ralink";
326 break;
327 case RADIO_RADIA_16:
328 radio_str = "Radia";
329 break;
330 case RADIO_UNKNOWN_17:
331 /* TI seems to have a radio which is
332 * additionally 802.11a capable, too */
333 radio_str = "802.11a/b/g radio?! Please report";
334 break;
335 case RADIO_UNKNOWN_19:
336 radio_str = "A radio used by Safecom cards?! Please report";
337 break;
338 case RADIO_UNKNOWN_1B:
339 radio_str = "An unknown radio used by TNETW1450 USB adapters";
340 break;
341 default:
342 radio_str = "UNKNOWN, please report radio type name!";
343 break;
346 switch (adev->form_factor) {
347 case 0x00:
348 form_str = "unspecified";
349 break;
350 case 0x01:
351 form_str = "(mini-)PCI / CardBus";
352 break;
353 case 0x02:
354 form_str = "USB";
355 break;
356 case 0x03:
357 form_str = "Compact Flash";
358 break;
359 default:
360 form_str = "UNKNOWN, please report";
361 break;
364 acx_log(LOG_INFO, L_ANY, "acx: chipset %s, radio type 0x%02X (%s), "
365 "form factor 0x%02X (%s), EEPROM version 0x%02X, "
366 "uploaded firmware '%s'\n",
367 adev->chip_name, adev->radio_type, radio_str,
368 adev->form_factor, form_str, adev->eeprom_version,
369 adev->firmware_version);
371 FN_EXIT0;
375 /***********************************************************************
376 ** acx_e_get_stats, acx_e_get_wireless_stats
379 acx_e_get_stats(struct ieee80211_hw *hw,
380 struct ieee80211_low_level_stats *stats)
382 acx_device_t *adev = ieee2adev(hw);
383 unsigned long flags;
384 acx_lock(adev, flags);
385 memcpy(stats, &adev->ieee_stats, sizeof(*stats));
386 acx_unlock(adev, flags);
387 return 0;
391 /***********************************************************************
392 ** maps acx111 tx descr rate field to acx100 one
394 const u8 acx_bitpos2rate100[] = {
395 RATE100_1, /* 0 */
396 RATE100_2, /* 1 */
397 RATE100_5, /* 2 */
398 RATE100_2, /* 3, should not happen */
399 RATE100_2, /* 4, should not happen */
400 RATE100_11, /* 5 */
401 RATE100_2, /* 6, should not happen */
402 RATE100_2, /* 7, should not happen */
403 RATE100_22, /* 8 */
404 RATE100_2, /* 9, should not happen */
405 RATE100_2, /* 10, should not happen */
406 RATE100_2, /* 11, should not happen */
407 RATE100_2, /* 12, should not happen */
408 RATE100_2, /* 13, should not happen */
409 RATE100_2, /* 14, should not happen */
410 RATE100_2, /* 15, should not happen */
413 u8 acx_rate111to100(u16 r)
415 return acx_bitpos2rate100[highest_bit(r)];
419 /***********************************************************************
420 ** Calculate level like the feb 2003 windows driver seems to do
422 static u8 acx_signal_to_winlevel(u8 rawlevel)
424 /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
425 u8 winlevel = ((4 + (rawlevel * 5)) / 8);
427 if (winlevel > 100)
428 winlevel = 100;
429 return winlevel;
432 u8 acx_signal_determine_quality(u8 signal, u8 noise)
434 int qual;
436 qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2;
438 if (qual > 100)
439 return 100;
440 if (qual < 0)
441 return 0;
442 return qual;
446 /***********************************************************************
447 ** Interrogate/configure commands
450 /* FIXME: the lengths given here probably aren't always correct.
451 * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4",
452 * unless the firmware actually expects a different length than the struct length */
453 static const u16 acx100_ie_len[] = {
455 ACX100_IE_ACX_TIMER_LEN,
456 sizeof(acx100_ie_powersave_t) - 4, /* is that 6 or 8??? */
457 ACX1xx_IE_QUEUE_CONFIG_LEN,
458 ACX100_IE_BLOCK_SIZE_LEN,
459 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
460 ACX1xx_IE_RATE_FALLBACK_LEN,
461 ACX100_IE_WEP_OPTIONS_LEN,
462 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
464 ACX1xx_IE_ASSOC_ID_LEN,
466 ACX111_IE_CONFIG_OPTIONS_LEN,
467 ACX1xx_IE_FWREV_LEN,
468 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
469 ACX1xx_IE_MEDIUM_USAGE_LEN,
470 ACX1xx_IE_RXCONFIG_LEN,
473 sizeof(fw_stats_t) - 4,
475 ACX1xx_IE_FEATURE_CONFIG_LEN,
476 ACX111_IE_KEY_CHOOSE_LEN,
477 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
478 ACX1FF_IE_WONE_CONFIG_LEN,
480 ACX1FF_IE_TID_CONFIG_LEN,
484 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
485 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
486 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
487 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
489 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
490 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
491 ACX1FF_IE_CCA_THRESHOLD_LEN,
492 ACX1FF_IE_EVENT_MASK_LEN,
493 ACX1FF_IE_DTIM_PERIOD_LEN,
495 ACX1FF_IE_ACI_CONFIG_SET_LEN,
502 ACX1FF_IE_EEPROM_VER_LEN,
505 static const u16 acx100_ie_len_dot11[] = {
507 ACX1xx_IE_DOT11_STATION_ID_LEN,
509 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
510 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
511 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
512 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
513 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
514 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
516 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
517 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
519 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
520 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
521 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
522 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
528 static const u16 acx111_ie_len[] = {
530 ACX100_IE_ACX_TIMER_LEN,
531 sizeof(acx111_ie_powersave_t) - 4,
532 ACX1xx_IE_QUEUE_CONFIG_LEN,
533 ACX100_IE_BLOCK_SIZE_LEN,
534 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
535 ACX1xx_IE_RATE_FALLBACK_LEN,
536 ACX100_IE_WEP_OPTIONS_LEN,
537 ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
539 ACX1xx_IE_ASSOC_ID_LEN,
541 ACX111_IE_CONFIG_OPTIONS_LEN,
542 ACX1xx_IE_FWREV_LEN,
543 ACX1xx_IE_FCS_ERROR_COUNT_LEN,
544 ACX1xx_IE_MEDIUM_USAGE_LEN,
545 ACX1xx_IE_RXCONFIG_LEN,
548 sizeof(fw_stats_t) - 4,
550 ACX1xx_IE_FEATURE_CONFIG_LEN,
551 ACX111_IE_KEY_CHOOSE_LEN,
552 ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
553 ACX1FF_IE_WONE_CONFIG_LEN,
555 ACX1FF_IE_TID_CONFIG_LEN,
559 ACX1FF_IE_CALIB_ASSESSMENT_LEN,
560 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
561 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
562 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
564 ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
565 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
566 ACX1FF_IE_CCA_THRESHOLD_LEN,
567 ACX1FF_IE_EVENT_MASK_LEN,
568 ACX1FF_IE_DTIM_PERIOD_LEN,
570 ACX1FF_IE_ACI_CONFIG_SET_LEN,
577 ACX1FF_IE_EEPROM_VER_LEN,
580 static const u16 acx111_ie_len_dot11[] = {
582 ACX1xx_IE_DOT11_STATION_ID_LEN,
584 ACX100_IE_DOT11_BEACON_PERIOD_LEN,
585 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
586 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
587 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
588 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
589 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
591 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
592 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
594 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
595 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
596 ACX100_IE_DOT11_ED_THRESHOLD_LEN,
597 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
604 #undef FUNC
605 #define FUNC "configure"
606 #if !ACX_DEBUG
607 int acx_s_configure(acx_device_t * adev, void *pdr, int type)
609 #else
611 acx_s_configure_debug(acx_device_t * adev, void *pdr, int type,
612 const char *typestr)
614 #endif
615 u16 len;
616 int res;
618 if (type < 0x1000)
619 len = adev->ie_len[type];
620 else
621 len = adev->ie_len_dot11[type - 0x1000];
623 acx_log(LOG_DEBUG, L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
624 if (unlikely(!len)) {
625 acx_log(LOG_DEBUG, L_ANY, "zero-length type %s?!\n", typestr);
628 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
629 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
630 res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4);
631 if (unlikely(OK != res)) {
632 #if ACX_DEBUG
633 acx_log(LOG_WARNING, L_ANY, "%s: " FUNC "(type:%s) FAILED\n",
634 wiphy_name(adev->ieee->wiphy), typestr);
635 #else
636 acx_log(LOG_WARNING, L_ANY, "%s: " FUNC "(type:0x%X) FAILED\n",
637 wiphy_name(adev->ieee->wiphy), type);
638 #endif
639 /* dump_stack() is already done in issue_cmd() */
641 return res;
644 #undef FUNC
645 #define FUNC "interrogate"
646 #if !ACX_DEBUG
647 int acx_s_interrogate(acx_device_t * adev, void *pdr, int type)
649 #else
651 acx_s_interrogate_debug(acx_device_t * adev, void *pdr, int type,
652 const char *typestr)
654 #endif
655 u16 len;
656 int res;
658 FN_ENTER;
660 /* FIXME: no check whether this exceeds the array yet.
661 * We should probably remember the number of entries... */
662 if (type < 0x1000)
663 len = adev->ie_len[type];
664 else
665 len = adev->ie_len_dot11[type - 0x1000];
667 acx_log(LOG_DEBUG, L_CTL, FUNC "(type:%s,len:%u)\n", typestr, len);
669 ((acx_ie_generic_t *) pdr)->type = cpu_to_le16(type);
670 ((acx_ie_generic_t *) pdr)->len = cpu_to_le16(len);
671 res = acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, pdr, len + 4);
672 if (unlikely(OK != res)) {
673 #if ACX_DEBUG
674 acx_log(LOG_WARNING, L_ANY, "%s: " FUNC "(type:%s) FAILED\n",
675 wiphy_name(adev->ieee->wiphy), typestr);
676 #else
677 acx_log(LOG_WARNING, L_ANY, "%s: " FUNC "(type:0x%X) FAILED\n",
678 wiphy_name(adev->ieee->wiphy), type);
679 #endif
680 /* dump_stack() is already done in issue_cmd() */
683 FN_EXIT1(res);
684 return res;
687 #if CMD_DISCOVERY
688 void great_inquisitor(acx_device_t * adev)
690 static struct {
691 u16 type;
692 u16 len;
693 /* 0x200 was too large here: */
694 u8 data[0x100 - 4];
695 } __attribute__ ((packed)) ie;
696 u16 type;
698 FN_ENTER;
700 /* 0..0x20, 0x1000..0x1020 */
701 for (type = 0; type <= 0x1020; type++) {
702 if (type == 0x21)
703 type = 0x1000;
704 ie.type = cpu_to_le16(type);
705 ie.len = cpu_to_le16(sizeof(ie) - 4);
706 acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie));
708 FN_EXIT0;
710 #endif
713 #ifdef CONFIG_PROC_FS
714 /***********************************************************************
715 ** /proc files
717 /***********************************************************************
718 ** acx_l_proc_output
719 ** Generate content for our /proc entry
721 ** Arguments:
722 ** buf is a pointer to write output to
723 ** adev is the usual pointer to our private struct acx_device
724 ** Returns:
725 ** number of bytes actually written to buf
726 ** Side effects:
727 ** none
729 static int acx_l_proc_output(char *buf, acx_device_t * adev)
731 char *p = buf;
733 FN_ENTER;
735 p += sprintf(p,
736 "acx driver version:\t\t" ACX_RELEASE "\n"
737 "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n"
738 "chip name:\t\t\t%s (0x%08X)\n"
739 "radio type:\t\t\t0x%02X\n"
740 "form factor:\t\t\t0x%02X\n"
741 "EEPROM version:\t\t\t0x%02X\n"
742 "firmware version:\t\t%s (0x%08X)\n",
743 adev->chip_name, adev->firmware_id,
744 adev->radio_type,
745 adev->form_factor,
746 adev->eeprom_version,
747 adev->firmware_version, adev->firmware_numver);
749 FN_EXIT1(p - buf);
750 return p - buf;
754 /***********************************************************************
756 static int acx_s_proc_diag_output(char *buf, acx_device_t * adev)
758 char *p = buf;
759 unsigned long flags;
760 ssize_t len = 0, partlen;
761 u32 temp1, temp2;
762 u8 *st, *st_end;
763 #ifdef __BIG_ENDIAN
764 u8 *st2;
765 #endif
766 fw_stats_t *fw_stats;
767 char *part_str = NULL;
768 fw_stats_tx_t *tx = NULL;
769 fw_stats_rx_t *rx = NULL;
770 fw_stats_dma_t *dma = NULL;
771 fw_stats_irq_t *irq = NULL;
772 fw_stats_wep_t *wep = NULL;
773 fw_stats_pwr_t *pwr = NULL;
774 fw_stats_mic_t *mic = NULL;
775 fw_stats_aes_t *aes = NULL;
776 fw_stats_event_t *evt = NULL;
778 FN_ENTER;
780 acx_lock(adev, flags);
782 if (IS_PCI(adev))
783 p = acxpci_s_proc_diag_output(p, adev);
785 p += sprintf(p,
786 "\n"
787 "** network status **\n"
788 "dev_state_mask 0x%04X\n"
789 "mode %u, channel %u, "
790 "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
791 adev->dev_state_mask,
792 adev->mode, adev->channel,
793 adev->reg_dom_id, adev->reg_dom_chanmask);
794 p += sprintf(p,
795 "ESSID \"%s\", essid_active %d, essid_len %d, "
796 "essid_for_assoc \"%s\", nick \"%s\"\n"
797 "WEP ena %d, restricted %d, idx %d\n",
798 adev->essid, adev->essid_active, (int)adev->essid_len,
799 adev->essid_for_assoc, adev->nick,
800 adev->wep_enabled, adev->wep_restricted,
801 adev->wep_current_index);
802 p += sprintf(p, "dev_addr " MACSTR "\n", MAC(adev->dev_addr));
803 p += sprintf(p, "bssid " MACSTR "\n", MAC(adev->bssid));
804 p += sprintf(p, "ap_filter " MACSTR "\n", MAC(adev->ap));
806 p += sprintf(p, "\n" "** PHY status **\n"
807 "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
808 "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
809 "rate_basic 0x%04X, rate_oper 0x%04X\n"
810 "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
811 "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
812 adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */
813 adev->sensitivity, adev->antenna, adev->ed_threshold,
814 adev->cca, adev->preamble_mode, adev->rate_basic, adev->rate_oper, adev->rts_threshold,
815 adev->frag_threshold, adev->short_retry, adev->long_retry,
816 adev->msdu_lifetime, adev->listen_interval,
817 adev->beacon_interval);
819 acx_unlock(adev, flags);
821 p += sprintf(p,
822 "\n"
823 "** Firmware **\n"
824 "NOTE: version dependent statistics layout, "
825 "please report if you suspect wrong parsing!\n"
826 "\n" "version \"%s\"\n", adev->firmware_version);
828 /* TODO: may replace kmalloc/memset with kzalloc once
829 * Linux 2.6.14 is widespread */
830 fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL);
831 if (!fw_stats) {
832 FN_EXIT1(0);
833 return 0;
835 memset(fw_stats, 0, sizeof(*fw_stats));
837 st = (u8 *) fw_stats;
839 part_str = "statistics query command";
841 if (OK != acx_s_interrogate(adev, st, ACX1xx_IE_FIRMWARE_STATISTICS))
842 goto fw_stats_end;
844 st += sizeof(u16);
845 len = *(u16 *) st;
847 if (len > sizeof(*fw_stats)) {
848 p += sprintf(p,
849 "firmware version with bigger fw_stats struct detected\n"
850 "(%zu vs. %zu), please report\n", len, sizeof(fw_stats_t));
851 if (len > sizeof(*fw_stats)) {
852 p += sprintf(p, "struct size exceeded allocation!\n");
853 len = sizeof(*fw_stats);
856 st += sizeof(u16);
857 st_end = st - 2 * sizeof(u16) + len;
859 #ifdef __BIG_ENDIAN
860 /* let's make one bold assumption here:
861 * (hopefully!) *all* statistics fields are u32 only,
862 * thus if we need to make endianness corrections
863 * we can simply do them in one go, in advance */
864 st2 = (u8 *) fw_stats;
865 for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4)
866 *(u32 *) st2 = le32_to_cpu(*(u32 *) st2);
867 #endif
869 part_str = "Rx/Tx";
871 /* directly at end of a struct part? --> no error! */
872 if (st == st_end)
873 goto fw_stats_end;
875 tx = (fw_stats_tx_t *) st;
876 st += sizeof(fw_stats_tx_t);
877 rx = (fw_stats_rx_t *) st;
878 st += sizeof(fw_stats_rx_t);
879 partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t);
881 if (IS_ACX100(adev)) {
882 /* at least ACX100 PCI F/W 1.9.8.b
883 * and ACX100 USB F/W 1.0.7-USB
884 * don't have those two fields... */
885 st -= 2 * sizeof(u32);
887 /* our parsing doesn't quite match this firmware yet,
888 * log failure */
889 if (st > st_end)
890 goto fw_stats_fail;
891 temp1 = temp2 = 999999999;
892 } else {
893 if (st > st_end)
894 goto fw_stats_fail;
895 temp1 = rx->rx_aci_events;
896 temp2 = rx->rx_aci_resets;
899 p += sprintf(p,
900 "%s:\n"
901 " tx_desc_overfl %u\n"
902 " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
903 " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n"
904 " rx_aci_events %u, rx_aci_resets %u\n",
905 part_str,
906 tx->tx_desc_of,
907 rx->rx_oom,
908 rx->rx_hdr_of,
909 rx->rx_hw_stuck,
910 rx->rx_dropped_frame,
911 rx->rx_frame_ptr_err, rx->rx_xfr_hint_trig, temp1, temp2);
913 part_str = "DMA";
915 if (st == st_end)
916 goto fw_stats_end;
918 dma = (fw_stats_dma_t *) st;
919 partlen = sizeof(fw_stats_dma_t);
920 st += partlen;
922 if (st > st_end)
923 goto fw_stats_fail;
925 p += sprintf(p,
926 "%s:\n"
927 " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n",
928 part_str,
929 dma->rx_dma_req,
930 dma->rx_dma_err, dma->tx_dma_req, dma->tx_dma_err);
932 part_str = "IRQ";
934 if (st == st_end)
935 goto fw_stats_end;
937 irq = (fw_stats_irq_t *) st;
938 partlen = sizeof(fw_stats_irq_t);
939 st += partlen;
941 if (st > st_end)
942 goto fw_stats_fail;
944 p += sprintf(p,
945 "%s:\n"
946 " cmd_cplt %u, fiq %u\n"
947 " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
948 " irqs %u, tx_procs %u, decrypt_done %u\n"
949 " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
950 " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
951 " host_acks %u, pci_pm %u, acm_wakeups %u\n",
952 part_str,
953 irq->cmd_cplt,
954 irq->fiq,
955 irq->rx_hdrs,
956 irq->rx_cmplt,
957 irq->rx_mem_of,
958 irq->rx_rdys,
959 irq->irqs,
960 irq->tx_procs,
961 irq->decrypt_done,
962 irq->dma_0_done,
963 irq->dma_1_done,
964 irq->tx_exch_complet,
965 irq->commands,
966 irq->rx_procs,
967 irq->hw_pm_mode_changes,
968 irq->host_acks, irq->pci_pm, irq->acm_wakeups);
970 part_str = "WEP";
972 if (st == st_end)
973 goto fw_stats_end;
975 wep = (fw_stats_wep_t *) st;
976 partlen = sizeof(fw_stats_wep_t);
977 st += partlen;
979 if ((IS_PCI(adev) && IS_ACX100(adev))
980 || (IS_USB(adev) && IS_ACX100(adev))
982 /* at least ACX100 PCI F/W 1.9.8.b
983 * and ACX100 USB F/W 1.0.7-USB
984 * don't have those two fields... */
985 st -= 2 * sizeof(u32);
986 if (st > st_end)
987 goto fw_stats_fail;
988 temp1 = temp2 = 999999999;
989 } else {
990 if (st > st_end)
991 goto fw_stats_fail;
992 temp1 = wep->wep_pkt_decrypt;
993 temp2 = wep->wep_decrypt_irqs;
996 p += sprintf(p,
997 "%s:\n"
998 " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
999 " wep_key_not_found %u, wep_decrypt_fail %u\n"
1000 " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
1001 part_str,
1002 wep->wep_key_count,
1003 wep->wep_default_key_count,
1004 wep->dot11_def_key_mib,
1005 wep->wep_key_not_found,
1006 wep->wep_decrypt_fail, temp1, temp2);
1008 part_str = "power";
1010 if (st == st_end)
1011 goto fw_stats_end;
1013 pwr = (fw_stats_pwr_t *) st;
1014 partlen = sizeof(fw_stats_pwr_t);
1015 st += partlen;
1017 if (st > st_end)
1018 goto fw_stats_fail;
1020 p += sprintf(p,
1021 "%s:\n"
1022 " tx_start_ctr %u, no_ps_tx_too_short %u\n"
1023 " rx_start_ctr %u, no_ps_rx_too_short %u\n"
1024 " lppd_started %u\n"
1025 " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n",
1026 part_str,
1027 pwr->tx_start_ctr,
1028 pwr->no_ps_tx_too_short,
1029 pwr->rx_start_ctr,
1030 pwr->no_ps_rx_too_short,
1031 pwr->lppd_started,
1032 pwr->no_lppd_too_noisy,
1033 pwr->no_lppd_too_short, pwr->no_lppd_matching_frame);
1035 part_str = "MIC";
1037 if (st == st_end)
1038 goto fw_stats_end;
1040 mic = (fw_stats_mic_t *) st;
1041 partlen = sizeof(fw_stats_mic_t);
1042 st += partlen;
1044 if (st > st_end)
1045 goto fw_stats_fail;
1047 p += sprintf(p,
1048 "%s:\n"
1049 " mic_rx_pkts %u, mic_calc_fail %u\n",
1050 part_str, mic->mic_rx_pkts, mic->mic_calc_fail);
1052 part_str = "AES";
1054 if (st == st_end)
1055 goto fw_stats_end;
1057 aes = (fw_stats_aes_t *) st;
1058 partlen = sizeof(fw_stats_aes_t);
1059 st += partlen;
1061 if (st > st_end)
1062 goto fw_stats_fail;
1064 p += sprintf(p,
1065 "%s:\n"
1066 " aes_enc_fail %u, aes_dec_fail %u\n"
1067 " aes_enc_pkts %u, aes_dec_pkts %u\n"
1068 " aes_enc_irq %u, aes_dec_irq %u\n",
1069 part_str,
1070 aes->aes_enc_fail,
1071 aes->aes_dec_fail,
1072 aes->aes_enc_pkts,
1073 aes->aes_dec_pkts, aes->aes_enc_irq, aes->aes_dec_irq);
1075 part_str = "event";
1077 if (st == st_end)
1078 goto fw_stats_end;
1080 evt = (fw_stats_event_t *) st;
1081 partlen = sizeof(fw_stats_event_t);
1082 st += partlen;
1084 if (st > st_end)
1085 goto fw_stats_fail;
1087 p += sprintf(p,
1088 "%s:\n"
1089 " heartbeat %u, calibration %u\n"
1090 " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
1091 " oom_late %u\n"
1092 " phy_tx_err %u, tx_stuck %u\n",
1093 part_str,
1094 evt->heartbeat,
1095 evt->calibration,
1096 evt->rx_mismatch,
1097 evt->rx_mem_empty,
1098 evt->rx_pool,
1099 evt->oom_late, evt->phy_tx_err, evt->tx_stuck);
1101 if (st < st_end)
1102 goto fw_stats_bigger;
1104 goto fw_stats_end;
1106 fw_stats_fail:
1107 st -= partlen;
1108 p += sprintf(p,
1109 "failed at %s part (size %zu), offset %zu (struct size %zu), "
1110 "please report\n", part_str, partlen,
1111 ((void *)st - (void *)fw_stats), len);
1113 fw_stats_bigger:
1114 for (; st < st_end; st += 4)
1115 p += sprintf(p,
1116 "UNKN%3d: %u\n",
1117 (int)((void *)st - (void *)fw_stats), *(u32 *) st);
1119 fw_stats_end:
1120 kfree(fw_stats);
1122 FN_EXIT1(p - buf);
1123 return p - buf;
1127 /***********************************************************************
1129 static int acx_s_proc_phy_output(char *buf, acx_device_t * adev)
1131 char *p = buf;
1132 int i;
1134 FN_ENTER;
1137 if (RADIO_RFMD_11 != adev->radio_type) {
1138 printk("sorry, not yet adapted for radio types "
1139 "other than RFMD, please verify "
1140 "PHY size etc. first!\n");
1141 goto end;
1145 /* The PHY area is only 0x80 bytes long; further pages after that
1146 * only have some page number registers with altered value,
1147 * all other registers remain the same. */
1148 for (i = 0; i < 0x80; i++) {
1149 acx_s_read_phy_reg(adev, i, p++);
1152 FN_EXIT1(p - buf);
1153 return p - buf;
1157 /***********************************************************************
1158 ** acx_e_read_proc_XXXX
1159 ** Handle our /proc entry
1161 ** Arguments:
1162 ** standard kernel read_proc interface
1163 ** Returns:
1164 ** number of bytes written to buf
1165 ** Side effects:
1166 ** none
1168 static int
1169 acx_e_read_proc(char *buf, char **start, off_t offset, int count,
1170 int *eof, void *data)
1172 acx_device_t *adev = (acx_device_t *) data;
1173 unsigned long flags;
1174 int length;
1176 FN_ENTER;
1178 acx_sem_lock(adev);
1179 acx_lock(adev, flags);
1180 /* fill buf */
1181 length = acx_l_proc_output(buf, adev);
1182 acx_unlock(adev, flags);
1183 acx_sem_unlock(adev);
1185 /* housekeeping */
1186 if (length <= offset + count)
1187 *eof = 1;
1188 *start = buf + offset;
1189 length -= offset;
1190 if (length > count)
1191 length = count;
1192 if (length < 0)
1193 length = 0;
1194 FN_EXIT1(length);
1195 return length;
1198 static int
1199 acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count,
1200 int *eof, void *data)
1202 acx_device_t *adev = (acx_device_t *) data;
1203 int length;
1205 FN_ENTER;
1207 acx_sem_lock(adev);
1208 /* fill buf */
1209 length = acx_s_proc_diag_output(buf, adev);
1210 acx_sem_unlock(adev);
1212 /* housekeeping */
1213 if (length <= offset + count)
1214 *eof = 1;
1215 *start = buf + offset;
1216 length -= offset;
1217 if (length > count)
1218 length = count;
1219 if (length < 0)
1220 length = 0;
1221 FN_EXIT1(length);
1222 return length;
1225 static int
1226 acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count,
1227 int *eof, void *data)
1229 acx_device_t *adev = (acx_device_t *) data;
1230 int length;
1232 FN_ENTER;
1234 /* fill buf */
1235 length = 0;
1236 if (IS_PCI(adev)) {
1237 acx_sem_lock(adev);
1238 length = acxpci_proc_eeprom_output(buf, adev);
1239 acx_sem_unlock(adev);
1242 /* housekeeping */
1243 if (length <= offset + count)
1244 *eof = 1;
1245 *start = buf + offset;
1246 length -= offset;
1247 if (length > count)
1248 length = count;
1249 if (length < 0)
1250 length = 0;
1251 FN_EXIT1(length);
1252 return length;
1255 static int
1256 acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count,
1257 int *eof, void *data)
1259 acx_device_t *adev = (acx_device_t *) data;
1260 int length;
1262 FN_ENTER;
1264 acx_sem_lock(adev);
1265 /* fill buf */
1266 length = acx_s_proc_phy_output(buf, adev);
1267 acx_sem_unlock(adev);
1269 /* housekeeping */
1270 if (length <= offset + count)
1271 *eof = 1;
1272 *start = buf + offset;
1273 length -= offset;
1274 if (length > count)
1275 length = count;
1276 if (length < 0)
1277 length = 0;
1278 FN_EXIT1(length);
1279 return length;
1283 /***********************************************************************
1284 ** /proc files registration
1286 static const char *const
1287 proc_files[] = { "", "_diag", "_eeprom", "_phy" };
1289 static read_proc_t *const
1290 proc_funcs[] = {
1291 acx_e_read_proc,
1292 acx_e_read_proc_diag,
1293 acx_e_read_proc_eeprom,
1294 acx_e_read_proc_phy
1297 static int manage_proc_entries(struct ieee80211_hw *hw, int remove)
1299 acx_device_t *adev = ieee2adev(hw);
1300 char procbuf[80];
1301 int i;
1303 FN_ENTER;
1305 for (i = 0; i < ARRAY_SIZE(proc_files); i++) {
1306 snprintf(procbuf, sizeof(procbuf),
1307 "driver/acx%s", proc_files[i]);
1308 acx_log(LOG_INFO, L_INIT, "%sing /proc entry %s\n",
1309 remove ? "remov" : "creat", procbuf);
1310 if (!remove) {
1311 if (!create_proc_read_entry
1312 (procbuf, 0, NULL, proc_funcs[i], adev)) {
1313 acx_log(LOG_WARNING, L_ANY,
1314 "cannot register /proc entry %s\n", procbuf);
1315 FN_EXIT1(NOT_OK);
1316 return NOT_OK;
1318 } else {
1319 remove_proc_entry(procbuf, NULL);
1322 FN_EXIT0;
1323 return OK;
1326 int acx_proc_register_entries(struct ieee80211_hw *ieee)
1328 return manage_proc_entries(ieee, 0);
1331 int acx_proc_unregister_entries(struct ieee80211_hw *ieee)
1333 return manage_proc_entries(ieee, 1);
1335 #endif /* CONFIG_PROC_FS */
1337 /****
1338 ** Gathered From rt2x00 and bcm43xx_mac80211 projects
1340 void acx_free_modes(acx_device_t * adev)
1343 // kfree(adev->modes);
1344 // adev->modes = NULL;
1348 #define RATETAB_ENT(_rate, _rateid, _flags) \
1350 .rate = (_rate), \
1351 .val = (_rateid), \
1352 .val2 = (_rateid), \
1353 .flags = (_flags), \
1357 static struct ieee80211_rate __acx_rates[] = {
1358 { .rate = 10,
1359 .val = RATE111_1,
1360 .flags = IEEE80211_RATE_CCK },
1361 { .rate = 20,
1362 .val = RATE111_2,
1363 .flags = IEEE80211_RATE_CCK },
1364 { .rate = 55,
1365 .val = RATE111_5,
1366 .flags = IEEE80211_RATE_CCK },
1367 { .rate = 110,
1368 .val = RATE111_11,
1369 .flags = IEEE80211_RATE_CCK },
1370 { .rate = 60,
1371 .val = RATE111_6,
1372 .flags = IEEE80211_RATE_OFDM },
1373 { .rate = 90,
1374 .val = RATE111_9,
1375 .flags = IEEE80211_RATE_OFDM },
1376 { .rate = 120,
1377 .val = RATE111_12,
1378 .flags = IEEE80211_RATE_OFDM },
1379 { .rate = 180,
1380 .val = RATE111_18,
1381 .flags = IEEE80211_RATE_OFDM },
1382 { .rate = 240,
1383 .val = RATE111_24,
1384 .flags = IEEE80211_RATE_OFDM },
1385 { .rate = 360,
1386 .val = RATE111_36,
1387 .flags = IEEE80211_RATE_OFDM },
1388 { .rate = 480,
1389 .val = RATE111_48,
1390 .flags = IEEE80211_RATE_OFDM },
1391 { .rate = 540,
1392 .val = RATE111_54,
1393 .flags = IEEE80211_RATE_OFDM },
1396 static struct ieee80211_channel channels[] = {
1397 { .chan = 1,
1398 .freq = 2412},
1399 { .chan = 2,
1400 .freq = 2417},
1401 { .chan = 3,
1402 .freq = 2422},
1403 { .chan = 4,
1404 .freq = 2427},
1405 { .chan = 5,
1406 .freq = 2432},
1407 { .chan = 6,
1408 .freq = 2437},
1409 { .chan = 7,
1410 .freq = 2442},
1411 { .chan = 8,
1412 .freq = 2447},
1413 { .chan = 9,
1414 .freq = 2452},
1415 { .chan = 10,
1416 .freq = 2457},
1417 { .chan = 11,
1418 .freq = 2462},
1419 { .chan = 12,
1420 .freq = 2467},
1421 { .chan = 13,
1422 .freq = 2472},
1425 int acx_setup_modes(acx_device_t * adev)
1427 struct ieee80211_hw *hw = adev->ieee;
1428 struct ieee80211_hw_mode *mode;
1429 int err = -ENOMEM;
1431 FN_ENTER;
1433 if (IS_ACX111(adev)) {
1435 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode) * 2, GFP_KERNEL);
1436 err = acx_setup_modes_gphy(adev);
1438 mode = &adev->modes[0];
1440 /* from the zd1211rw driver: - do we need to do the same? */
1442 memcpy(mode->channels, channels, sizeof(channels));
1443 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1446 mode->mode = MODE_IEEE80211G;
1447 mode->num_channels = ARRAY_SIZE(channels);
1448 mode->num_rates = 12;
1449 mode->rates = __acx_rates;
1450 } else {
1452 adev->modes = kzalloc(sizeof(struct ieee80211_hw_mode), GFP_KERNEL);
1453 err = acx_setup_modes_bphy(adev);
1455 mode = &adev->modes[1];
1457 /* from the zd1211rw driver: - do we need to do the same? */
1459 memcpy(mode->channels, channels, sizeof(channels));
1460 memcpy(mode->rates, __acx_rates, sizeof(__acx_rates));
1463 mode->mode = MODE_IEEE80211B;
1464 mode->num_channels = ARRAY_SIZE(channels);
1465 mode->num_rates = 4;
1466 mode->rates = __acx_rates;
1469 /* if (err && adev->modes)
1470 kfree(adev->modes);*/
1472 mode->channels = channels;
1473 err = ieee80211_register_hwmode(hw, mode);
1475 FN_EXIT1(err);
1476 return err;
1480 /***********************************************************************
1481 ** acx_fill_beacon_or_proberesp_template
1483 ** Origin: derived from rt2x00 project
1485 static int
1486 acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
1487 struct acx_template_beacon *templ,
1488 struct sk_buff* skb /* in host order! */)
1490 FN_ENTER;
1492 memcpy(templ,skb->data, skb->len);
1493 FN_EXIT1(skb->len);
1494 return skb->len;
1497 /***********************************************************************
1498 ** acx_s_set_beacon_template
1502 static int
1503 acx_s_set_beacon_template(acx_device_t *adev, struct sk_buff *skb)
1505 struct acx_template_beacon bcn;
1506 int len, result;
1508 FN_ENTER;
1509 acx_log(LOG_INFO, L_ANY, "size of template: %08zX, "
1510 "size of beacon: %08X\n",
1511 sizeof(struct acx_template_beacon),skb->len);
1512 len = acx_fill_beacon_or_proberesp_template(adev, &bcn, skb);
1513 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
1515 FN_EXIT1(result);
1516 return result;
1519 /***********************************************************************
1520 ** acx_cmd_join_bssid
1522 ** Common code for both acx100 and acx111.
1524 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1525 static const u8 bitpos2genframe_txrate[] = {
1526 10, /* 0. 1 Mbit/s */
1527 20, /* 1. 2 Mbit/s */
1528 55, /* 2. 5.5 Mbit/s */
1529 0x0B, /* 3. 6 Mbit/s */
1530 0x0F, /* 4. 9 Mbit/s */
1531 110, /* 5. 11 Mbit/s */
1532 0x0A, /* 6. 12 Mbit/s */
1533 0x0E, /* 7. 18 Mbit/s */
1534 220, /* 8. 22 Mbit/s */
1535 0x09, /* 9. 24 Mbit/s */
1536 0x0D, /* 10. 36 Mbit/s */
1537 0x08, /* 11. 48 Mbit/s */
1538 0x0C, /* 12. 54 Mbit/s */
1539 10, /* 13. 1 Mbit/s, should never happen */
1540 10, /* 14. 1 Mbit/s, should never happen */
1541 10, /* 15. 1 Mbit/s, should never happen */
1544 /* Looks scary, eh?
1545 ** Actually, each one compiled into one AND and one SHIFT,
1546 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1547 static inline unsigned int rate111to5bits(unsigned int rate)
1549 return (rate & 0x7)
1550 | ((rate & RATE111_11) / (RATE111_11 / JOINBSS_RATES_11))
1551 | ((rate & RATE111_22) / (RATE111_22 / JOINBSS_RATES_22));
1555 void acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
1557 acx_joinbss_t tmp;
1558 int dtim_interval;
1559 int i;
1561 if (mac_is_zero(bssid))
1562 return;
1564 FN_ENTER;
1566 dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
1567 1 : adev->dtim_interval;
1569 memset(&tmp, 0, sizeof(tmp));
1571 for (i = 0; i < ETH_ALEN; i++) {
1572 tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
1575 tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
1577 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1578 ** are sent with one of these rates */
1579 if (IS_ACX111(adev)) {
1580 /* It was experimentally determined that rates_basic
1581 ** can take 11g rates as well, not only rates
1582 ** defined with JOINBSS_RATES_BASIC111_nnn.
1583 ** Just use RATE111_nnn constants... */
1584 tmp.u.acx111.dtim_interval = dtim_interval;
1585 tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
1586 acx_log(LOG_INFO, L_ASSOC, "rates_basic:%04X, "
1587 "rates_supported:%04X\n",
1588 adev->rate_basic, adev->rate_oper);
1589 } else {
1590 tmp.u.acx100.dtim_interval = dtim_interval;
1591 tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
1592 tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
1593 acx_log(LOG_INFO, L_ASSOC, "rates_basic:%04X->%02X, "
1594 "rates_supported:%04X->%02X\n",
1595 adev->rate_basic, tmp.u.acx100.rates_basic,
1596 adev->rate_oper, tmp.u.acx100.rates_supported);
1599 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1600 ** will be sent (rate/modulation/preamble) */
1601 tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
1602 tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
1603 /* we can use short pre *if* all peers can understand it */
1604 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1606 /* we switch fw to STA mode in MONITOR mode, it seems to be
1607 ** the only mode where fw does not emit beacons by itself
1608 ** but allows us to send anything (we really want to retain
1609 ** ability to tx arbitrary frames in MONITOR mode)
1611 tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
1612 tmp.channel = adev->channel;
1613 tmp.essid_len = adev->essid_len;
1615 memcpy(tmp.essid, adev->essid, tmp.essid_len);
1616 acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
1618 acx_log(LOG_DEBUG, L_ASSOC, "BSS_Type = %u\n", tmp.macmode);
1619 acx_log(LOG_DEBUG, L_ASSOC, "JoinBSSID MAC:" MACSTR "\n",
1620 adev->bssid, "\n");
1622 /* acx_update_capabilities(adev); */
1623 FN_EXIT0;
1626 /***********************************************************************
1627 ** acxpci_i_set_multicast_list
1628 ** FIXME: most likely needs refinement
1631 void acx_i_set_multicast_list(struct ieee80211_hw *hw,
1632 unsigned int changed_flags,
1633 unsigned int *total_flags,
1634 int mc_count, struct dev_addr_list *mc_list)
1636 acx_device_t *adev = ieee2adev(hw);
1637 unsigned long flags;
1639 FN_ENTER;
1641 acx_lock(adev, flags);
1643 changed_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1644 FIF_CONTROL | FIF_OTHER_BSS);
1645 *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL |
1646 FIF_CONTROL | FIF_OTHER_BSS);
1647 /* if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0)
1648 return; */
1650 if (*total_flags) {
1651 SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1652 CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1653 SET_BIT(adev->set_mask, SET_RXCONFIG);
1654 /* let kernel know in case *we* needed to set promiscuous */
1655 } else {
1656 CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
1657 SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
1658 SET_BIT(adev->set_mask, SET_RXCONFIG);
1661 /* cannot update card settings directly here, atomic context */
1662 acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
1664 acx_unlock(adev, flags);
1666 FN_EXIT0;
1669 /***********************************************************************
1670 ** acx111 feature config
1672 ** Obvious
1674 static int
1675 acx111_s_get_feature_config(acx_device_t * adev,
1676 u32 * feature_options, u32 * data_flow_options)
1678 struct acx111_ie_feature_config feat;
1680 FN_ENTER;
1682 if (!IS_ACX111(adev)) {
1683 return NOT_OK;
1686 memset(&feat, 0, sizeof(feat));
1688 if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1689 FN_EXIT1(NOT_OK);
1690 return NOT_OK;
1692 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
1693 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1694 feat.feature_options, feat.data_flow_options);
1696 if (feature_options)
1697 *feature_options = le32_to_cpu(feat.feature_options);
1698 if (data_flow_options)
1699 *data_flow_options = le32_to_cpu(feat.data_flow_options);
1701 FN_EXIT0;
1702 return OK;
1706 static int
1707 acx111_s_set_feature_config(acx_device_t * adev,
1708 u32 feature_options, u32 data_flow_options,
1709 unsigned int mode
1710 /* 0 == remove, 1 == add, 2 == set */ )
1712 struct acx111_ie_feature_config feat;
1714 FN_ENTER;
1716 if (!IS_ACX111(adev)) {
1717 FN_EXIT1(NOT_OK);
1718 return NOT_OK;
1721 if ((mode < 0) || (mode > 2)) {
1722 FN_EXIT1(NOT_OK);
1723 return NOT_OK;
1726 if (mode != 2)
1727 /* need to modify old data */
1728 acx111_s_get_feature_config(adev, &feat.feature_options,
1729 &feat.data_flow_options);
1730 else {
1731 /* need to set a completely new value */
1732 feat.feature_options = 0;
1733 feat.data_flow_options = 0;
1736 if (mode == 0) { /* remove */
1737 CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
1738 CLEAR_BIT(feat.data_flow_options,
1739 cpu_to_le32(data_flow_options));
1740 } else { /* add or set */
1741 SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
1742 SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
1745 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
1746 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1747 "new: feature 0x%08X dataflow 0x%08X\n",
1748 feature_options, data_flow_options, mode,
1749 le32_to_cpu(feat.feature_options),
1750 le32_to_cpu(feat.data_flow_options));
1752 if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
1753 FN_EXIT1(NOT_OK);
1754 return NOT_OK;
1757 FN_EXIT0;
1758 return OK;
1761 static inline int acx111_s_feature_off(acx_device_t * adev, u32 f, u32 d)
1763 return acx111_s_set_feature_config(adev, f, d, 0);
1765 static inline int acx111_s_feature_on(acx_device_t * adev, u32 f, u32 d)
1767 return acx111_s_set_feature_config(adev, f, d, 1);
1769 static inline int acx111_s_feature_set(acx_device_t * adev, u32 f, u32 d)
1771 return acx111_s_set_feature_config(adev, f, d, 2);
1775 /***********************************************************************
1776 ** acx100_s_init_memory_pools
1778 static int
1779 acx100_s_init_memory_pools(acx_device_t * adev, const acx_ie_memmap_t * mmt)
1781 acx100_ie_memblocksize_t MemoryBlockSize;
1782 acx100_ie_memconfigoption_t MemoryConfigOption;
1783 int TotalMemoryBlocks;
1784 int RxBlockNum;
1785 int TotalRxBlockSize;
1786 int TxBlockNum;
1787 int TotalTxBlockSize;
1789 FN_ENTER;
1791 /* Let's see if we can follow this:
1792 first we select our memory block size (which I think is
1793 completely arbitrary) */
1794 MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
1796 /* Then we alert the card to our decision of block size */
1797 if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
1798 goto bad;
1801 /* We figure out how many total blocks we can create, using
1802 the block size we chose, and the beginning and ending
1803 memory pointers, i.e.: end-start/size */
1804 TotalMemoryBlocks =
1805 (le32_to_cpu(mmt->PoolEnd) -
1806 le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
1808 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "TotalMemoryBlocks=%u (%u bytes)\n",
1809 TotalMemoryBlocks, TotalMemoryBlocks * adev->memblocksize);
1811 /* MemoryConfigOption.DMA_config bitmask:
1812 access to ACX memory is to be done:
1813 0x00080000 using PCI conf space?!
1814 0x00040000 using IO instructions?
1815 0x00000000 using memory access instructions
1816 0x00020000 using local memory block linked list (else what?)
1817 0x00010000 using host indirect descriptors (else host must access ACX memory?)
1819 if (IS_PCI(adev)) {
1820 MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
1821 /* Declare start of the Rx host pool */
1822 MemoryConfigOption.pRxHostDesc =
1823 cpu2acx(adev->rxhostdesc_startphy);
1824 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "pRxHostDesc 0x%08X, "
1825 "rxhostdesc_startphy 0x%lX\n",
1826 acx2cpu(MemoryConfigOption.pRxHostDesc),
1827 (long)adev->rxhostdesc_startphy);
1828 } else {
1829 MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
1832 /* 50% of the allotment of memory blocks go to tx descriptors */
1833 TxBlockNum = TotalMemoryBlocks / 2;
1834 MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
1836 /* and 50% go to the rx descriptors */
1837 RxBlockNum = TotalMemoryBlocks - TxBlockNum;
1838 MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
1840 /* size of the tx and rx descriptor queues */
1841 TotalTxBlockSize = TxBlockNum * adev->memblocksize;
1842 TotalRxBlockSize = RxBlockNum * adev->memblocksize;
1843 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "TxBlockNum %u RxBlockNum %u "
1844 "TotalTxBlockSize %u TotalTxBlockSize %u\n",
1845 TxBlockNum, RxBlockNum, TotalTxBlockSize, TotalRxBlockSize);
1848 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1849 MemoryConfigOption.rx_mem =
1850 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
1852 /* align the rx descriptor queue to units of 0x20
1853 * and offset it by the tx descriptor queue */
1854 MemoryConfigOption.tx_mem =
1855 cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize +
1856 0x1f) & ~0x1f);
1857 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "rx_mem %08X rx_mem %08X\n",
1858 MemoryConfigOption.tx_mem, MemoryConfigOption.rx_mem);
1860 /* alert the device to our decision */
1861 if (OK !=
1862 acx_s_configure(adev, &MemoryConfigOption,
1863 ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
1864 goto bad;
1867 /* and tell the device to kick it into gear */
1868 if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
1869 goto bad;
1871 FN_EXIT1(OK);
1872 return OK;
1873 bad:
1874 FN_EXIT1(NOT_OK);
1875 return NOT_OK;
1879 /***********************************************************************
1880 ** acx100_s_create_dma_regions
1882 ** Note that this fn messes up heavily with hardware, but we cannot
1883 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1885 /* OLD CODE? - let's rewrite it! */
1886 static int acx100_s_create_dma_regions(acx_device_t * adev)
1888 acx100_ie_queueconfig_t queueconf;
1889 acx_ie_memmap_t memmap;
1890 int res = NOT_OK;
1891 u32 tx_queue_start, rx_queue_start;
1893 FN_ENTER;
1895 /* read out the acx100 physical start address for the queues */
1896 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1897 goto fail;
1900 tx_queue_start = le32_to_cpu(memmap.QueueStart);
1901 rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
1903 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "initializing Queue Indicator\n");
1905 memset(&queueconf, 0, sizeof(queueconf));
1907 /* Not needed for PCI, so we can avoid setting them altogether */
1908 if (IS_USB(adev)) {
1909 queueconf.NumTxDesc = USB_TX_CNT;
1910 queueconf.NumRxDesc = USB_RX_CNT;
1913 /* calculate size of queues */
1914 queueconf.AreaSize = cpu_to_le32(TX_CNT * sizeof(txdesc_t) +
1915 RX_CNT * sizeof(rxdesc_t) + 8);
1916 queueconf.NumTxQueues = 1; /* number of tx queues */
1917 /* sets the beginning of the tx descriptor queue */
1918 queueconf.TxQueueStart = memmap.QueueStart;
1919 /* done by memset: queueconf.TxQueuePri = 0; */
1920 queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
1921 queueconf.QueueOptions = 1; /* auto reset descriptor */
1922 /* sets the end of the rx descriptor queue */
1923 queueconf.QueueEnd =
1924 cpu_to_le32(rx_queue_start + RX_CNT * sizeof(rxdesc_t)
1926 /* sets the beginning of the next queue */
1927 queueconf.HostQueueEnd =
1928 cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
1929 if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
1930 goto fail;
1933 if (IS_PCI(adev)) {
1934 /* sets the beginning of the rx descriptor queue, after the tx descrs */
1935 if (OK != acxpci_s_create_hostdesc_queues(adev))
1936 goto fail;
1937 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
1940 if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1941 goto fail;
1944 memmap.PoolStart = cpu_to_le32((le32_to_cpu(memmap.QueueEnd) + 4 +
1945 0x1f) & ~0x1f);
1947 if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
1948 goto fail;
1951 if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
1952 goto fail;
1955 res = OK;
1956 goto end;
1958 fail:
1959 acx_s_mwait(1000); /* ? */
1960 if (IS_PCI(adev))
1961 acxpci_free_desc_queues(adev);
1962 end:
1963 FN_EXIT1(res);
1964 return res;
1968 /***********************************************************************
1969 ** acx111_s_create_dma_regions
1971 ** Note that this fn messes heavily with hardware, but we cannot
1972 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1974 #define ACX111_PERCENT(percent) ((percent)/5)
1976 static int acx111_s_create_dma_regions(acx_device_t * adev)
1978 struct acx111_ie_memoryconfig memconf;
1979 struct acx111_ie_queueconfig queueconf;
1980 u32 tx_queue_start, rx_queue_start;
1982 FN_ENTER;
1984 /* Calculate memory positions and queue sizes */
1986 /* Set up our host descriptor pool + data pool */
1987 if (IS_PCI(adev)) {
1988 if (OK != acxpci_s_create_hostdesc_queues(adev))
1989 goto fail;
1992 memset(&memconf, 0, sizeof(memconf));
1993 /* the number of STAs (STA contexts) to support
1994 ** NB: was set to 1 and everything seemed to work nevertheless... */
1995 memconf.no_of_stations = 1; //cpu_to_le16(VEC_SIZE(adev->sta_list));
1996 /* specify the memory block size. Default is 256 */
1997 memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
1998 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
1999 memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
2000 /* set the count of our queues
2001 ** NB: struct acx111_ie_memoryconfig shall be modified
2002 ** if we ever will switch to more than one rx and/or tx queue */
2003 memconf.count_rx_queues = 1;
2004 memconf.count_tx_queues = 1;
2005 /* 0 == Busmaster Indirect Memory Organization, which is what we want
2006 * (using linked host descs with their allocated mem).
2007 * 2 == Generic Bus Slave */
2008 /* done by memset: memconf.options = 0; */
2009 /* let's use 25% for fragmentations and 75% for frame transfers
2010 * (specified in units of 5%) */
2011 memconf.fragmentation = ACX111_PERCENT(75);
2012 /* Rx descriptor queue config */
2013 memconf.rx_queue1_count_descs = RX_CNT;
2014 memconf.rx_queue1_type = 7; /* must be set to 7 */
2015 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2016 if (IS_PCI(adev)) {
2017 memconf.rx_queue1_host_rx_start =
2018 cpu2acx(adev->rxhostdesc_startphy);
2020 /* Tx descriptor queue config */
2021 memconf.tx_queue1_count_descs = TX_CNT;
2022 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2024 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
2025 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2026 ** But it is actually correct wrt IE numbers.
2027 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
2028 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2029 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2030 if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
2031 goto fail;
2034 acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
2036 tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
2037 rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
2039 acx_log(LOG_DEBUG, L_INIT, "dump queue head (from card):\n"
2040 "len: %u\n"
2041 "tx_memory_block_address: %X\n"
2042 "rx_memory_block_address: %X\n"
2043 "tx1_queue address: %X\n"
2044 "rx1_queue address: %X\n",
2045 le16_to_cpu(queueconf.len),
2046 le32_to_cpu(queueconf.tx_memory_block_address),
2047 le32_to_cpu(queueconf.rx_memory_block_address),
2048 tx_queue_start, rx_queue_start);
2050 if (IS_PCI(adev))
2051 acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
2053 FN_EXIT1(OK);
2054 return OK;
2055 fail:
2056 if (IS_PCI(adev))
2057 acxpci_free_desc_queues(adev);
2059 FN_EXIT1(NOT_OK);
2060 return NOT_OK;
2064 /***********************************************************************
2066 static void acx_s_initialize_rx_config(acx_device_t * adev)
2068 struct {
2069 u16 id;
2070 u16 len;
2071 u16 rx_cfg1;
2072 u16 rx_cfg2;
2073 } __attribute__ ((packed)) cfg;
2074 switch (adev->mode) {
2075 case ACX_MODE_MONITOR:
2076 adev->rx_config_1 = (u16) (0
2077 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2078 /* | RX_CFG1_FILTER_SSID */
2079 /* | RX_CFG1_FILTER_BCAST */
2080 /* | RX_CFG1_RCV_MC_ADDR1 */
2081 /* | RX_CFG1_RCV_MC_ADDR0 */
2082 /* | RX_CFG1_FILTER_ALL_MULTI */
2083 /* | RX_CFG1_FILTER_BSSID */
2084 /* | RX_CFG1_FILTER_MAC */
2085 | RX_CFG1_RCV_PROMISCUOUS
2086 | RX_CFG1_INCLUDE_FCS
2087 /* | RX_CFG1_INCLUDE_PHY_HDR */
2089 adev->rx_config_2 = (u16) (0
2090 | RX_CFG2_RCV_ASSOC_REQ
2091 | RX_CFG2_RCV_AUTH_FRAMES
2092 | RX_CFG2_RCV_BEACON_FRAMES
2093 | RX_CFG2_RCV_CONTENTION_FREE
2094 | RX_CFG2_RCV_CTRL_FRAMES
2095 | RX_CFG2_RCV_DATA_FRAMES
2096 | RX_CFG2_RCV_BROKEN_FRAMES
2097 | RX_CFG2_RCV_MGMT_FRAMES
2098 | RX_CFG2_RCV_PROBE_REQ
2099 | RX_CFG2_RCV_PROBE_RESP
2100 | RX_CFG2_RCV_ACK_FRAMES
2101 | RX_CFG2_RCV_OTHER);
2102 break;
2103 default:
2104 adev->rx_config_1 = (u16) (0
2105 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2106 /* | RX_CFG1_FILTER_SSID */
2107 /* | RX_CFG1_FILTER_BCAST */
2108 /* | RX_CFG1_RCV_MC_ADDR1 */
2109 /* | RX_CFG1_RCV_MC_ADDR0 */
2110 /* | RX_CFG1_FILTER_ALL_MULTI */
2111 /* | RX_CFG1_FILTER_BSSID */
2112 /* | RX_CFG1_FILTER_MAC */
2113 | RX_CFG1_RCV_PROMISCUOUS
2114 /* | RX_CFG1_INCLUDE_FCS */
2115 /* | RX_CFG1_INCLUDE_PHY_HDR */
2117 adev->rx_config_2 = (u16) (0
2118 | RX_CFG2_RCV_ASSOC_REQ
2119 | RX_CFG2_RCV_AUTH_FRAMES
2120 | RX_CFG2_RCV_BEACON_FRAMES
2121 | RX_CFG2_RCV_CONTENTION_FREE
2122 | RX_CFG2_RCV_CTRL_FRAMES
2123 | RX_CFG2_RCV_DATA_FRAMES
2124 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2125 | RX_CFG2_RCV_MGMT_FRAMES
2126 | RX_CFG2_RCV_PROBE_REQ
2127 | RX_CFG2_RCV_PROBE_RESP
2128 | RX_CFG2_RCV_ACK_FRAMES
2129 | RX_CFG2_RCV_OTHER);
2130 break;
2132 adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
2134 if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
2135 || (adev->firmware_numver >= 0x02000000))
2136 adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
2137 else
2138 adev->phy_header_len = 0;
2140 acx_log(LOG_DEBUG, L_INIT, "setting RXconfig to %04X:%04X\n",
2141 adev->rx_config_1, adev->rx_config_2);
2143 cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
2144 cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
2145 acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
2149 /***********************************************************************
2150 ** FIXME: this should be solved in a general way for all radio types
2151 ** by decoding the radio firmware module,
2152 ** since it probably has some standard structure describing how to
2153 ** set the power level of the radio module which it controls.
2154 ** Or maybe not, since the radio module probably has a function interface
2155 ** instead which then manages Tx level programming :-\
2157 ** Obvious
2159 static int acx111_s_set_tx_level(acx_device_t * adev, u8 level_dbm)
2161 struct acx111_ie_tx_level tx_level;
2163 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2164 * 1 (30mW) [15dBm]
2165 * 2 (10mW) [10dBm]
2166 * For now, just assume all other acx111 cards have the same.
2167 * FIXME: Ideally we would query it here, but we first need a
2168 * standard way to query individual configoptions easily.
2169 * Well, now we have proper cfgopt txpower variables, but this still
2170 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2171 if (level_dbm <= 12) {
2172 tx_level.level = 2; /* 10 dBm */
2173 adev->tx_level_dbm = 10;
2174 } else {
2175 tx_level.level = 1; /* 15 dBm */
2176 adev->tx_level_dbm = 15;
2178 if (level_dbm != adev->tx_level_dbm)
2179 acx_log(LOG_WARNING, L_INIT, "acx111 firmware has specific "
2180 "power levels only: adjusted %d dBm to %d dBm!\n",
2181 level_dbm, adev->tx_level_dbm);
2183 return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
2186 static int acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
2188 if (IS_ACX111(adev)) {
2189 return acx111_s_set_tx_level(adev, level_dbm);
2191 if (IS_PCI(adev)) {
2192 return acx100pci_s_set_tx_level(adev, level_dbm);
2195 return OK;
2199 /***********************************************************************
2200 ** acx_s_set_defaults
2202 void acx_s_set_defaults(acx_device_t * adev)
2204 struct ieee80211_conf *conf = &adev->ieee->conf;
2205 unsigned long flags;
2206 u16 default_irq_mask = (IS_ACX111(adev)) ?
2207 ACX111_DEFAULT_IRQ_MASK :
2208 ACX100_DEFAULT_IRQ_MASK;
2210 FN_ENTER;
2212 acx_lock(adev, flags);
2213 /* do it before getting settings, prevent bogus channel 0 warning */
2214 adev->channel = 1;
2216 /* query some settings from the card.
2217 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2218 * query is REQUIRED, otherwise the card won't work correctly! */
2219 adev->get_mask =
2220 GETSET_ANTENNA | GETSET_SENSITIVITY | GETSET_STATION_ID |
2221 GETSET_REG_DOMAIN;
2222 /* Only ACX100 supports ED and CCA */
2223 if (IS_ACX100(adev))
2224 adev->get_mask |= GETSET_CCA | GETSET_ED_THRESH;
2226 acx_unlock(adev, flags);
2228 acx_s_update_card_settings(adev);
2230 acx_lock(adev, flags);
2232 /* set our global interrupt mask */
2233 if (IS_PCI(adev))
2234 adev->irq_mask = default_irq_mask;
2236 adev->led_power = 1; /* LED is active on startup */
2237 adev->brange_max_quality = 60; /* LED blink max quality is 60 */
2238 adev->brange_time_last_state_change = jiffies;
2240 /* copy the MAC address we just got from the card
2241 * into our MAC address used during current 802.11 session */
2242 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
2243 MAC_BCAST(adev->ap);
2245 adev->essid_len =
2246 snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
2247 adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
2248 adev->essid_active = 1;
2250 /* we have a nick field to waste, so why not abuse it
2251 * to announce the driver version? ;-) */
2252 strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
2254 if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
2255 /* first regulatory domain entry in EEPROM == default reg. domain */
2256 adev->reg_dom_id = adev->cfgopt_domains.list[0];
2259 /* 0xffff would be better, but then we won't get a "scan complete"
2260 * interrupt, so our current infrastructure will fail: */
2261 adev->scan_count = 1;
2262 adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
2263 adev->scan_duration = 100;
2264 adev->scan_probe_delay = 200;
2265 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2266 adev->scan_rate = ACX_SCAN_RATE_1;
2269 adev->mode = ACX_MODE_2_STA;
2270 adev->listen_interval = 100;
2271 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
2272 adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
2274 adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
2276 adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
2277 adev->frag_threshold = 2346;
2279 /* use standard default values for retry limits */
2280 adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
2281 adev->long_retry = 4; /* max. retries for long (RTS) packets */
2283 adev->preamble_mode = 2; /* auto */
2284 adev->fallback_threshold = 3;
2285 adev->stepup_threshold = 10;
2286 adev->rate_bcast = RATE111_1;
2287 adev->rate_bcast100 = RATE100_1;
2288 adev->rate_basic = RATE111_1 | RATE111_2;
2289 adev->rate_auto = 1;
2290 if (IS_ACX111(adev)) {
2291 adev->rate_oper = RATE111_ALL;
2292 } else {
2293 adev->rate_oper = RATE111_ACX100_COMPAT;
2296 /* Supported Rates element - the rates here are given in units of
2297 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2298 acx_l_update_ratevector(adev);
2300 /* set some more defaults */
2301 if (IS_ACX111(adev)) {
2302 /* 30mW (15dBm) is default, at least in my acx111 card: */
2303 adev->tx_level_dbm = 15;
2304 conf->power_level = adev->tx_level_dbm;
2305 acx_unlock(adev, flags);
2306 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2307 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2308 acx_lock(adev, flags);
2309 } else {
2310 /* don't use max. level, since it might be dangerous
2311 * (e.g. WRT54G people experience
2312 * excessive Tx power damage!) */
2313 adev->tx_level_dbm = 18;
2314 conf->power_level = adev->tx_level_dbm;
2315 acx_unlock(adev, flags);
2316 acx_s_set_tx_level(adev, adev->tx_level_dbm);
2317 SET_BIT(adev->set_mask, GETSET_TXPOWER);
2318 acx_lock(adev, flags);
2321 /* adev->tx_level_auto = 1; */
2322 if (IS_ACX111(adev)) {
2323 /* start with sensitivity level 1 out of 3: */
2324 adev->sensitivity = 1;
2327 /* #define ENABLE_POWER_SAVE */
2328 #ifdef ENABLE_POWER_SAVE
2329 adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
2330 adev->ps_listen_interval = 1;
2331 adev->ps_options =
2332 PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
2333 adev->ps_hangover_period = 30;
2334 adev->ps_enhanced_transition_time = 0;
2335 #else
2336 adev->ps_wakeup_cfg = 0;
2337 adev->ps_listen_interval = 0;
2338 adev->ps_options = 0;
2339 adev->ps_hangover_period = 0;
2340 adev->ps_enhanced_transition_time = 0;
2341 #endif
2343 /* These settings will be set in fw on ifup */
2344 adev->set_mask = 0 | GETSET_RETRY | SET_MSDU_LIFETIME
2345 /* configure card to do rate fallback when in auto rate mode */
2346 | SET_RATE_FALLBACK | SET_RXCONFIG | GETSET_TXPOWER
2347 /* better re-init the antenna value we got above */
2348 | GETSET_ANTENNA
2349 #if POWER_SAVE_80211
2350 | GETSET_POWER_80211
2351 #endif
2354 acx_unlock(adev, flags);
2355 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2357 acx_s_initialize_rx_config(adev);
2359 FN_EXIT0;
2363 /***********************************************************************
2364 ** acx_l_process_rxbuf
2366 ** NB: used by USB code also
2368 void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf)
2370 struct ieee80211_hdr *hdr;
2371 u16 fc, buf_len;
2373 FN_ENTER;
2375 hdr = acx_get_wlan_hdr(adev, rxbuf);
2376 fc = le16_to_cpu(hdr->frame_control);
2377 /* length of frame from control field to first byte of FCS */
2378 buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
2380 acx_log_dump(LOG_DEBUG, L_DATA, hdr, buf_len, "RX: 802.11 buffer:\n");
2382 acx_l_rx(adev, rxbuf);
2383 /* Now check Rx quality level, AFTER processing packet.
2384 * I tried to figure out how to map these levels to dBm
2385 * values, but for the life of me I really didn't
2386 * manage to get it. Either these values are not meant to
2387 * be expressed in dBm, or it's some pretty complicated
2388 * calculation. */
2390 #ifdef FROM_SCAN_SOURCE_ONLY
2391 /* only consider packets originating from the MAC
2392 * address of the device that's managing our BSSID.
2393 * Disable it for now, since it removes information (levels
2394 * from different peers) and slows the Rx path. *//*
2395 if (adev->ap_client && mac_is_equal(hdr->a2, adev->ap_client->address)) {
2397 #endif
2399 FN_EXIT0;
2403 /***********************************************************************
2404 ** acx_l_handle_txrate_auto
2406 ** Theory of operation:
2407 ** client->rate_cap is a bitmask of rates client is capable of.
2408 ** client->rate_cfg is a bitmask of allowed (configured) rates.
2409 ** It is set as a result of iwconfig rate N [auto]
2410 ** or iwpriv set_rates "N,N,N N,N,N" commands.
2411 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
2412 ** auto (0x00ff == 18Mbit or any lower value),
2413 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
2415 ** client->rate_cur is a value for rate111 field in tx descriptor.
2416 ** It is always set to txrate_cfg sans zero or more most significant
2417 ** bits. This routine handles selection of new rate_cur value depending on
2418 ** outcome of last tx event.
2420 ** client->rate_100 is a precalculated rate value for acx100
2421 ** (we can do without it, but will need to calculate it on each tx).
2423 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
2424 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
2425 ** In theory you can implement it, but so far it is considered not worth doing.
2427 ** 22Mbit, of course, is PBCC always. */
2429 /* maps acx100 tx descr rate field to acx111 one */
2431 static u16 rate100to111(u8 r)
2433 switch (r) {
2434 case RATE100_1:
2435 return RATE111_1;
2436 case RATE100_2:
2437 return RATE111_2;
2438 case RATE100_5:
2439 case (RATE100_5 | RATE100_PBCC511):
2440 return RATE111_5;
2441 case RATE100_11:
2442 case (RATE100_11 | RATE100_PBCC511):
2443 return RATE111_11;
2444 case RATE100_22:
2445 return RATE111_22;
2446 default:
2447 printk("acx: unexpected acx100 txrate: %u! "
2448 "Please report\n", r);
2449 return RATE111_1;
2456 acx_i_start_xmit(struct ieee80211_hw *hw,
2457 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2459 acx_device_t *adev = ieee2adev(hw);
2460 tx_t *tx;
2461 void *txbuf;
2462 unsigned long flags;
2464 int txresult = NOT_OK;
2466 FN_ENTER;
2468 if (unlikely(!skb)) {
2469 /* indicate success */
2470 txresult = OK;
2471 goto out;
2474 if (unlikely(!adev)) {
2475 goto out;
2478 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2479 goto out;
2481 if (unlikely(!adev->initialized)) {
2482 goto out;
2485 acx_lock(adev, flags);
2487 tx = acx_l_alloc_tx(adev);
2489 if (unlikely(!tx)) {
2490 acx_log_ratelimited(LOG_WARNING, L_ANY, "%s: start_xmit: "
2491 "txdesc ring is full, dropping tx\n",
2492 wiphy_name(adev->ieee->wiphy));
2493 txresult = NOT_OK;
2494 goto out_unlock;
2497 txbuf = acx_l_get_txbuf(adev, tx);
2499 if (unlikely(!txbuf)) {
2500 /* Card was removed */
2501 txresult = NOT_OK;
2502 acx_l_dealloc_tx(adev, tx);
2503 goto out_unlock;
2505 memcpy(txbuf, skb->data, skb->len);
2507 acx_l_tx_data(adev, tx, skb->len, ctl,skb);
2509 txresult = OK;
2510 adev->stats.tx_packets++;
2511 adev->stats.tx_bytes += skb->len;
2513 out_unlock:
2514 acx_unlock(adev, flags);
2516 out:
2517 FN_EXIT1(txresult);
2518 return txresult;
2520 /***********************************************************************
2521 ** acx_l_update_ratevector
2523 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
2525 const u8 acx_bitpos2ratebyte[] = {
2526 DOT11RATEBYTE_1,
2527 DOT11RATEBYTE_2,
2528 DOT11RATEBYTE_5_5,
2529 DOT11RATEBYTE_6_G,
2530 DOT11RATEBYTE_9_G,
2531 DOT11RATEBYTE_11,
2532 DOT11RATEBYTE_12_G,
2533 DOT11RATEBYTE_18_G,
2534 DOT11RATEBYTE_22,
2535 DOT11RATEBYTE_24_G,
2536 DOT11RATEBYTE_36_G,
2537 DOT11RATEBYTE_48_G,
2538 DOT11RATEBYTE_54_G,
2541 void acx_l_update_ratevector(acx_device_t * adev)
2543 u16 bcfg = adev->rate_basic;
2544 u16 ocfg = adev->rate_oper;
2545 u8 *supp = adev->rate_supported;
2546 const u8 *dot11 = acx_bitpos2ratebyte;
2548 FN_ENTER;
2550 while (ocfg) {
2551 if (ocfg & 1) {
2552 *supp = *dot11;
2553 if (bcfg & 1) {
2554 *supp |= 0x80;
2556 supp++;
2558 dot11++;
2559 ocfg >>= 1;
2560 bcfg >>= 1;
2562 adev->rate_supported_len = supp - adev->rate_supported;
2564 acx_log_dump(LOG_DEBUG, L_ASSOC, adev->rate_supported,
2565 adev->rate_supported_len, "new ratevector:\n");
2567 FN_EXIT0;
2570 /***********************************************************************
2571 ** acx_i_timer
2573 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2575 ** Obvious
2577 void acx_i_timer(unsigned long address)
2579 unsigned long flags;
2580 acx_device_t *adev = (acx_device_t *) address;
2582 FN_ENTER;
2584 acx_lock(adev, flags);
2586 FIXME();
2587 /* We need calibration and stats gather tasks to perform here */
2589 acx_unlock(adev, flags);
2591 FN_EXIT0;
2595 /***********************************************************************
2596 ** acx_set_timer
2598 ** Sets the 802.11 state management timer's timeout.
2600 ** Linux derived
2602 void acx_set_timer(acx_device_t * adev, int timeout_us)
2604 FN_ENTER;
2606 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_IRQ,
2607 "%s(%u ms)\n", __func__, timeout_us / 1000);
2609 if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
2610 acx_log(LOG_WARNING, L_ANY, "attempt to set the timer "
2611 "when the card interface is not up!\n");
2612 goto end;
2615 /* first check if the timer was already initialized, THEN modify it */
2616 if (adev->mgmt_timer.function) {
2617 mod_timer(&adev->mgmt_timer,
2618 jiffies + (timeout_us * HZ / 1000000));
2620 end:
2621 FN_EXIT0;
2624 /** acx_plcp_get_bitrate_cck
2626 ** Obvious
2628 static u8 acx_plcp_get_bitrate_cck(u8 plcp)
2630 switch (plcp) {
2631 case 0x0A:
2632 return ACX_CCK_RATE_1MB;
2633 case 0x14:
2634 return ACX_CCK_RATE_2MB;
2635 case 0x37:
2636 return ACX_CCK_RATE_5MB;
2637 case 0x6E:
2638 return ACX_CCK_RATE_11MB;
2640 return 0;
2643 /* Extract the bitrate out of an OFDM PLCP header. */
2644 /** Obvious **/
2645 static u8 acx_plcp_get_bitrate_ofdm(u8 plcp)
2647 switch (plcp & 0xF) {
2648 case 0xB:
2649 return ACX_OFDM_RATE_6MB;
2650 case 0xF:
2651 return ACX_OFDM_RATE_9MB;
2652 case 0xA:
2653 return ACX_OFDM_RATE_12MB;
2654 case 0xE:
2655 return ACX_OFDM_RATE_18MB;
2656 case 0x9:
2657 return ACX_OFDM_RATE_24MB;
2658 case 0xD:
2659 return ACX_OFDM_RATE_36MB;
2660 case 0x8:
2661 return ACX_OFDM_RATE_48MB;
2662 case 0xC:
2663 return ACX_OFDM_RATE_54MB;
2665 return 0;
2669 /***********************************************************************
2670 ** acx_l_rx
2672 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
2673 ** buffer and feeds it to the network stack via netif_rx().
2675 ** Look to bcm43xx or p54
2677 static void acx_l_rx(acx_device_t * adev, rxbuffer_t * rxbuf)
2680 struct ieee80211_rx_status* status = &adev->rx_status;
2681 struct ieee80211_hdr *w_hdr;
2682 struct sk_buff *skb;
2683 int buflen;
2684 FN_ENTER;
2686 if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
2687 acx_log_ratelimited(LOG_WARNING, L_ANY,
2688 "asked to receive a packet but interface is down??\n");
2689 goto out;
2692 w_hdr = acx_get_wlan_hdr(adev, rxbuf);
2693 buflen = RXBUF_BYTES_USED(rxbuf) - ((u8*)w_hdr - (u8*)rxbuf);
2695 * Allocate our skb
2697 skb = dev_alloc_skb(buflen + 2);
2699 if (!skb) {
2700 acx_log_ratelimited(LOG_WARNING, L_ANY,
2701 "skb allocation FAILED\n");
2702 goto out;
2705 skb_reserve(skb, 2);
2706 skb_put(skb, buflen);
2707 memcpy(skb->data, w_hdr, buflen);
2709 // memset(&status, 0, sizeof(status));
2711 status->mactime = rxbuf->time;
2712 status->signal = acx_signal_to_winlevel(rxbuf->phy_level);
2713 status->noise = acx_signal_to_winlevel(rxbuf->phy_snr);
2714 status->flag = 0;
2715 status->rate = rxbuf->phy_plcp_signal;
2716 status->antenna = 1;
2717 if (rxbuf->phy_stat_baseband & (1 << 3)) { /* Uses OFDM */
2718 status->rate = acx_plcp_get_bitrate_ofdm(rxbuf->phy_plcp_signal);
2719 } else {
2720 status->rate = acx_plcp_get_bitrate_cck(rxbuf->phy_plcp_signal);
2724 * FIXME: should it really be done here??
2726 ieee80211_rx_irqsafe(adev->ieee, skb, status);
2727 adev->stats.rx_packets++;
2728 adev->stats.rx_bytes += skb->len;
2729 out:
2730 FN_EXIT0;
2735 /***********************************************************************
2736 ** acx_s_read_fw
2738 ** Loads a firmware image
2740 ** Returns:
2741 ** 0 unable to load file
2742 ** pointer to firmware success
2744 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file,
2745 u32 * size)
2747 firmware_image_t *res;
2748 const struct firmware *fw_entry;
2750 res = NULL;
2751 acx_log(LOG_INFO, L_INIT, "requesting firmware image '%s'\n", file);
2752 if (!request_firmware(&fw_entry, file, dev)) {
2753 *size = 8;
2754 if (fw_entry->size >= 8)
2755 *size = 8 + le32_to_cpu(*(u32 *) (fw_entry->data + 4));
2756 if (fw_entry->size != *size) {
2757 acx_log(LOG_WARNING, L_ANY,
2758 "acx: firmware size does not match "
2759 "firmware header: %d != %d, "
2760 "aborting fw upload\n",
2761 (int)fw_entry->size, (int)*size);
2762 goto release_ret;
2764 res = vmalloc(*size);
2765 if (!res) {
2766 acx_log(LOG_INFO, L_ANY, "acx: no memory for firmware "
2767 "(%u bytes)\n", *size);
2768 goto release_ret;
2770 memcpy(res, fw_entry->data, fw_entry->size);
2771 release_ret:
2772 release_firmware(fw_entry);
2773 return res;
2775 acx_log(LOG_WARNING, L_ANY, "acx: firmware image '%s' was not provided. "
2776 "Check your hotplug scripts\n", file);
2778 /* checksum will be verified in write_fw, so don't bother here */
2779 return res;
2783 /***********************************************************************
2784 ** acx_s_set_wepkey
2786 static void acx100_s_set_wepkey(acx_device_t * adev)
2788 ie_dot11WEPDefaultKey_t dk;
2789 int i;
2791 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2792 if (adev->wep_keys[i].size != 0) {
2793 acx_log(LOG_DEBUG, L_INIT, "setting WEP key: %d with "
2794 "total size: %d\n",
2795 i, (int)adev->wep_keys[i].size);
2796 dk.action = 1;
2797 dk.keySize = adev->wep_keys[i].size;
2798 dk.defaultKeyNum = i;
2799 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2800 acx_s_configure(adev, &dk,
2801 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
2806 static void acx111_s_set_wepkey(acx_device_t * adev)
2808 acx111WEPDefaultKey_t dk;
2809 int i;
2811 for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
2812 if (adev->wep_keys[i].size != 0) {
2813 acx_log(LOG_DEBUG, L_INIT, "setting WEP key: %d with "
2814 "total size: %d\n", i,
2815 (int)adev->wep_keys[i].size);
2816 memset(&dk, 0, sizeof(dk));
2817 dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
2818 dk.keySize = adev->wep_keys[i].size;
2820 /* are these two lines necessary? */
2821 dk.type = 0; /* default WEP key */
2822 dk.index = 0; /* ignored when setting default key */
2824 dk.defaultKeyNum = i;
2825 memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
2826 acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk,
2827 sizeof(dk));
2831 /* Obvious */
2832 static void acx_s_set_wepkey(acx_device_t * adev)
2834 if (IS_ACX111(adev))
2835 acx111_s_set_wepkey(adev);
2836 else
2837 acx100_s_set_wepkey(adev);
2841 /***********************************************************************
2842 ** acx100_s_init_wep
2844 ** FIXME: this should probably be moved into the new card settings
2845 ** management, but since we're also modifying the memory map layout here
2846 ** due to the WEP key space we want, we should take care...
2848 static int acx100_s_init_wep(acx_device_t * adev)
2850 acx100_ie_wep_options_t options;
2851 ie_dot11WEPDefaultKeyID_t dk;
2852 acx_ie_memmap_t pt;
2853 int res = NOT_OK;
2855 FN_ENTER;
2857 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2858 goto fail;
2861 acx_log(LOG_DEBUG, L_REALLYVERBOSE, "CodeEnd:%X\n", pt.CodeEnd);
2863 pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2864 pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
2866 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2867 goto fail;
2870 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
2871 options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
2872 options.WEPOption = 0x00;
2874 acx_log(LOG_DEBUG, L_ASSOC, "writing WEP options\n");
2875 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
2877 acx100_s_set_wepkey(adev);
2879 if (adev->wep_keys[adev->wep_current_index].size != 0) {
2880 acx_log(LOG_DEBUG, L_ASSOC,
2881 "setting active default WEP key number: %d\n",
2882 adev->wep_current_index);
2883 dk.KeyID = adev->wep_current_index;
2884 acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
2886 /* FIXME!!! wep_key_struct is filled nowhere! But adev
2887 * is initialized to 0, and we don't REALLY need those keys either */
2888 /* for (i = 0; i < 10; i++) {
2889 if (adev->wep_key_struct[i].len != 0) {
2890 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
2891 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
2892 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
2893 wep_mgmt.Action = cpu_to_le16(1);
2894 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
2895 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
2896 adev->wep_key_struct[i].index = i;
2902 /* now retrieve the updated WEPCacheEnd pointer... */
2903 if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2904 acx_log(LOG_WARNING, L_ANY,
2905 "%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
2906 wiphy_name(adev->ieee->wiphy));
2907 goto fail;
2909 /* ...and tell it to start allocating templates at that location */
2910 /* (no endianness conversion needed) */
2911 pt.PacketTemplateStart = pt.WEPCacheEnd;
2913 if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
2914 acx_log(LOG_WARNING, L_ANY,
2915 "%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
2916 wiphy_name(adev->ieee->wiphy));
2917 goto fail;
2919 res = OK;
2921 fail:
2922 FN_EXIT1(res);
2923 return res;
2927 static int
2928 acx_s_init_max_template_generic(acx_device_t * adev, unsigned int len,
2929 unsigned int cmd)
2931 int res;
2932 union {
2933 acx_template_nullframe_t null;
2934 acx_template_beacon_t b;
2935 acx_template_tim_t tim;
2936 acx_template_probereq_t preq;
2937 acx_template_proberesp_t presp;
2938 } templ;
2940 memset(&templ, 0, len);
2941 templ.null.size = cpu_to_le16(len - 2);
2942 res = acx_s_issue_cmd(adev, cmd, &templ, len);
2943 return res;
2946 static inline int acx_s_init_max_null_data_template(acx_device_t * adev)
2948 return acx_s_init_max_template_generic(adev,
2949 sizeof(acx_template_nullframe_t),
2950 ACX1xx_CMD_CONFIG_NULL_DATA);
2953 static inline int acx_s_init_max_beacon_template(acx_device_t * adev)
2955 return acx_s_init_max_template_generic(adev,
2956 sizeof(acx_template_beacon_t),
2957 ACX1xx_CMD_CONFIG_BEACON);
2960 static inline int acx_s_init_max_tim_template(acx_device_t * adev)
2962 return acx_s_init_max_template_generic(adev, sizeof(acx_template_tim_t),
2963 ACX1xx_CMD_CONFIG_TIM);
2966 static inline int acx_s_init_max_probe_response_template(acx_device_t * adev)
2968 return acx_s_init_max_template_generic(adev,
2969 sizeof(acx_template_proberesp_t),
2970 ACX1xx_CMD_CONFIG_PROBE_RESPONSE);
2973 static inline int acx_s_init_max_probe_request_template(acx_device_t * adev)
2975 return acx_s_init_max_template_generic(adev,
2976 sizeof(acx_template_probereq_t),
2977 ACX1xx_CMD_CONFIG_PROBE_REQUEST);
2980 /***********************************************************************
2981 ** acx_s_set_tim_template
2983 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
2984 ** by calling this function
2985 ** (it can be done by irq handler on each DTIM irq or by timer...)
2987 [802.11 7.3.2.6] TIM information element:
2988 - 1 EID
2989 - 1 Length
2990 1 1 DTIM Count
2991 indicates how many beacons (including this) appear before next DTIM
2992 (0=this one is a DTIM)
2993 2 1 DTIM Period
2994 number of beacons between successive DTIMs
2995 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
2996 3 1 Bitmap Control
2997 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
2998 set to 1 in TIM elements with a value of 0 in the DTIM Count field
2999 when one or more broadcast or multicast frames are buffered at the AP.
3000 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
3001 4 n Partial Virtual Bitmap
3002 Visible part of traffic-indication bitmap.
3003 Full bitmap consists of 2008 bits (251 octets) such that bit number N
3004 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
3005 in octet number N/8 where the low-order bit of each octet is bit0,
3006 and the high order bit is bit7.
3007 Each set bit in virtual bitmap corresponds to traffic buffered by AP
3008 for a specific station (with corresponding AID?).
3009 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
3010 Bitmap Offset is a number of skipped zero octets (see above).
3011 'Missing' octets at the tail are also assumed to be zero.
3012 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
3013 This means that traffic-indication bitmap is:
3014 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
3015 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
3017 static int acx_s_set_tim_template(acx_device_t * adev)
3019 /* For now, configure smallish test bitmap, all zero ("no pending data") */
3020 enum { bitmap_size = 5 };
3022 acx_template_tim_t t;
3023 int result;
3025 FN_ENTER;
3027 memset(&t, 0, sizeof(t));
3028 t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
3029 t.tim_eid = WLAN_EID_TIM;
3030 t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
3031 result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
3032 FN_EXIT1(result);
3033 return result;
3039 #if POWER_SAVE_80211
3040 /***********************************************************************
3041 ** acx_s_set_null_data_template
3043 static int acx_s_set_null_data_template(acx_device_t * adev)
3045 struct acx_template_nullframe b;
3046 int result;
3048 FN_ENTER;
3050 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
3052 b.size = cpu_to_le16(sizeof(b) - 2);
3053 b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
3054 b.hdr.dur = 0;
3055 MAC_BCAST(b.hdr.a1);
3056 MAC_COPY(b.hdr.a2, adev->dev_addr);
3057 MAC_COPY(b.hdr.a3, adev->bssid);
3058 b.hdr.seq = 0;
3060 result =
3061 acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
3063 FN_EXIT1(result);
3064 return result;
3066 #endif
3073 /***********************************************************************
3074 ** acx_s_init_packet_templates()
3076 ** NOTE: order is very important here, to have a correct memory layout!
3077 ** init templates: max Probe Request (station mode), max NULL data,
3078 ** max Beacon, max TIM, max Probe Response.
3080 static int acx_s_init_packet_templates(acx_device_t * adev)
3082 acx_ie_memmap_t mm; /* ACX100 only */
3083 int result = NOT_OK;
3085 FN_ENTER;
3087 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_INIT,
3088 "initializing max packet templates\n");
3090 if (OK != acx_s_init_max_probe_request_template(adev))
3091 goto failed;
3093 if (OK != acx_s_init_max_null_data_template(adev))
3094 goto failed;
3096 if (OK != acx_s_init_max_beacon_template(adev))
3097 goto failed;
3099 if (OK != acx_s_init_max_tim_template(adev))
3100 goto failed;
3102 if (OK != acx_s_init_max_probe_response_template(adev))
3103 goto failed;
3105 if (IS_ACX111(adev)) {
3106 /* ACX111 doesn't need the memory map magic below,
3107 * and the other templates will be set later (acx_start) */
3108 result = OK;
3109 goto success;
3112 /* ACX100 will have its TIM template set,
3113 * and we also need to update the memory map */
3115 if (OK != acx_s_set_tim_template(adev))
3116 goto failed_acx100;
3118 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
3119 "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
3121 if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3122 goto failed_acx100;
3124 mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
3125 if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
3126 goto failed_acx100;
3128 result = OK;
3129 goto success;
3131 failed_acx100:
3132 acx_log(LOG_DEBUG, L_REALLYVERBOSE | L_INIT,
3133 /* "cb=0x%X\n" */
3134 "ACXMemoryMap:\n"
3135 ".CodeStart=0x%X\n"
3136 ".CodeEnd=0x%X\n"
3137 ".WEPCacheStart=0x%X\n"
3138 ".WEPCacheEnd=0x%X\n"
3139 ".PacketTemplateStart=0x%X\n" ".PacketTemplateEnd=0x%X\n",
3140 /* len, */
3141 le32_to_cpu(mm.CodeStart),
3142 le32_to_cpu(mm.CodeEnd),
3143 le32_to_cpu(mm.WEPCacheStart),
3144 le32_to_cpu(mm.WEPCacheEnd),
3145 le32_to_cpu(mm.PacketTemplateStart),
3146 le32_to_cpu(mm.PacketTemplateEnd));
3148 failed:
3149 acx_log(LOG_WARNING, L_ANY, "%s: %s() FAILED\n",
3150 wiphy_name(adev->ieee->wiphy), __func__);
3152 success:
3153 FN_EXIT1(result);
3154 return result;
3159 /***********************************************************************
3160 ** acx_s_init_mac
3162 int acx_s_init_mac(acx_device_t * adev)
3164 int result = NOT_OK;
3166 FN_ENTER;
3168 if (IS_ACX111(adev)) {
3169 adev->ie_len = acx111_ie_len;
3170 adev->ie_len_dot11 = acx111_ie_len_dot11;
3171 } else {
3172 adev->ie_len = acx100_ie_len;
3173 adev->ie_len_dot11 = acx100_ie_len_dot11;
3176 if (IS_PCI(adev)) {
3177 adev->memblocksize = 256; /* 256 is default */
3178 /* try to load radio for both ACX100 and ACX111, since both
3179 * chips have at least some firmware versions making use of an
3180 * external radio module */
3181 acxpci_s_upload_radio(adev);
3182 } else {
3183 adev->memblocksize = 128;
3186 if (IS_ACX111(adev)) {
3187 /* for ACX111, the order is different from ACX100
3188 1. init packet templates
3189 2. create station context and create dma regions
3190 3. init wep default keys
3192 if (OK != acx_s_init_packet_templates(adev))
3193 goto fail;
3194 if (OK != acx111_s_create_dma_regions(adev)) {
3195 acx_log(LOG_WARNING, L_ANY,
3196 "%s: acx111_create_dma_regions FAILED\n",
3197 wiphy_name(adev->ieee->wiphy));
3198 goto fail;
3200 } else {
3201 if (OK != acx100_s_init_wep(adev))
3202 goto fail;
3203 if (OK != acx_s_init_packet_templates(adev))
3204 goto fail;
3205 if (OK != acx100_s_create_dma_regions(adev)) {
3206 acx_log(LOG_WARNING, L_ANY,
3207 "%s: acx100_create_dma_regions FAILED\n",
3208 wiphy_name(adev->ieee->wiphy));
3209 goto fail;
3213 SET_IEEE80211_PERM_ADDR(adev->ieee, adev->dev_addr);
3214 result = OK;
3216 fail:
3217 if (result)
3218 acx_log(LOG_WARNING, L_ANY, "init_mac() FAILED\n");
3219 FN_EXIT1(result);
3220 return result;
3225 #if POWER_SAVE_80211
3226 static void acx_s_update_80211_powersave_mode(acx_device_t * adev)
3228 /* merge both structs in a union to be able to have common code */
3229 union {
3230 acx111_ie_powersave_t acx111;
3231 acx100_ie_powersave_t acx100;
3232 } pm;
3234 /* change 802.11 power save mode settings */
3235 acx_log(LOG_DEBUG, L_INIT, "updating 802.11 power save mode settings: "
3236 "wakeup_cfg 0x%02X, listen interval %u, "
3237 "options 0x%02X, hangover period %u, "
3238 "enhanced_ps_transition_time %u\n",
3239 adev->ps_wakeup_cfg, adev->ps_listen_interval,
3240 adev->ps_options, adev->ps_hangover_period,
3241 adev->ps_enhanced_transition_time);
3242 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3243 acx_log(LOG_DEBUG, L_INIT, "Previous PS mode settings: "
3244 "wakeup_cfg 0x%02X, "
3245 "listen interval %u, options 0x%02X, "
3246 "hangover period %u, "
3247 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
3248 pm.acx111.wakeup_cfg,
3249 pm.acx111.listen_interval,
3250 pm.acx111.options,
3251 pm.acx111.hangover_period,
3252 IS_ACX111(adev) ?
3253 pm.acx111.enhanced_ps_transition_time
3254 : pm.acx100.enhanced_ps_transition_time,
3255 IS_ACX111(adev) ? pm.acx111.beacon_rx_time : (u32) - 1);
3256 pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
3257 pm.acx111.listen_interval = adev->ps_listen_interval;
3258 pm.acx111.options = adev->ps_options;
3259 pm.acx111.hangover_period = adev->ps_hangover_period;
3260 if (IS_ACX111(adev)) {
3261 pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
3262 pm.acx111.enhanced_ps_transition_time =
3263 cpu_to_le32(adev->ps_enhanced_transition_time);
3264 } else {
3265 pm.acx100.enhanced_ps_transition_time =
3266 cpu_to_le16(adev->ps_enhanced_transition_time);
3268 acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT);
3269 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3270 acx_log(LOG_DEBUG, L_INIT, "wakeup_cfg: 0x%02X\n",
3271 pm.acx111.wakeup_cfg);
3272 acx_s_mwait(40);
3273 acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
3274 acx_log(LOG_DEBUG, L_INIT, "wakeup_cfg: 0x%02X\n",
3275 pm.acx111.wakeup_cfg);
3276 acx_log(LOG_DEBUG, L_INIT, "power save mode change %s\n",
3277 (pm.acx111.wakeup_cfg & PS_CFG_PENDING) ?
3278 "FAILED" : "was successful");
3279 /* FIXME: maybe verify via PS_CFG_PENDING bit here
3280 * that power save mode change was successful. */
3281 /* FIXME: we shouldn't trigger a scan immediately after
3282 * fiddling with power save mode (since the firmware is sending
3283 * a NULL frame then). */
3285 #endif
3288 /***********************************************************************
3289 ** acx_s_update_card_settings
3291 ** Applies accumulated changes in various adev->xxxx members
3292 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
3293 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
3295 void acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
3297 unsigned mask;
3299 unsigned int i;
3301 for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
3302 if (acx_reg_domain_ids[i] == adev->reg_dom_id)
3303 break;
3305 if (sizeof(acx_reg_domain_ids) == i) {
3306 acx_log(LOG_WARNING, L_INIT,
3307 "Invalid or unsupported regulatory domain"
3308 " 0x%02X specified, falling back to FCC (USA)!"
3309 " Please report if this sounds fishy!\n",
3310 adev->reg_dom_id);
3311 i = 0;
3312 adev->reg_dom_id = acx_reg_domain_ids[i];
3314 /* since there was a mismatch, we need to force updating */
3315 do_set = 1;
3318 if (do_set) {
3319 acx_ie_generic_t dom;
3320 dom.m.bytes[0] = adev->reg_dom_id;
3321 acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3324 adev->reg_dom_chanmask = reg_domain_channel_masks[i];
3326 mask = (1 << (adev->channel - 1));
3329 * Check our channels wrt the current regulatory domain
3331 if (adev->reg_dom_chanmask & mask)
3332 return;
3335 * Hmm nope, need to adjust channels!
3338 mask = 1;
3339 for (i = 1; i <= 14; i++) {
3340 if (!(adev->reg_dom_chanmask & mask)) {
3341 mask <<= 1;
3342 continue;
3344 acx_log(LOG_INFO, L_ANY, "%s: adjusting selected channel "
3345 "from %d to %d due to new regulatory domain\n",
3346 wiphy_name(adev->ieee->wiphy), adev->channel, i);
3347 adev->channel = i;
3348 break;
3352 static void acx111_s_sens_radio_16_17(acx_device_t * adev)
3354 u32 feature1, feature2;
3356 if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
3357 acx_log(LOG_WARNING, L_ANY,
3358 "%s: invalid sensitivity setting (1..3), "
3359 "setting to 1\n", wiphy_name(adev->ieee->wiphy));
3360 adev->sensitivity = 1;
3362 acx111_s_get_feature_config(adev, &feature1, &feature2);
3363 CLEAR_BIT(feature1, FEATURE1_LOW_RX | FEATURE1_EXTRA_LOW_RX);
3364 if (adev->sensitivity > 1)
3365 SET_BIT(feature1, FEATURE1_LOW_RX);
3366 if (adev->sensitivity > 2)
3367 SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
3368 acx111_s_feature_set(adev, feature1, feature2);
3372 void acx_s_update_card_settings(acx_device_t *adev)
3374 unsigned long flags;
3375 unsigned int start_scan = 0;
3376 int i;
3378 FN_ENTER;
3380 acx_log(LOG_DEBUG, L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
3381 adev->get_mask, adev->set_mask);
3383 /* Track dependencies betweed various settings */
3385 if (adev->set_mask & (GETSET_MODE | GETSET_RESCAN | GETSET_WEP)) {
3386 acx_log(LOG_DEBUG, L_INIT,
3387 "important setting has been changed. "
3388 "Need to update packet templates, too\n");
3389 SET_BIT(adev->set_mask, SET_TEMPLATES);
3391 if (adev->set_mask & GETSET_CHANNEL) {
3392 /* This will actually tune RX/TX to the channel */
3393 SET_BIT(adev->set_mask, GETSET_RX | GETSET_TX);
3394 switch (adev->mode) {
3395 case ACX_MODE_0_ADHOC:
3396 case ACX_MODE_3_AP:
3397 /* Beacons contain channel# - update them */
3398 SET_BIT(adev->set_mask, SET_TEMPLATES);
3401 switch (adev->mode) {
3402 case ACX_MODE_0_ADHOC:
3403 case ACX_MODE_2_STA:
3404 start_scan = 1;
3408 /* Apply settings */
3411 if (adev->get_mask & GETSET_STATION_ID) {
3412 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3413 const u8 *paddr;
3415 acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3416 paddr = &stationID[4];
3417 // memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
3418 for (i = 0; i < ETH_ALEN; i++) {
3419 /* we copy the MAC address (reversed in
3420 * the card) to the netdevice's MAC
3421 * address, and on ifup it will be
3422 * copied into iwadev->dev_addr */
3423 adev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
3425 SET_IEEE80211_PERM_ADDR(adev->ieee,adev->dev_addr);
3426 CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
3429 if (adev->get_mask & GETSET_SENSITIVITY) {
3430 if ((RADIO_RFMD_11 == adev->radio_type)
3431 || (RADIO_MAXIM_0D == adev->radio_type)
3432 || (RADIO_RALINK_15 == adev->radio_type)) {
3433 acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
3434 } else {
3435 acx_log(LOG_WARNING, L_INIT,
3436 "don't know how to get sensitivity "
3437 "for radio type 0x%02X\n", adev->radio_type);
3438 adev->sensitivity = 0;
3440 acx_log(LOG_DEBUG, L_INIT, "got sensitivity value %u\n",
3441 adev->sensitivity);
3443 CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
3446 if (adev->get_mask & GETSET_ANTENNA) {
3447 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3449 memset(antenna, 0, sizeof(antenna));
3450 acx_s_interrogate(adev, antenna,
3451 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3452 adev->antenna = antenna[4];
3453 acx_log(LOG_INFO, L_INIT, "got antenna value 0x%02X\n",
3454 adev->antenna);
3455 CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
3458 if (adev->get_mask & GETSET_ED_THRESH) {
3459 if (IS_ACX100(adev)) {
3460 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3462 memset(ed_threshold, 0, sizeof(ed_threshold));
3463 acx_s_interrogate(adev, ed_threshold,
3464 ACX100_IE_DOT11_ED_THRESHOLD);
3465 adev->ed_threshold = ed_threshold[4];
3466 } else {
3467 acx_log(LOG_WARNING, L_INIT,
3468 "acx111 doesn't support ED\n");
3469 adev->ed_threshold = 0;
3471 acx_log(LOG_INFO, L_INIT,
3472 "got Energy Detect (ED) threshold %u\n",
3473 adev->ed_threshold);
3474 CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
3477 if (adev->get_mask & GETSET_CCA) {
3478 if (IS_ACX100(adev)) {
3479 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3481 memset(cca, 0, sizeof(adev->cca));
3482 acx_s_interrogate(adev, cca,
3483 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3484 adev->cca = cca[4];
3485 } else {
3486 acx_log(LOG_WARNING, L_INIT,
3487 "acx111 doesn't support CCA\n");
3488 adev->cca = 0;
3490 acx_log(LOG_INFO, L_INIT,
3491 "got Channel Clear Assessment (CCA) value %u\n",
3492 adev->cca);
3493 CLEAR_BIT(adev->get_mask, GETSET_CCA);
3496 if (adev->get_mask & GETSET_REG_DOMAIN) {
3497 acx_ie_generic_t dom;
3499 acx_s_interrogate(adev, &dom,
3500 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
3501 adev->reg_dom_id = dom.m.bytes[0];
3502 acx_s_set_sane_reg_domain(adev, 0);
3503 acx_log(LOG_INFO, L_INIT,
3504 "got regulatory domain 0x%02X\n", adev->reg_dom_id);
3505 CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
3508 if (adev->set_mask & GETSET_STATION_ID) {
3509 u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
3510 u8 *paddr;
3512 paddr = &stationID[4];
3513 MAC_COPY(adev->dev_addr, adev->ieee->wiphy->perm_addr);
3514 for (i = 0; i < ETH_ALEN; i++) {
3515 /* copy the MAC address we obtained when we noticed
3516 * that the ethernet iface's MAC changed
3517 * to the card (reversed in
3518 * the card!) */
3519 paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
3521 acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
3522 CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
3525 if (adev->set_mask & SET_STA_LIST) {
3526 CLEAR_BIT(adev->set_mask, SET_STA_LIST);
3528 if (adev->set_mask & SET_RATE_FALLBACK) {
3529 u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
3531 /* configure to not do fallbacks when not in auto rate mode */
3532 rate[4] =
3533 (adev->
3534 rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
3535 acx_log(LOG_DEBUG, L_INIT,
3536 "updating Tx fallback to %u retries\n", rate[4]);
3537 acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK);
3538 CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
3540 if (adev->set_mask & GETSET_TXPOWER) {
3541 acx_log(LOG_DEBUG, L_INIT, "updating transmit power: %u dBm\n",
3542 adev->tx_level_dbm);
3543 acx_s_set_tx_level(adev, adev->tx_level_dbm);
3544 CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
3547 if (adev->set_mask & GETSET_SENSITIVITY) {
3548 acx_log(LOG_DEBUG, L_INIT, "updating sensitivity value: %u\n",
3549 adev->sensitivity);
3550 switch (adev->radio_type) {
3551 case RADIO_RFMD_11:
3552 case RADIO_MAXIM_0D:
3553 case RADIO_RALINK_15:
3554 acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
3555 break;
3556 case RADIO_RADIA_16:
3557 case RADIO_UNKNOWN_17:
3558 acx111_s_sens_radio_16_17(adev);
3559 break;
3560 default:
3561 acx_log(LOG_WARNING, L_INIT,
3562 "don't know how to modify sensitivity "
3563 "for radio type 0x%02X\n", adev->radio_type);
3565 CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
3568 if (adev->set_mask & GETSET_ANTENNA) {
3569 /* antenna */
3570 u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
3572 memset(antenna, 0, sizeof(antenna));
3573 antenna[4] = adev->antenna;
3574 acx_log(LOG_DEBUG, L_INIT, "updating antenna value: 0x%02X\n",
3575 adev->antenna);
3576 acx_s_configure(adev, &antenna,
3577 ACX1xx_IE_DOT11_CURRENT_ANTENNA);
3578 CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
3581 if (adev->set_mask & GETSET_ED_THRESH) {
3582 /* ed_threshold */
3583 acx_log(LOG_INFO, L_INIT,
3584 "updating Energy Detect (ED) threshold: %u\n",
3585 adev->ed_threshold);
3586 if (IS_ACX100(adev)) {
3587 u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
3589 memset(ed_threshold, 0, sizeof(ed_threshold));
3590 ed_threshold[4] = adev->ed_threshold;
3591 acx_s_configure(adev, &ed_threshold,
3592 ACX100_IE_DOT11_ED_THRESHOLD);
3593 } else
3594 acx_log(LOG_WARNING, L_INIT,
3595 "acx111 doesn't support ED!\n");
3596 CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
3599 if (adev->set_mask & GETSET_CCA) {
3600 /* CCA value */
3601 acx_log(LOG_DEBUG, L_INIT,
3602 "updating Channel Clear Assessment (CCA) value: "
3603 "0x%02X\n", adev->cca);
3604 if (IS_ACX100(adev)) {
3605 u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
3607 memset(cca, 0, sizeof(cca));
3608 cca[4] = adev->cca;
3609 acx_s_configure(adev, &cca,
3610 ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
3611 } else
3612 acx_log(LOG_WARNING, L_INIT,
3613 "acx111 doesn't support CCA!\n");
3614 CLEAR_BIT(adev->set_mask, GETSET_CCA);
3617 if (adev->set_mask & GETSET_LED_POWER) {
3618 /* Enable Tx */
3619 acx_log(LOG_INFO, L_INIT,
3620 "updating power LED status: %u\n", adev->led_power);
3622 acx_lock(adev, flags); /* acxpci_l_power_led expects that the lock is already taken! */
3623 if (IS_PCI(adev))
3624 acxpci_l_power_led(adev, adev->led_power);
3625 CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
3626 acx_unlock(adev, flags);
3629 if (adev->set_mask & GETSET_POWER_80211) {
3630 #if POWER_SAVE_80211
3631 acx_s_update_80211_powersave_mode(adev);
3632 #endif
3633 CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
3636 if (adev->set_mask & GETSET_CHANNEL) {
3637 /* channel */
3638 acx_log(LOG_INFO, L_INIT, "updating channel to: %u\n",
3639 adev->channel);
3640 CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
3643 if (adev->set_mask & GETSET_TX) {
3644 /* set Tx */
3645 acx_log(LOG_INFO, L_INIT, "updating: %s Tx\n",
3646 adev->tx_disabled ? "disable" : "enable");
3647 if (adev->tx_disabled)
3648 acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
3649 else {
3650 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3651 &adev->channel, 1);
3652 FIXME();
3653 /* This needs to be keyed on WEP? */
3654 /* acx111_s_feature_on(adev, 0,
3655 FEATURE2_NO_TXCRYPT |
3656 FEATURE2_SNIFFER); */
3657 acx_wake_queue(adev->ieee, NULL);
3659 CLEAR_BIT(adev->set_mask, GETSET_TX);
3662 if (adev->set_mask & GETSET_RX) {
3663 /* Enable Rx */
3664 acx_log(LOG_INFO, L_INIT,
3665 "updating: enable Rx on channel: %u\n", adev->channel);
3666 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
3667 CLEAR_BIT(adev->set_mask, GETSET_RX);
3670 if (adev->set_mask & GETSET_RETRY) {
3671 u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
3672 u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
3674 acx_log(LOG_INFO, L_INIT,
3675 "updating short retry limit: %u, "
3676 "long retry limit: %u\n",
3677 adev->short_retry, adev->long_retry);
3678 short_retry[0x4] = adev->short_retry;
3679 long_retry[0x4] = adev->long_retry;
3680 acx_s_configure(adev, &short_retry,
3681 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
3682 acx_s_configure(adev, &long_retry,
3683 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
3684 CLEAR_BIT(adev->set_mask, GETSET_RETRY);
3687 if (adev->set_mask & SET_MSDU_LIFETIME) {
3688 u8 xmt_msdu_lifetime[4 +
3689 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
3691 acx_log(LOG_DEBUG, L_INIT, "updating tx MSDU lifetime: %u\n",
3692 adev->msdu_lifetime);
3693 *(u32 *) & xmt_msdu_lifetime[4] =
3694 cpu_to_le32((u32) adev->msdu_lifetime);
3695 acx_s_configure(adev, &xmt_msdu_lifetime,
3696 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
3697 CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
3700 if (adev->set_mask & GETSET_REG_DOMAIN) {
3701 acx_log(LOG_INFO, L_INIT,
3702 "updating regulatory domain: 0x%02X\n",
3703 adev->reg_dom_id);
3704 acx_s_set_sane_reg_domain(adev, 1);
3705 CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
3707 if (adev->set_mask & GETSET_MODE ) {
3708 acx111_s_feature_on(adev, 0,
3709 FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3710 switch (adev->mode) {
3711 case ACX_MODE_3_AP:
3712 adev->aid = 0;
3713 //acx111_s_feature_off(adev, 0,
3714 // FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3715 MAC_COPY(adev->bssid, adev->dev_addr);
3716 acx_s_cmd_join_bssid(adev, adev->dev_addr);
3717 break;
3718 case ACX_MODE_MONITOR:
3719 SET_BIT(adev->set_mask, SET_RXCONFIG | SET_WEP_OPTIONS);
3720 break;
3721 case ACX_MODE_0_ADHOC:
3722 case ACX_MODE_2_STA:
3723 acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT | FEATURE2_SNIFFER);
3724 break;
3725 default:
3726 break;
3728 CLEAR_BIT(adev->set_mask, GETSET_MODE);
3730 if (adev->set_mask & SET_TEMPLATES) {
3731 switch (adev->mode)
3733 case ACX_MODE_3_AP:
3734 acx_s_set_tim_template(adev);
3735 break;
3736 default:
3737 break;
3739 if (adev->beacon_cache)
3741 acx_s_set_beacon_template(adev, adev->beacon_cache);
3742 dev_kfree_skb(adev->beacon_cache);
3743 adev->beacon_cache = NULL;
3745 CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
3748 if (adev->set_mask & SET_RXCONFIG) {
3749 acx_s_initialize_rx_config(adev);
3750 CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
3753 if (adev->set_mask & GETSET_RESCAN) {
3754 /* switch (adev->mode) {
3755 case ACX_MODE_0_ADHOC:
3756 case ACX_MODE_2_STA:
3757 start_scan = 1;
3758 break;
3760 */ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
3763 if (adev->set_mask & GETSET_WEP) {
3764 /* encode */
3766 ie_dot11WEPDefaultKeyID_t dkey;
3767 #ifdef DEBUG_WEP
3768 struct {
3769 u16 type;
3770 u16 len;
3771 u8 val;
3772 } __attribute__ ((packed)) keyindic;
3773 #endif
3774 acx_log(LOG_DEBUG, L_INIT, "updating WEP key settings\n");
3776 acx_s_set_wepkey(adev);
3777 if (adev->wep_enabled) {
3778 dkey.KeyID = adev->wep_current_index;
3779 acx_log(LOG_DEBUG, L_INIT,
3780 "setting WEP key %u as default\n",
3781 dkey.KeyID);
3782 acx_s_configure(adev, &dkey,
3783 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
3784 #ifdef DEBUG_WEP
3785 keyindic.val = 3;
3786 acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
3787 #endif
3790 // start_scan = 1;
3791 CLEAR_BIT(adev->set_mask, GETSET_WEP);
3794 if (adev->set_mask & SET_WEP_OPTIONS) {
3795 acx100_ie_wep_options_t options;
3797 if (IS_ACX111(adev)) {
3798 acx_log(LOG_DEBUG, L_REALLYVERBOSE,
3799 "setting WEP Options for acx111 "
3800 "is not supported\n");
3801 } else {
3802 acx_log(LOG_DEBUG, L_INIT, "setting WEP Options\n");
3804 /* let's choose maximum setting: 4 default keys,
3805 * plus 10 other keys: */
3806 options.NumKeys =
3807 cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
3808 /* don't decrypt default key only,
3809 * don't override decryption: */
3810 options.WEPOption = 0;
3811 if (adev->mode == ACX_MODE_3_AP) {
3812 /* don't decrypt default key only,
3813 * override decryption mechanism: */
3814 options.WEPOption = 2;
3817 acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
3819 CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
3823 /* debug, rate, and nick don't need any handling */
3824 /* what about sniffing mode?? */
3826 /* log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
3827 adev->get_mask, adev->set_mask);
3829 /* end: */
3830 FN_EXIT0;
3833 #if 0
3834 /***********************************************************************
3835 ** acx_e_after_interrupt_task
3837 static int acx_s_recalib_radio(acx_device_t * adev)
3839 if (IS_ACX111(adev)) {
3840 acx111_cmd_radiocalib_t cal;
3842 /* automatic recalibration, choose all methods: */
3843 cal.methods = cpu_to_le32(0x8000000f);
3844 /* automatic recalibration every 60 seconds (value in TUs)
3845 * I wonder what the firmware default here is? */
3846 cal.interval = cpu_to_le32(58594);
3847 return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
3848 &cal, sizeof(cal),
3849 CMD_TIMEOUT_MS(100));
3850 } else {
3851 /* On ACX100, we need to recalibrate the radio
3852 * by issuing a GETSET_TX|GETSET_RX */
3853 if ( /* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
3854 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
3855 (OK ==
3856 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX,
3857 &adev->channel, 1))
3858 && (OK ==
3859 acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX,
3860 &adev->channel, 1)))
3861 return OK;
3862 return NOT_OK;
3865 #endif // if 0
3866 #if 0
3867 static void acx_s_after_interrupt_recalib(acx_device_t * adev)
3869 int res;
3871 /* this helps with ACX100 at least;
3872 * hopefully ACX111 also does a
3873 * recalibration here */
3875 /* clear flag beforehand, since we want to make sure
3876 * it's cleared; then only set it again on specific circumstances */
3877 CLEAR_BIT(adev->after_interrupt_jobs, ACX_TASKLET_CMD_RADIO_RECALIB);
3879 /* better wait a bit between recalibrations to
3880 * prevent overheating due to torturing the card
3881 * into working too long despite high temperature
3882 * (just a safety measure) */
3883 if (adev->recalib_time_last_success
3884 && time_before(jiffies, adev->recalib_time_last_success
3885 + RECALIB_PAUSE * 60 * HZ)) {
3886 if (adev->recalib_msg_ratelimit <= 4) {
3887 printk("%s: less than " STRING(RECALIB_PAUSE)
3888 " minutes since last radio recalibration, "
3889 "not recalibrating (maybe card is too hot?)\n",
3890 wiphy_name(adev->ieee->wiphy));
3891 adev->recalib_msg_ratelimit++;
3892 if (adev->recalib_msg_ratelimit == 5)
3893 printk("disabling above message until next recalib\n");
3895 return;
3898 adev->recalib_msg_ratelimit = 0;
3900 /* note that commands sometimes fail (card busy),
3901 * so only clear flag if we were fully successful */
3902 res = acx_s_recalib_radio(adev);
3903 if (res == OK) {
3904 printk("%s: successfully recalibrated radio\n",
3905 wiphy_name(adev->ieee->wiphy));
3906 adev->recalib_time_last_success = jiffies;
3907 adev->recalib_failure_count = 0;
3908 } else {
3909 /* failed: resubmit, but only limited
3910 * amount of times within some time range
3911 * to prevent endless loop */
3913 adev->recalib_time_last_success = 0; /* we failed */
3915 /* if some time passed between last
3916 * attempts, then reset failure retry counter
3917 * to be able to do next recalib attempt */
3918 if (time_after
3919 (jiffies, adev->recalib_time_last_attempt + 5 * HZ))
3920 adev->recalib_failure_count = 0;
3922 if (adev->recalib_failure_count < 5) {
3923 /* increment inside only, for speedup of outside path */
3924 adev->recalib_failure_count++;
3925 adev->recalib_time_last_attempt = jiffies;
3926 acx_schedule_task(adev,
3927 ACX_TASKLET_CMD_RADIO_RECALIB);
3931 #endif // if 0
3933 void acx_e_after_interrupt_task(struct work_struct *work)
3935 acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
3936 unsigned long flags;
3938 FN_ENTER;
3940 acx_lock(adev, flags);
3942 if (!adev->after_interrupt_jobs || !adev->initialized)
3943 goto end; /* no jobs to do */
3945 /* we see lotsa tx errors */
3946 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_RADIO_RECALIB) {
3947 acx_log_ratelimited(LOG_WARNING, L_ANY,
3948 "too many TX errors??\n");
3949 // acx_s_after_interrupt_recalib(adev);
3952 /* a poor interrupt code wanted to do update_card_settings() */
3953 if (adev->after_interrupt_jobs & ACX_TASKLET_UPDATE_CARD_CFG) {
3954 if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
3955 acx_unlock(adev, flags);
3956 acx_s_update_card_settings(adev);
3957 acx_lock(adev, flags);
3959 CLEAR_BIT(adev->after_interrupt_jobs,
3960 ACX_TASKLET_UPDATE_CARD_CFG);
3963 /* 1) we detected that no Scan_Complete IRQ came from fw, or
3964 ** 2) we found too many STAs */
3965 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_STOP_SCAN) {
3966 acx_log(LOG_DEBUG, L_IRQ, "sending a stop scan cmd...\n");
3967 acx_unlock(adev, flags);
3968 acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
3969 acx_lock(adev, flags);
3970 /* HACK: set the IRQ bit, since we won't get a
3971 * scan complete IRQ any more on ACX111 (works on ACX100!),
3972 * since _we_, not a fw, have stopped the scan */
3973 SET_BIT(adev->irq_status, ACX_IRQ_SCAN_COMPLETE);
3974 CLEAR_BIT(adev->after_interrupt_jobs,
3975 ACX_TASKLET_CMD_STOP_SCAN);
3978 /* either fw sent Scan_Complete or we detected that
3979 ** no Scan_Complete IRQ came from fw. Finish scanning,
3980 ** pick join partner if any */
3981 if (adev->after_interrupt_jobs & ACX_TASKLET_COMPLETE_SCAN) {
3982 /* + scan kills current join status - restore it
3983 ** (do we need it for STA?) */
3984 /* + does it happen only with active scans?
3985 ** active and passive scans? ALL scans including
3986 ** background one? */
3987 /* + was not verified that everything is restored
3988 ** (but at least we start to emit beacons again) */
3989 CLEAR_BIT(adev->after_interrupt_jobs,
3990 ACX_TASKLET_COMPLETE_SCAN);
3993 /* STA auth or assoc timed out, start over again */
3995 if (adev->after_interrupt_jobs & ACX_TASKLET_RESTART_SCAN) {
3996 acx_log(LOG_DEBUG, L_IRQ, "sending a start_scan cmd...\n");
3997 CLEAR_BIT(adev->after_interrupt_jobs,
3998 ACX_TASKLET_RESTART_SCAN);
4001 /* whee, we got positive assoc response! 8) */
4002 if (adev->after_interrupt_jobs & ACX_TASKLET_CMD_ASSOCIATE) {
4003 CLEAR_BIT(adev->after_interrupt_jobs,
4004 ACX_TASKLET_CMD_ASSOCIATE);
4006 end:
4007 if(adev->after_interrupt_jobs)
4009 acx_log(LOG_DEBUG, L_ANY, "Jobs still to be run: %x\n",
4010 adev->after_interrupt_jobs);
4011 adev->after_interrupt_jobs = 0;
4013 acx_unlock(adev, flags);
4014 // acx_sem_unlock(adev);
4015 FN_EXIT0;
4019 /***********************************************************************
4020 ** acx_schedule_task
4022 ** Schedule the call of the after_interrupt method after leaving
4023 ** the interrupt context.
4025 void acx_schedule_task(acx_device_t * adev, unsigned int set_flag)
4027 if (!adev->after_interrupt_jobs)
4029 SET_BIT(adev->after_interrupt_jobs, set_flag);
4030 schedule_work(&adev->after_interrupt_task);
4035 /***********************************************************************
4037 void acx_init_task_scheduler(acx_device_t * adev)
4039 /* configure task scheduler */
4040 INIT_WORK(&adev->after_interrupt_task, acx_interrupt_tasklet);
4044 /***********************************************************************
4045 ** acx_s_start
4047 void acx_s_start(acx_device_t * adev)
4049 FN_ENTER;
4052 * Ok, now we do everything that can possibly be done with ioctl
4053 * calls to make sure that when it was called before the card
4054 * was up we get the changes asked for
4057 SET_BIT(adev->set_mask, SET_TEMPLATES | SET_STA_LIST | GETSET_WEP
4058 | GETSET_TXPOWER | GETSET_ANTENNA | GETSET_ED_THRESH |
4059 GETSET_CCA | GETSET_REG_DOMAIN | GETSET_MODE | GETSET_CHANNEL |
4060 GETSET_TX | GETSET_RX | GETSET_STATION_ID);
4062 acx_log(LOG_INFO, L_INIT,
4063 "updating initial settings on iface activation\n");
4064 acx_s_update_card_settings(adev);
4066 FN_EXIT0;
4070 /***********************************************************************
4071 ** acx_update_capabilities
4072 *//*
4073 void acx_update_capabilities(acx_device_t * adev)
4075 u16 cap = 0;
4077 switch (adev->mode) {
4078 case ACX_MODE_3_AP:
4079 SET_BIT(cap, WF_MGMT_CAP_ESS);
4080 break;
4081 case ACX_MODE_0_ADHOC:
4082 SET_BIT(cap, WF_MGMT_CAP_IBSS);
4083 break;
4084 */ /* other types of stations do not emit beacons */
4085 /* }
4087 if (adev->wep_restricted) {
4088 SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
4090 if (adev->cfgopt_dot11ShortPreambleOption) {
4091 SET_BIT(cap, WF_MGMT_CAP_SHORT);
4093 if (adev->cfgopt_dot11PBCCOption) {
4094 SET_BIT(cap, WF_MGMT_CAP_PBCC);
4096 if (adev->cfgopt_dot11ChannelAgility) {
4097 SET_BIT(cap, WF_MGMT_CAP_AGILITY);
4099 log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
4100 adev->capabilities, cap);
4101 adev->capabilities = cap;
4105 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4108 static void acx_s_select_opmode(acx_device_t * adev)
4110 int changed = 0;
4111 FN_ENTER;
4113 if (adev->interface.operating) {
4114 switch (adev->interface.type) {
4115 case IEEE80211_IF_TYPE_AP:
4116 if (adev->mode != ACX_MODE_3_AP)
4118 adev->mode = ACX_MODE_3_AP;
4119 changed = 1;
4121 break;
4122 case IEEE80211_IF_TYPE_IBSS:
4123 if (adev->mode != ACX_MODE_0_ADHOC)
4125 adev->mode = ACX_MODE_0_ADHOC;
4126 changed = 1;
4128 break;
4129 case IEEE80211_IF_TYPE_STA:
4130 if (adev->mode != ACX_MODE_2_STA)
4132 adev->mode = ACX_MODE_2_STA;
4133 changed = 1;
4135 break;
4136 case IEEE80211_IF_TYPE_WDS:
4137 default:
4138 if (adev->mode != ACX_MODE_OFF)
4140 adev->mode = ACX_MODE_OFF;
4141 changed = 1;
4143 break;
4145 } else {
4146 if (adev->interface.type == IEEE80211_IF_TYPE_MNTR)
4148 if (adev->mode != ACX_MODE_MONITOR)
4150 adev->mode = ACX_MODE_MONITOR;
4151 changed = 1;
4154 else
4156 if (adev->mode != ACX_MODE_OFF)
4158 adev->mode = ACX_MODE_OFF;
4159 changed = 1;
4163 if (changed)
4165 SET_BIT(adev->set_mask, GETSET_MODE);
4166 acx_s_update_card_settings(adev);
4167 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4170 FN_EXIT0;
4174 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4178 int acx_add_interface(struct ieee80211_hw *ieee,
4179 struct ieee80211_if_init_conf *conf)
4181 acx_device_t *adev = ieee2adev(ieee);
4182 unsigned long flags;
4183 int err = -EOPNOTSUPP;
4185 DECLARE_MAC_BUF(mac);
4187 FN_ENTER;
4188 acx_lock(adev, flags);
4190 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4191 adev->interface.monitor++;
4192 } else {
4193 if (adev->interface.operating)
4194 goto out_unlock;
4195 adev->interface.operating = 1;
4196 adev->interface.mac_addr = conf->mac_addr;
4197 adev->interface.type = conf->type;
4199 // adev->mode = conf->type;
4201 acx_unlock(adev, flags);
4203 if (adev->initialized)
4204 acx_s_select_opmode(adev);
4206 acx_lock(adev, flags);
4208 err = 0;
4210 acx_log(LOG_INFO, L_ANY, "Virtual interface added "
4211 "(type: 0x%08X, ID: %d, MAC: %s)\n",
4212 conf->type,
4213 adev->interface.if_id,
4214 print_mac(mac, conf->mac_addr));
4216 out_unlock:
4217 acx_unlock(adev, flags);
4219 FN_EXIT0;
4220 return err;
4223 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4227 void acx_remove_interface(struct ieee80211_hw *hw,
4228 struct ieee80211_if_init_conf *conf)
4230 acx_device_t *adev = ieee2adev(hw);
4232 DECLARE_MAC_BUF(mac);
4234 FN_ENTER;
4236 acx_sem_lock(adev);
4237 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
4238 adev->interface.monitor--;
4239 // assert(bcm->interface.monitor >= 0);
4240 } else {
4241 adev->interface.operating = 0;
4244 acx_log(LOG_INFO, L_ANY, "Removing interface: %d %d\n",
4245 adev->interface.operating, conf->type);
4246 acx_sem_unlock(adev);
4248 if (adev->initialized)
4249 acx_s_select_opmode(adev);
4250 flush_scheduled_work();
4252 acx_log(LOG_INFO, L_ANY, "Virtual interface removed "
4253 "(type: 0x%08X, ID: %d, MAC: %s)\n",
4254 conf->type, adev->interface.if_id,
4255 print_mac(mac, conf->mac_addr));
4257 FN_EXIT0;
4260 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4264 int acx_net_reset(struct ieee80211_hw *ieee)
4266 acx_device_t *adev = ieee2adev(ieee);
4267 FN_ENTER;
4268 if (IS_PCI(adev))
4269 acxpci_s_reset_dev(adev);
4270 else
4271 TODO();
4273 FN_EXIT0;
4274 return 0;
4278 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4281 int acx_selectchannel(acx_device_t * adev, u8 channel, int freq)
4283 int result;
4285 FN_ENTER;
4287 acx_sem_lock(adev);
4288 adev->rx_status.channel = channel;
4289 adev->rx_status.freq = freq;
4291 adev->channel = channel;
4292 /* hmm, the following code part is strange, but this is how
4293 * it was being done before... */
4294 acx_log(LOG_DEBUG, L_IOCTL, "Changing to channel %d\n", channel);
4295 SET_BIT(adev->set_mask, GETSET_CHANNEL);
4296 result = -EINPROGRESS; /* need to call commit handler */
4298 acx_sem_unlock(adev);
4299 FN_EXIT1(result);
4300 return result;
4304 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4307 int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
4309 acx_device_t *adev = ieee2adev(hw);
4310 unsigned long flags;
4312 FN_ENTER;
4314 acx_lock(adev, flags);
4315 //FIXME();
4316 if (!adev->initialized) {
4317 acx_unlock(adev, flags);
4318 return 0;
4320 if (conf->beacon_int != adev->beacon_interval)
4321 adev->beacon_interval = conf->beacon_int;
4322 if (conf->channel != adev->channel) {
4323 acx_unlock(adev, flags);
4324 acx_selectchannel(adev, conf->channel,conf->freq);
4325 acx_lock(adev, flags);
4326 /* acx_schedule_task(adev,
4327 ACX_TASKLET_UPDATE_CARD_CFG
4328 */ /*+ ACX_TASKLET_RESTART_SCAN */ /*);*/
4331 if (conf->short_slot_time != adev->short_slot) {
4332 // assert(phy->type == BCM43xx_PHYTYPE_G);
4333 if (conf->short_slot_time)
4334 acx_short_slot_timing_enable(adev);
4335 else
4336 acx_short_slot_timing_disable(adev);
4337 acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4340 adev->tx_disabled = !conf->radio_enabled;
4341 /* if (conf->power_level != 0){
4342 adev->tx_level_dbm = conf->power_level;
4343 acx_s_set_tx_level(adev, adev->tx_level_dbm);
4344 SET_BIT(adev->set_mask,GETSET_TXPOWER);
4345 //acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4348 //FIXME: This does not seem to wake up:
4349 #if 0
4350 if (conf->power_level == 0) {
4351 if (radio->enabled)
4352 bcm43xx_radio_turn_off(bcm);
4353 } else {
4354 if (!radio->enabled)
4355 bcm43xx_radio_turn_on(bcm);
4357 #endif
4359 //TODO: phymode
4360 //TODO: antennas
4361 if (adev->set_mask > 0) {
4362 acx_unlock(adev, flags);
4363 acx_s_update_card_settings(adev);
4364 acx_lock(adev, flags);
4366 acx_unlock(adev, flags);
4368 FN_EXIT0;
4369 return 0;
4373 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4377 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
4378 extern int acx_config_interface(struct ieee80211_hw* ieee,
4379 struct ieee80211_vif *vif,
4380 struct ieee80211_if_conf *conf)
4382 acx_device_t *adev = ieee2adev(ieee);
4383 unsigned long flags;
4384 int err = -ENODEV;
4385 FN_ENTER;
4386 if (!adev->interface.operating)
4387 goto err_out;
4389 if (adev->initialized)
4390 acx_s_select_opmode(adev);
4392 acx_lock(adev, flags);
4394 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4395 && (adev->vif == vif)) {
4396 if (conf->bssid)
4398 adev->interface.bssid = conf->bssid;
4399 MAC_COPY(adev->bssid,conf->bssid);
4402 if ((conf->type == IEEE80211_IF_TYPE_AP)
4403 && (adev->vif == vif)) {
4404 #else
4405 int acx_config_interface(struct ieee80211_hw* ieee, int if_id,
4406 struct ieee80211_if_conf *conf)
4408 acx_device_t *adev = ieee2adev(ieee);
4409 unsigned long flags;
4410 int err = -ENODEV;
4411 FN_ENTER;
4412 if (!adev->interface.operating)
4413 goto err_out;
4415 if (adev->initialized)
4416 acx_s_select_opmode(adev);
4418 acx_lock(adev, flags);
4420 if ((conf->type != IEEE80211_IF_TYPE_MNTR)
4421 && (adev->interface.if_id == if_id)) {
4422 if (conf->bssid)
4424 adev->interface.bssid = conf->bssid;
4425 MAC_COPY(adev->bssid,conf->bssid);
4428 if ((conf->type == IEEE80211_IF_TYPE_AP)
4429 && (adev->interface.if_id == if_id)) {
4430 #endif
4432 if ((conf->ssid_len > 0) && conf->ssid)
4434 adev->essid_len = conf->ssid_len;
4435 memcpy(adev->essid, conf->ssid, conf->ssid_len);
4436 SET_BIT(adev->set_mask, SET_TEMPLATES);
4439 if (conf->beacon != 0)
4441 adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
4442 adev->beacon_cache = conf->beacon;
4443 SET_BIT(adev->set_mask, SET_TEMPLATES);
4446 acx_unlock(adev, flags);
4448 if (adev->set_mask != 0)
4449 acx_s_update_card_settings(adev);
4450 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4451 err = 0;
4452 err_out:
4453 FN_EXIT1(err);
4454 return err;
4458 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4462 int acx_net_get_tx_stats(struct ieee80211_hw *hw,
4463 struct ieee80211_tx_queue_stats *stats)
4465 // acx_device_t *adev = ndev2adev(net_dev);
4466 struct ieee80211_tx_queue_stats_data *data;
4467 int err = -ENODEV;
4469 FN_ENTER;
4471 // acx_lock(adev, flags);
4472 data = &(stats->data[0]);
4473 data->len = 0;
4474 data->limit = TX_CNT;
4475 data->count = 0;
4476 // acx_unlock(adev, flags);
4478 FN_EXIT0;
4479 return err;
4482 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4486 int acx_net_conf_tx(struct ieee80211_hw *hw,
4487 int queue, const struct ieee80211_tx_queue_params *params)
4489 FN_ENTER;
4490 // TODO();
4491 FN_EXIT0;
4492 return 0;
4495 static void keymac_write(acx_device_t * adev, u16 index, const u32 * addr)
4497 /* for keys 0-3 there is no associated mac address */
4498 if (index < 4)
4499 return;
4501 index -= 4;
4502 if (1) {
4503 TODO();
4505 bcm43xx_shm_write32(bcm,
4506 BCM43xx_SHM_HWMAC,
4507 index * 2,
4508 cpu_to_be32(*addr));
4509 bcm43xx_shm_write16(bcm,
4510 BCM43xx_SHM_HWMAC,
4511 (index * 2) + 1,
4512 cpu_to_be16(*((u16 *)(addr + 1))));
4514 } else {
4515 if (index < 8) {
4516 TODO(); /* Put them in the macaddress filter */
4517 } else {
4518 TODO();
4519 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
4520 Keep in mind to update the count of keymacs in 0x003 */
4526 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4530 int acx_clear_keys(acx_device_t * adev)
4532 static const u32 zero_mac[2] = { 0 };
4533 unsigned int i, j, nr_keys = 54;
4534 u16 offset;
4536 /* FixMe:Check for Number of Keys available */
4538 // assert(nr_keys <= ARRAY_SIZE(adev->key));
4540 for (i = 0; i < nr_keys; i++) {
4541 adev->key[i].enabled = 0;
4542 /* returns for i < 4 immediately */
4543 keymac_write(adev, i, zero_mac);
4545 bcm43xx_shm_write16(adev, BCM43xx_SHM_SHARED,
4546 0x100 + (i * 2), 0x0000);
4548 for (j = 0; j < 8; j++) {
4549 offset =
4550 adev->security_offset + (j * 4) +
4551 (i * ACX_SEC_KEYSIZE);
4553 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
4554 offset, 0x0000);
4558 return 1;
4562 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4566 int acx_key_write(acx_device_t * adev,
4567 u16 index, u8 algorithm,
4568 const struct ieee80211_key_conf *key, const u8 * mac_addr)
4570 // struct iw_point *dwrq = &wrqu->encoding;
4571 int result;
4573 FN_ENTER;
4575 log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
4576 dwrq->flags, dwrq->length, extra ? "set" : "No key");
4578 // acx_sem_lock(adev);
4580 // index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4581 if (key->keylen > 0) {
4582 /* if index is 0 or invalid, use default key */
4583 if (index > 3)
4584 index = (int)adev->wep_current_index;
4585 if ((algorithm == ACX_SEC_ALGO_WEP) ||
4586 (algorithm == ACX_SEC_ALGO_WEP104)) {
4587 switch(key->keylen) {
4588 case 40 / 8:
4589 /* WEP 40-bit =
4590 40-bit entered key + 24 bit IV = 64-bit */
4591 adev->wep_keys[index].size = 13;
4592 break;
4593 case 104 / 8:
4594 /* WEP 104-bit =
4595 104-bit entered key + 24-bit IV = 128-bit */
4596 adev->wep_keys[index].size = 29;
4597 break;
4598 case 128 / 8:
4599 /* WEP 128-bit =
4600 128-bit entered key + 24 bit IV = 152-bit */
4601 adev->wep_keys[index].size = 16;
4602 break;
4603 default:
4604 adev->wep_keys[index].size = 0;
4605 return -EINVAL; /* shouldn't happen */
4608 memset(adev->wep_keys[index].key, 0,
4609 sizeof(adev->wep_keys[index].key));
4610 memcpy(adev->wep_keys[index].key, key, key->keylen);
4611 } else {
4612 /* set transmit key */
4613 if (index <= 3)
4614 adev->wep_current_index = index;
4615 // else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
4616 /* complain if we were not just setting
4617 * the key mode */
4618 // result = -EINVAL;
4619 // goto end_unlock;
4620 // }
4624 adev->wep_enabled = (algorithm == ALG_WEP);
4626 adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
4628 if (algorithm & IW_ENCODE_OPEN) {
4629 adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
4630 adev->wep_restricted = 0;
4632 } else if (algorithm & IW_ENCODE_RESTRICTED) {
4633 adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
4634 adev->wep_restricted = 1;
4637 // adev->auth_alg = algorithm;
4638 /* set flag to make sure the card WEP settings get updated */
4639 if (adev->wep_enabled) {
4640 SET_BIT(adev->set_mask, GETSET_WEP);
4641 acx_s_update_card_settings(adev);
4642 // acx_schedule_task(adev, ACX_TASKLET_UPDATE_CARD_CFG);
4645 log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
4646 dwrq->length, extra, dwrq->flags);
4647 for (index = 0; index <= 3; index++) {
4648 if (adev->wep_keys[index].size) {
4649 log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
4650 adev->wep_keys[index].index,
4651 (int) adev->wep_keys[index].size,
4652 adev->wep_keys[index].key);
4656 result = -EINPROGRESS;
4657 // acx_sem_unlock(adev);
4659 FN_EXIT1(result);
4660 return result;
4666 ** Derived from mac80211 code, p54, bcm43xx_mac80211
4670 int acx_net_set_key(struct ieee80211_hw *ieee,
4671 enum set_key_cmd cmd, const u8 *local_addr,
4672 const u8 * addr, struct ieee80211_key_conf *key)
4674 // return 0;
4675 struct acx_device *adev = ieee2adev(ieee);
4676 unsigned long flags;
4677 u8 algorithm;
4678 u16 index;
4679 int err = -EINVAL;
4680 FN_ENTER;
4681 // TODO();
4682 switch (key->alg) {
4683 default:
4684 /* case ALG_NONE:
4685 case ALG_NULL:
4686 algorithm = ACX_SEC_ALGO_NONE;
4687 break;
4688 */ case ALG_WEP:
4689 if (key->keylen == 5)
4690 algorithm = ACX_SEC_ALGO_WEP;
4691 else
4692 algorithm = ACX_SEC_ALGO_WEP104;
4693 break;
4694 case ALG_TKIP:
4695 algorithm = ACX_SEC_ALGO_TKIP;
4696 break;
4697 case ALG_CCMP:
4698 algorithm = ACX_SEC_ALGO_AES;
4699 break;
4702 index = (u8) (key->keyidx);
4703 if (index >= ARRAY_SIZE(adev->key))
4704 goto out;
4705 acx_lock(adev, flags);
4706 switch (cmd) {
4707 case SET_KEY:
4708 err = acx_key_write(adev, index, algorithm, key, addr);
4709 if (err)
4710 goto out_unlock;
4711 key->hw_key_idx = index;
4712 /* CLEAR_BIT(key->flags, IEEE80211_KEY_FORCE_SW_ENCRYPT);*/
4713 /* if (CHECK_BIT(key->flags, IEEE80211_KEY_DEFAULT_TX_KEY))
4714 adev->default_key_idx = index;*/
4715 SET_BIT(key->flags, IEEE80211_KEY_FLAG_GENERATE_IV);
4716 adev->key[index].enabled = 1;
4717 break;
4718 case DISABLE_KEY:
4719 adev->key[index].enabled = 0;
4720 err = 0;
4721 break;
4722 /* case ENABLE_COMPRESSION:
4723 case DISABLE_COMPRESSION:
4724 err = 0;
4725 break; */
4727 out_unlock:
4728 acx_unlock(adev, flags);
4729 out:
4730 FN_EXIT0;
4731 return err;
4736 /***********************************************************************
4737 ** Common function to parse ALL configoption struct formats
4738 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
4739 ** FIXME: logging should be removed here and added to a /proc file instead
4741 ** Look into bcm43xx
4743 void
4744 acx_s_parse_configoption(acx_device_t * adev,
4745 const acx111_ie_configoption_t * pcfg)
4747 const u8 *pEle;
4748 int i;
4749 int is_acx111 = IS_ACX111(adev);
4751 acx_log_dump(LOG_DEBUG, L_REALLYVERBOSE, pcfg, sizeof(*pcfg),
4752 "configoption struct content:\n");
4754 if ((is_acx111 && (adev->eeprom_version == 5))
4755 || (!is_acx111 && (adev->eeprom_version == 4))
4756 || (!is_acx111 && (adev->eeprom_version == 5))) {
4757 /* these versions are known to be supported */
4758 } else {
4759 acx_log(LOG_WARNING, L_ANY,
4760 "unknown chip and EEPROM version combination "
4761 "(%s, v%d), "
4762 "don't know how to parse config options yet. "
4763 "Please report\n", is_acx111 ? "ACX111" : "ACX100",
4764 adev->eeprom_version);
4765 return;
4768 /* first custom-parse the first part which has chip-specific layout */
4770 pEle = (const u8 *)pcfg;
4772 pEle += 4; /* skip (type,len) header */
4774 memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
4775 pEle += sizeof(adev->cfgopt_NVSv);
4777 if (is_acx111) {
4778 adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *) pEle);
4779 pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
4781 adev->cfgopt_probe_delay = 200; /* good default value? */
4782 pEle += 2; /* FIXME: unknown, value 0x0001 */
4783 } else {
4784 memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
4785 pEle += sizeof(adev->cfgopt_MAC);
4787 adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *) pEle);
4788 pEle += sizeof(adev->cfgopt_probe_delay);
4789 if ((adev->cfgopt_probe_delay < 100)
4790 || (adev->cfgopt_probe_delay > 500)) {
4791 acx_log(LOG_WARNING, L_ANY,
4792 "strange probe_delay value %d, "
4793 "tweaking to 200\n", adev->cfgopt_probe_delay);
4794 adev->cfgopt_probe_delay = 200;
4798 adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *) pEle);
4799 pEle += sizeof(adev->cfgopt_eof_memory);
4801 acx_log(LOG_INFO, L_ANY, "NVS_vendor_offs:%04X probe_delay:%d "
4802 "eof_memory:%d\n",
4803 adev->cfgopt_NVS_vendor_offs, adev->cfgopt_probe_delay,
4804 adev->cfgopt_eof_memory);
4806 adev->cfgopt_dot11CCAModes = *pEle++;
4807 adev->cfgopt_dot11Diversity = *pEle++;
4808 adev->cfgopt_dot11ShortPreambleOption = *pEle++;
4809 adev->cfgopt_dot11PBCCOption = *pEle++;
4810 adev->cfgopt_dot11ChannelAgility = *pEle++;
4811 adev->cfgopt_dot11PhyType = *pEle++;
4812 adev->cfgopt_dot11TempType = *pEle++;
4813 acx_log(LOG_INFO, L_ANY,
4814 "CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
4815 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
4816 adev->cfgopt_dot11CCAModes, adev->cfgopt_dot11Diversity,
4817 adev->cfgopt_dot11ShortPreambleOption,
4818 adev->cfgopt_dot11PBCCOption, adev->cfgopt_dot11ChannelAgility,
4819 adev->cfgopt_dot11PhyType, adev->cfgopt_dot11TempType);
4821 /* then use common parsing for next part which has common layout */
4823 pEle++; /* skip table_count (6) */
4825 adev->cfgopt_antennas.type = pEle[0];
4826 adev->cfgopt_antennas.len = pEle[1];
4829 * FIXME: a candidate for acx_log_dump(), but the code is bizarre
4831 acx_log(LOG_INFO, L_ANY, "AntennaID:%02X Len:%02X Data:",
4832 adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
4833 for (i = 0; i < pEle[1]; i++) {
4834 adev->cfgopt_antennas.list[i] = pEle[i + 2];
4835 printk("%02X ", pEle[i + 2]);
4837 printk("\n");
4839 pEle += pEle[1] + 2;
4840 adev->cfgopt_power_levels.type = pEle[0];
4841 adev->cfgopt_power_levels.len = pEle[1];
4844 * FIXME: see above
4846 acx_log(LOG_INFO, L_ANY, "PowerLevelID:%02X Len:%02X Data:",
4847 adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
4848 for (i = 0; i < pEle[1]; i++) {
4849 adev->cfgopt_power_levels.list[i] =
4850 le16_to_cpu(*(u16 *) & pEle[i * 2 + 2]);
4851 printk("%04X ", adev->cfgopt_power_levels.list[i]);
4853 printk("\n");
4855 pEle += pEle[1] * 2 + 2;
4856 adev->cfgopt_data_rates.type = pEle[0];
4857 adev->cfgopt_data_rates.len = pEle[1];
4860 * FIXME again
4862 acx_log(LOG_INFO, L_ANY, "DataRatesID:%02X Len:%02X Data:",
4863 adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
4864 for (i = 0; i < pEle[1]; i++) {
4865 adev->cfgopt_data_rates.list[i] = pEle[i + 2];
4866 printk("%02X ", pEle[i + 2]);
4868 printk("\n");
4870 pEle += pEle[1] + 2;
4871 adev->cfgopt_domains.type = pEle[0];
4872 adev->cfgopt_domains.len = pEle[1];
4875 * And again
4877 acx_log(LOG_INFO, L_ANY, "DomainID:%02X Len:%02X Data:",
4878 adev->cfgopt_domains.type, adev->cfgopt_domains.len);
4879 for (i = 0; i < pEle[1]; i++) {
4880 adev->cfgopt_domains.list[i] = pEle[i + 2];
4881 printk("%02X ", pEle[i + 2]);
4883 printk("\n");
4885 pEle += pEle[1] + 2;
4886 adev->cfgopt_product_id.type = pEle[0];
4887 adev->cfgopt_product_id.len = pEle[1];
4888 for (i = 0; i < pEle[1]; i++) {
4889 adev->cfgopt_product_id.list[i] = pEle[i + 2];
4891 acx_log(LOG_INFO, L_ANY, "ProductID:%02X Len:%02X Data:%.*s\n",
4892 adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
4893 adev->cfgopt_product_id.len,
4894 (char *)adev->cfgopt_product_id.list);
4896 pEle += pEle[1] + 2;
4897 adev->cfgopt_manufacturer.type = pEle[0];
4898 adev->cfgopt_manufacturer.len = pEle[1];
4899 for (i = 0; i < pEle[1]; i++) {
4900 adev->cfgopt_manufacturer.list[i] = pEle[i + 2];
4902 acx_log(LOG_INFO, L_ANY, "ManufacturerID:%02X Len:%02X Data:%.*s\n",
4903 adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
4904 adev->cfgopt_manufacturer.len,
4905 (char *)adev->cfgopt_manufacturer.list);
4907 printk("EEPROM part:\n");
4908 for (i=0; i<58; i++) {
4909 printk("%02X =======> 0x%02X\n",
4910 i, (u8 *)adev->cfgopt_NVSv[i-2]);
4916 /***********************************************************************
4917 ** Linux Kernel Specific
4919 static int __init acx_e_init_module(void)
4921 int r1, r2;
4923 acx_struct_size_check();
4925 acx_log(LOG_INFO, L_ANY, "this driver is still EXPERIMENTAL\n");
4926 acx_log(LOG_INFO, L_ANY, "acx: reading README file and/or "
4927 "Craig's HOWTO is recommended, "
4928 "visit http://acx100.sourceforge.net/wiki in case "
4929 "of further questions/discussion\n");
4931 #if defined(CONFIG_ACX_MAC80211_PCI)
4932 r1 = acxpci_e_init_module();
4933 #else
4934 r1 = -EINVAL;
4935 #endif
4936 #if defined(CONFIG_ACX_MAC80211_USB)
4937 r2 = acxusb_e_init_module();
4938 #else
4939 r2 = -EINVAL;
4940 #endif
4941 if (r2 && r1) /* both failed! */
4942 return r2 ? r2 : r1;
4943 /* return success if at least one succeeded */
4944 return 0;
4947 static void __exit acx_e_cleanup_module(void)
4949 #if defined(CONFIG_ACX_MAC80211_PCI)
4950 acxpci_e_cleanup_module();
4951 #endif
4952 #if defined(CONFIG_ACX_MAC80211_USB)
4953 acxusb_e_cleanup_module();
4954 #endif
4957 module_init(acx_e_init_module)
4958 module_exit(acx_e_cleanup_module)