1 /***********************************************************************
2 ** Copyright (C) 2003 ACX100 Open Source Project
4 ** The contents of this file are subject to the Mozilla Public
5 ** License Version 1.1 (the "License"); you may not use this file
6 ** except in compliance with the License. You may obtain a copy of
7 ** the License at http://www.mozilla.org/MPL/
9 ** Software distributed under the License is distributed on an "AS
10 ** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11 ** implied. See the License for the specific language governing
12 ** rights and limitations under the License.
14 ** Alternatively, the contents of this file may be used under the
15 ** terms of the GNU Public License version 2 (the "GPL"), in which
16 ** case the provisions of the GPL are applicable instead of the
17 ** above. If you wish to allow the use of your version of this file
18 ** only under the terms of the GPL and not to allow others to use
19 ** your version of this file under the MPL, indicate your decision
20 ** by deleting the provisions above and replace them with the notice
21 ** and other provisions required by the GPL. If you do not delete
22 ** the provisions above, a recipient may use your version of this
23 ** file under either the MPL or the GPL.
24 ** ---------------------------------------------------------------------
25 ** Inquiries regarding the ACX100 Open Source Project can be
28 ** acx100-users@lists.sf.net
29 ** http://acx100.sf.net
30 ** ---------------------------------------------------------------------
33 #include <linux/version.h>
34 #include <linux/module.h>
35 #include <linux/kernel.h>
36 #include <linux/sched.h>
37 #include <linux/types.h>
38 #include <linux/slab.h>
39 #include <linux/delay.h>
40 #include <linux/proc_fs.h>
41 #include <linux/if_arp.h>
42 #include <linux/rtnetlink.h>
43 #include <linux/netdevice.h>
44 #include <linux/etherdevice.h>
45 #include <linux/wireless.h>
47 #include <linux/vmalloc.h>
48 #include <net/iw_handler.h>
53 /***********************************************************************
55 static client_t
*acx_l_sta_list_alloc(acx_device_t
*adev
);
56 static client_t
*acx_l_sta_list_get_from_hash(acx_device_t
*adev
, const u8
*address
);
58 static int acx_l_process_data_frame_master(acx_device_t
*adev
, rxbuffer_t
*rxbuf
);
59 static int acx_l_process_data_frame_client(acx_device_t
*adev
, rxbuffer_t
*rxbuf
);
60 /* static int acx_l_process_NULL_frame(acx_device_t *adev, rxbuffer_t *rxbuf, int vala); */
61 static int acx_l_process_mgmt_frame(acx_device_t
*adev
, rxbuffer_t
*rxbuf
);
62 static void acx_l_process_disassoc_from_sta(acx_device_t
*adev
, const wlan_fr_disassoc_t
*req
);
63 static void acx_l_process_disassoc_from_ap(acx_device_t
*adev
, const wlan_fr_disassoc_t
*req
);
64 static void acx_l_process_deauth_from_sta(acx_device_t
*adev
, const wlan_fr_deauthen_t
*req
);
65 static void acx_l_process_deauth_from_ap(acx_device_t
*adev
, const wlan_fr_deauthen_t
*req
);
66 static int acx_l_process_probe_response(acx_device_t
*adev
, wlan_fr_proberesp_t
*req
, const rxbuffer_t
*rxbuf
);
67 static int acx_l_process_assocresp(acx_device_t
*adev
, const wlan_fr_assocresp_t
*req
);
68 static int acx_l_process_reassocresp(acx_device_t
*adev
, const wlan_fr_reassocresp_t
*req
);
69 static int acx_l_process_authen(acx_device_t
*adev
, const wlan_fr_authen_t
*req
);
70 static int acx_l_transmit_assocresp(acx_device_t
*adev
, const wlan_fr_assocreq_t
*req
);
71 static int acx_l_transmit_reassocresp(acx_device_t
*adev
, const wlan_fr_reassocreq_t
*req
);
72 static int acx_l_transmit_deauthen(acx_device_t
*adev
, const u8
*addr
, u16 reason
);
73 static int acx_l_transmit_authen1(acx_device_t
*adev
);
74 static int acx_l_transmit_authen2(acx_device_t
*adev
, const wlan_fr_authen_t
*req
, client_t
*clt
);
75 static int acx_l_transmit_authen3(acx_device_t
*adev
, const wlan_fr_authen_t
*req
);
76 static int acx_l_transmit_authen4(acx_device_t
*adev
, const wlan_fr_authen_t
*req
);
77 static int acx_l_transmit_assoc_req(acx_device_t
*adev
);
80 /***********************************************************************
83 unsigned int acx_debug
/* will add __read_mostly later */ = ACX_DEFAULT_MSG
;
84 /* parameter is 'debug', corresponding var is acx_debug */
85 module_param_named(debug
, acx_debug
, uint
, 0);
86 MODULE_PARM_DESC(debug
, "Debug level mask (see L_xxx constants)");
90 MODULE_LICENSE("Dual MPL/GPL");
92 /* USB had this: MODULE_AUTHOR("Martin Wawro <martin.wawro AT uni-dortmund.de>"); */
93 MODULE_AUTHOR("ACX100 Open Source Driver development team");
94 MODULE_DESCRIPTION("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)");
97 /***********************************************************************
99 /* Probably a number of acx's intermediate buffers for USB transfers,
100 ** not to be confused with number of descriptors in tx/rx rings
101 ** (which are not directly accessible to host in USB devices) */
102 #define USB_RX_CNT 10
103 #define USB_TX_CNT 10
106 /***********************************************************************
109 /* minutes to wait until next radio recalibration: */
110 #define RECALIB_PAUSE 5
112 /* Please keep acx_reg_domain_ids_len in sync... */
113 const u8 acx_reg_domain_ids
[acx_reg_domain_ids_len
] =
114 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 };
115 static const u16 reg_domain_channel_masks
[acx_reg_domain_ids_len
] =
116 { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc };
118 acx_reg_domain_strings
[] = {
119 /* 0 */ " 1-11 FCC (USA)",
120 /* 1 */ " 1-11 DOC/IC (Canada)",
121 /* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */
122 /* 2 */ " 1-13 ETSI (Europe)",
123 /* 3 */ "10-11 Spain",
124 /* 4 */ "10-13 France",
125 /* 5 */ " 14 MKK (Japan)",
126 /* 6 */ " 1-14 MKK1",
127 /* 7 */ " 3-9 Israel (not all firmware versions)",
128 NULL
/* needs to remain as last entry */
133 /***********************************************************************
136 #ifdef PARANOID_LOCKING
137 static unsigned max_lock_time
;
138 static unsigned max_sem_time
;
141 acx_lock_unhold() { max_lock_time
= 0; }
143 acx_sem_unhold() { max_sem_time
= 0; }
145 static inline const char*
146 sanitize_str(const char *s
)
148 const char* t
= strrchr(s
, '/');
154 acx_lock_debug(acx_device_t
*adev
, const char* where
)
156 unsigned int count
= 100*1000*1000;
157 where
= sanitize_str(where
);
159 if (!spin_is_locked(&adev
->lock
)) break;
163 printk(KERN_EMERG
"LOCKUP: already taken at %s!\n", adev
->last_lock
);
166 adev
->last_lock
= where
;
167 rdtscl(adev
->lock_time
);
170 acx_unlock_debug(acx_device_t
*adev
, const char* where
)
173 if (!spin_is_locked(&adev
->lock
)) {
174 where
= sanitize_str(where
);
175 printk(KERN_EMERG
"STRAY UNLOCK at %s!\n", where
);
179 if (acx_debug
& L_LOCK
) {
182 diff
-= adev
->lock_time
;
183 if (diff
> max_lock_time
) {
184 where
= sanitize_str(where
);
185 printk("max lock hold time %ld CPU ticks from %s "
186 "to %s\n", diff
, adev
->last_lock
, where
);
187 max_lock_time
= diff
;
192 acx_down_debug(acx_device_t
*adev
, const char* where
)
195 unsigned long timeout
= jiffies
+ 5*HZ
;
197 where
= sanitize_str(where
);
200 sem_count
= atomic_read(&adev
->sem
.count
);
201 if (sem_count
) break;
202 if (time_after(jiffies
, timeout
))
207 printk(KERN_EMERG
"D STATE at %s! last sem at %s\n",
208 where
, adev
->last_sem
);
211 adev
->last_sem
= where
;
212 adev
->sem_time
= jiffies
;
214 if (acx_debug
& L_LOCK
) {
215 printk("%s: sem_down %d -> %d\n",
216 where
, sem_count
, atomic_read(&adev
->sem
.count
));
220 acx_up_debug(acx_device_t
*adev
, const char* where
)
222 int sem_count
= atomic_read(&adev
->sem
.count
);
224 where
= sanitize_str(where
);
225 printk(KERN_EMERG
"STRAY UP at %s! sem.count=%d\n", where
, sem_count
);
228 if (acx_debug
& L_LOCK
) {
229 unsigned long diff
= jiffies
- adev
->sem_time
;
230 if (diff
> max_sem_time
) {
231 where
= sanitize_str(where
);
232 printk("max sem hold time %ld jiffies from %s "
233 "to %s\n", diff
, adev
->last_sem
, where
);
238 if (acx_debug
& L_LOCK
) {
239 where
= sanitize_str(where
);
240 printk("%s: sem_up %d -> %d\n",
241 where
, sem_count
, atomic_read(&adev
->sem
.count
));
244 #endif /* PARANOID_LOCKING */
247 /***********************************************************************
251 static int acx_debug_func_indent
;
253 #define FUNC_INDENT_INCREMENT 2
256 #define TIMESTAMP(d) unsigned long d; rdtscl(d)
258 #define TIMESTAMP(d) unsigned long d = jiffies
262 spaces
[] = " " " "; /* Nx10 spaces */
265 log_fn_enter(const char *funcname
)
270 indent
= acx_debug_func_indent
;
271 if (indent
>= sizeof(spaces
))
272 indent
= sizeof(spaces
)-1;
274 printk("%08ld %s==> %s\n",
276 spaces
+ (sizeof(spaces
)-1) - indent
,
280 acx_debug_func_indent
+= FUNC_INDENT_INCREMENT
;
283 log_fn_exit(const char *funcname
)
288 acx_debug_func_indent
-= FUNC_INDENT_INCREMENT
;
290 indent
= acx_debug_func_indent
;
291 if (indent
>= sizeof(spaces
))
292 indent
= sizeof(spaces
)-1;
294 printk("%08ld %s<== %s\n",
296 spaces
+ (sizeof(spaces
)-1) - indent
,
301 log_fn_exit_v(const char *funcname
, int v
)
306 acx_debug_func_indent
-= FUNC_INDENT_INCREMENT
;
308 indent
= acx_debug_func_indent
;
309 if (indent
>= sizeof(spaces
))
310 indent
= sizeof(spaces
)-1;
312 printk("%08ld %s<== %s: %08X\n",
314 spaces
+ (sizeof(spaces
)-1) - indent
,
319 #endif /* ACX_DEBUG > 1 */
322 /***********************************************************************
323 ** Basically a msleep with logging
334 /***********************************************************************
335 ** Not inlined: it's larger than it seems
338 acx_print_mac(const char *head
, const u8
*mac
, const char *tail
)
340 printk("%s"MACSTR
"%s", head
, MAC(mac
), tail
);
344 /***********************************************************************
345 ** acx_get_status_name
348 acx_get_status_name(u16 status
)
350 static const char * const str
[] = {
351 "STOPPED", "SCANNING", "WAIT_AUTH",
352 "AUTHENTICATED", "ASSOCIATED", "INVALID??"
354 if (status
> VEC_SIZE(str
)-1)
355 status
= VEC_SIZE(str
)-1;
361 /***********************************************************************
362 ** acx_get_packet_type_string
366 acx_get_packet_type_string(u16 fc
)
368 static const char * const mgmt_arr
[] = {
369 "MGMT/AssocReq", "MGMT/AssocResp", "MGMT/ReassocReq",
370 "MGMT/ReassocResp", "MGMT/ProbeReq", "MGMT/ProbeResp",
371 "MGMT/UNKNOWN", "MGMT/UNKNOWN", "MGMT/Beacon", "MGMT/ATIM",
372 "MGMT/Disassoc", "MGMT/Authen", "MGMT/Deauthen"
374 static const char * const ctl_arr
[] = {
375 "CTL/PSPoll", "CTL/RTS", "CTL/CTS", "CTL/Ack", "CTL/CFEnd",
378 static const char * const data_arr
[] = {
379 "DATA/DataOnly", "DATA/Data CFAck", "DATA/Data CFPoll",
380 "DATA/Data CFAck/CFPoll", "DATA/Null", "DATA/CFAck",
381 "DATA/CFPoll", "DATA/CFAck/CFPoll"
384 u8 fstype
= (WF_FC_FSTYPE
& fc
) >> 4;
387 switch (WF_FC_FTYPE
& fc
) {
389 if (fstype
< VEC_SIZE(mgmt_arr
))
390 str
= mgmt_arr
[fstype
];
392 str
= "MGMT/UNKNOWN";
396 if (ctl
< VEC_SIZE(ctl_arr
))
402 if (fstype
< VEC_SIZE(data_arr
))
403 str
= data_arr
[fstype
];
405 str
= "DATA/UNKNOWN";
416 /***********************************************************************
417 ** acx_wlan_reason_str
419 static inline const char*
420 acx_wlan_reason_str(u16 reason
)
422 static const char* const reason_str
[] = {
424 /* 1 */ "unspecified",
425 /* 2 */ "prev auth is not valid",
426 /* 3 */ "leaving BBS",
427 /* 4 */ "due to inactivity",
428 /* 5 */ "AP is busy",
429 /* 6 */ "got class 2 frame from non-auth'ed STA",
430 /* 7 */ "got class 3 frame from non-assoc'ed STA",
431 /* 8 */ "STA has left BSS",
432 /* 9 */ "assoc without auth is not allowed",
433 /* 10 */ "bad power setting (802.11h)",
434 /* 11 */ "bad channel (802.11i)",
436 /* 13 */ "invalid IE",
437 /* 14 */ "MIC failure",
438 /* 15 */ "four-way handshake timeout",
439 /* 16 */ "group key handshake timeout",
440 /* 17 */ "IE is different",
441 /* 18 */ "invalid group cipher",
442 /* 19 */ "invalid pairwise cipher",
443 /* 20 */ "invalid AKMP",
444 /* 21 */ "unsupported RSN version",
445 /* 22 */ "invalid RSN IE cap",
446 /* 23 */ "802.1x failed",
447 /* 24 */ "cipher suite rejected"
449 return reason
< VEC_SIZE(reason_str
) ? reason_str
[reason
] : "?";
453 /***********************************************************************
454 ** acx_cmd_status_str
457 acx_cmd_status_str(unsigned int state
)
459 static const char * const cmd_error_strings
[] = {
463 "Invalid Information Element",
465 "Channel invalid in current regulatory domain",
467 "Command rejected (read-only information element)",
478 return state
< VEC_SIZE(cmd_error_strings
) ?
479 cmd_error_strings
[state
] : "?";
483 /***********************************************************************
486 static inline const char*
487 get_status_string(unsigned int status
)
489 /* A bit shortened, but hopefully still understandable */
490 static const char * const status_str
[] = {
491 /* 0 */ "Successful",
492 /* 1 */ "Unspecified failure",
501 /*10 */ "Cannot support all requested capabilities in Capability Information field",
502 /*11 */ "Reassoc denied (reason outside of 802.11b scope)",
503 /*12 */ "Assoc denied (reason outside of 802.11b scope), maybe MAC filtering by peer?",
504 /*13 */ "Responding station doesnt support specified auth algorithm",
505 /*14 */ "Auth rejected: wrong transaction sequence number",
506 /*15 */ "Auth rejected: challenge failure",
507 /*16 */ "Auth rejected: timeout for next frame in sequence",
508 /*17 */ "Assoc denied: too many STAs on this AP",
509 /*18 */ "Assoc denied: requesting STA doesnt support all data rates in basic set",
510 /*19 */ "Assoc denied: requesting STA doesnt support Short Preamble",
511 /*20 */ "Assoc denied: requesting STA doesnt support PBCC Modulation",
512 /*21 */ "Assoc denied: requesting STA doesnt support Channel Agility"
516 /*25 */ "Assoc denied: requesting STA doesnt support Short Slot Time",
517 /*26 */ "Assoc denied: requesting STA doesnt support DSSS-OFDM"
520 return status_str
[status
< VEC_SIZE(status_str
) ? status
: 2];
524 /***********************************************************************
527 acx_log_bad_eid(wlan_hdr_t
* hdr
, int len
, wlan_ie_t
* ie_ptr
)
529 if (acx_debug
& L_ASSOC
) {
530 int offset
= (u8
*)ie_ptr
- (u8
*)hdr
;
531 printk("acx: unknown EID %d in mgmt frame at offset %d. IE: ",
532 ie_ptr
->eid
, offset
);
533 /* IE len can be bogus, IE can extend past packet end. Oh well... */
534 acx_dump_bytes(ie_ptr
, ie_ptr
->len
+ 2);
535 if (acx_debug
& L_DATA
) {
536 printk("frame (%s): ",
537 acx_get_packet_type_string(le16_to_cpu(hdr
->fc
)));
538 acx_dump_bytes(hdr
, len
);
544 /***********************************************************************
548 acx_dump_bytes(const void *data
, int num
)
550 const u8
* ptr
= (const u8
*)data
;
558 printk( "%02X %02X %02X %02X %02X %02X %02X %02X "
559 "%02X %02X %02X %02X %02X %02X %02X %02X\n",
560 ptr
[0], ptr
[1], ptr
[2], ptr
[3],
561 ptr
[4], ptr
[5], ptr
[6], ptr
[7],
562 ptr
[8], ptr
[9], ptr
[10], ptr
[11],
563 ptr
[12], ptr
[13], ptr
[14], ptr
[15]);
569 printk("%02X ", *ptr
++);
570 printk("%02X\n", *ptr
);
576 /***********************************************************************
577 ** acx_s_get_firmware_version
580 acx_s_get_firmware_version(acx_device_t
*adev
)
583 u8 hexarr
[4] = { 0, 0, 0, 0 };
584 int hexidx
= 0, val
= 0;
590 memset(fw
.fw_id
, 'E', FW_ID_SIZE
);
591 acx_s_interrogate(adev
, &fw
, ACX1xx_IE_FWREV
);
592 memcpy(adev
->firmware_version
, fw
.fw_id
, FW_ID_SIZE
);
593 adev
->firmware_version
[FW_ID_SIZE
] = '\0';
595 log(L_DEBUG
, "fw_ver: fw_id='%s' hw_id=%08X\n",
596 adev
->firmware_version
, fw
.hw_id
);
598 if (strncmp(fw
.fw_id
, "Rev ", 4) != 0) {
599 printk("acx: strange firmware version string "
600 "'%s', please report\n", adev
->firmware_version
);
601 adev
->firmware_numver
= 0x01090407; /* assume 1.9.4.7 */
606 if ((c
== '.') || (c
== '\0')) {
607 hexarr
[hexidx
++] = val
;
608 if ((hexidx
> 3) || (c
== '\0')) /* end? */
613 if ((c
>= '0') && (c
<= '9'))
616 c
= c
- 'a' + (char)10;
620 adev
->firmware_numver
= (u32
)(
621 (hexarr
[0] << 24) + (hexarr
[1] << 16)
622 + (hexarr
[2] << 8) + hexarr
[3]);
623 log(L_DEBUG
, "firmware_numver 0x%08X\n", adev
->firmware_numver
);
625 if (IS_ACX111(adev
)) {
626 if (adev
->firmware_numver
== 0x00010011) {
627 /* This one does not survive floodpinging */
628 printk("acx: firmware '%s' is known to be buggy, "
629 "please upgrade\n", adev
->firmware_version
);
633 adev
->firmware_id
= le32_to_cpu(fw
.hw_id
);
635 /* we're able to find out more detailed chip names now */
636 switch (adev
->firmware_id
& 0xffff0000) {
639 adev
->chip_name
= "TNETW1100A";
642 adev
->chip_name
= "TNETW1100B";
646 adev
->chip_name
= "TNETW1130";
648 case 0x04030000: /* 0x04030101 is TNETW1450 */
649 adev
->chip_name
= "TNETW1450";
652 printk("acx: unknown chip ID 0x%08X, "
653 "please report\n", adev
->firmware_id
);
661 /***********************************************************************
662 ** acx_display_hardware_details
664 ** Displays hw/fw version, radio type etc...
667 acx_display_hardware_details(acx_device_t
*adev
)
669 const char *radio_str
, *form_str
;
673 switch (adev
->radio_type
) {
680 case RADIO_RALINK_15
:
681 radio_str
= "Ralink";
686 case RADIO_UNKNOWN_17
:
687 /* TI seems to have a radio which is
688 * additionally 802.11a capable, too */
689 radio_str
= "802.11a/b/g radio?! Please report";
691 case RADIO_UNKNOWN_19
:
692 radio_str
= "A radio used by Safecom cards?! Please report";
694 case RADIO_UNKNOWN_1B
:
695 radio_str
= "An unknown radio used by TNETW1450 USB adapters";
698 radio_str
= "UNKNOWN, please report radio type name!";
702 switch (adev
->form_factor
) {
704 form_str
= "unspecified";
707 form_str
= "(mini-)PCI / CardBus";
713 form_str
= "Compact Flash";
716 form_str
= "UNKNOWN, please report";
720 printk("acx: form factor 0x%02X (%s), "
721 "radio type 0x%02X (%s), EEPROM version 0x%02X, "
722 "uploaded firmware '%s' (0x%08X)\n",
723 adev
->form_factor
, form_str
, adev
->radio_type
, radio_str
,
724 adev
->eeprom_version
, adev
->firmware_version
,
731 /***********************************************************************
734 acx_e_change_mtu(struct net_device
*ndev
, int mtu
)
738 MAX_MTU
= WLAN_DATA_MAXLEN
- (ETH_HLEN
)
741 if (mtu
< MIN_MTU
|| mtu
> MAX_MTU
)
749 /***********************************************************************
750 ** acx_e_get_stats, acx_e_get_wireless_stats
752 struct net_device_stats
*
753 acx_e_get_stats(struct net_device
*ndev
)
755 acx_device_t
*adev
= ndev2adev(ndev
);
759 struct iw_statistics
*
760 acx_e_get_wireless_stats(struct net_device
*ndev
)
762 acx_device_t
*adev
= ndev2adev(ndev
);
763 return &adev
->wstats
;
767 /***********************************************************************
768 ** maps acx111 tx descr rate field to acx100 one
771 acx_bitpos2rate100
[] = {
775 RATE100_2
,/* 3, should not happen */
776 RATE100_2
,/* 4, should not happen */
778 RATE100_2
,/* 6, should not happen */
779 RATE100_2
,/* 7, should not happen */
781 RATE100_2
,/* 9, should not happen */
782 RATE100_2
,/* 10, should not happen */
783 RATE100_2
,/* 11, should not happen */
784 RATE100_2
,/* 12, should not happen */
785 RATE100_2
,/* 13, should not happen */
786 RATE100_2
,/* 14, should not happen */
787 RATE100_2
,/* 15, should not happen */
791 acx_rate111to100(u16 r
) {
792 return acx_bitpos2rate100
[highest_bit(r
)];
796 /***********************************************************************
797 ** Calculate level like the feb 2003 windows driver seems to do
800 acx_signal_to_winlevel(u8 rawlevel
)
802 /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
803 u8 winlevel
= ((4 + (rawlevel
* 5)) / 8);
811 acx_signal_determine_quality(u8 signal
, u8 noise
)
815 qual
= (((signal
- 30) * 100 / 70) + (100 - noise
* 4)) / 2;
825 /***********************************************************************
826 ** Interrogate/configure commands
829 /* FIXME: the lengths given here probably aren't always correct.
830 * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4",
831 * unless the firmware actually expects a different length than the struct length */
835 ACX100_IE_ACX_TIMER_LEN
,
836 sizeof(acx100_ie_powersave_t
)-4, /* is that 6 or 8??? */
837 ACX1xx_IE_QUEUE_CONFIG_LEN
,
838 ACX100_IE_BLOCK_SIZE_LEN
,
839 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN
,
840 ACX1xx_IE_RATE_FALLBACK_LEN
,
841 ACX100_IE_WEP_OPTIONS_LEN
,
842 ACX1xx_IE_MEMORY_MAP_LEN
, /* ACX1xx_IE_SSID_LEN, */
844 ACX1xx_IE_ASSOC_ID_LEN
,
846 ACX111_IE_CONFIG_OPTIONS_LEN
,
848 ACX1xx_IE_FCS_ERROR_COUNT_LEN
,
849 ACX1xx_IE_MEDIUM_USAGE_LEN
,
850 ACX1xx_IE_RXCONFIG_LEN
,
853 sizeof(fw_stats_t
)-4,
855 ACX1xx_IE_FEATURE_CONFIG_LEN
,
856 ACX111_IE_KEY_CHOOSE_LEN
,
857 ACX1FF_IE_MISC_CONFIG_TABLE_LEN
,
858 ACX1FF_IE_WONE_CONFIG_LEN
,
860 ACX1FF_IE_TID_CONFIG_LEN
,
864 ACX1FF_IE_CALIB_ASSESSMENT_LEN
,
865 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN
,
866 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN
,
867 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN
,
869 ACX1FF_IE_PACKET_DETECT_THRESH_LEN
,
870 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN
,
871 ACX1FF_IE_CCA_THRESHOLD_LEN
,
872 ACX1FF_IE_EVENT_MASK_LEN
,
873 ACX1FF_IE_DTIM_PERIOD_LEN
,
875 ACX1FF_IE_ACI_CONFIG_SET_LEN
,
882 ACX1FF_IE_EEPROM_VER_LEN
,
886 acx100_ie_len_dot11
[] = {
888 ACX1xx_IE_DOT11_STATION_ID_LEN
,
890 ACX100_IE_DOT11_BEACON_PERIOD_LEN
,
891 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN
,
892 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN
,
893 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN
,
894 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN
,
895 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN
,
897 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN
,
898 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN
,
900 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN
,
901 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN
,
902 ACX100_IE_DOT11_ED_THRESHOLD_LEN
,
903 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN
,
912 ACX100_IE_ACX_TIMER_LEN
,
913 sizeof(acx111_ie_powersave_t
)-4,
914 ACX1xx_IE_QUEUE_CONFIG_LEN
,
915 ACX100_IE_BLOCK_SIZE_LEN
,
916 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN
,
917 ACX1xx_IE_RATE_FALLBACK_LEN
,
918 ACX100_IE_WEP_OPTIONS_LEN
,
919 ACX1xx_IE_MEMORY_MAP_LEN
, /* ACX1xx_IE_SSID_LEN, */
921 ACX1xx_IE_ASSOC_ID_LEN
,
923 ACX111_IE_CONFIG_OPTIONS_LEN
,
925 ACX1xx_IE_FCS_ERROR_COUNT_LEN
,
926 ACX1xx_IE_MEDIUM_USAGE_LEN
,
927 ACX1xx_IE_RXCONFIG_LEN
,
930 sizeof(fw_stats_t
)-4,
932 ACX1xx_IE_FEATURE_CONFIG_LEN
,
933 ACX111_IE_KEY_CHOOSE_LEN
,
934 ACX1FF_IE_MISC_CONFIG_TABLE_LEN
,
935 ACX1FF_IE_WONE_CONFIG_LEN
,
937 ACX1FF_IE_TID_CONFIG_LEN
,
941 ACX1FF_IE_CALIB_ASSESSMENT_LEN
,
942 ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN
,
943 ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN
,
944 ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN
,
946 ACX1FF_IE_PACKET_DETECT_THRESH_LEN
,
947 ACX1FF_IE_TX_CONFIG_OPTIONS_LEN
,
948 ACX1FF_IE_CCA_THRESHOLD_LEN
,
949 ACX1FF_IE_EVENT_MASK_LEN
,
950 ACX1FF_IE_DTIM_PERIOD_LEN
,
952 ACX1FF_IE_ACI_CONFIG_SET_LEN
,
959 ACX1FF_IE_EEPROM_VER_LEN
,
963 acx111_ie_len_dot11
[] = {
965 ACX1xx_IE_DOT11_STATION_ID_LEN
,
967 ACX100_IE_DOT11_BEACON_PERIOD_LEN
,
968 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN
,
969 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN
,
970 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN
,
971 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN
,
972 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN
,
974 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN
,
975 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN
,
977 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN
,
978 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN
,
979 ACX100_IE_DOT11_ED_THRESHOLD_LEN
,
980 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN
,
988 #define FUNC "configure"
991 acx_s_configure(acx_device_t
*adev
, void *pdr
, int type
)
995 acx_s_configure_debug(acx_device_t
*adev
, void *pdr
, int type
, const char* typestr
)
1002 len
= adev
->ie_len
[type
];
1004 len
= adev
->ie_len_dot11
[type
- 0x1000];
1006 log(L_CTL
, FUNC
"(type:%s,len:%u)\n", typestr
, len
);
1007 if (unlikely(!len
)) {
1008 log(L_DEBUG
, "zero-length type %s?!\n", typestr
);
1011 ((acx_ie_generic_t
*)pdr
)->type
= cpu_to_le16(type
);
1012 ((acx_ie_generic_t
*)pdr
)->len
= cpu_to_le16(len
);
1013 res
= acx_s_issue_cmd(adev
, ACX1xx_CMD_CONFIGURE
, pdr
, len
+ 4);
1014 if (unlikely(OK
!= res
)) {
1016 printk("%s: "FUNC
"(type:%s) FAILED\n", adev
->ndev
->name
, typestr
);
1018 printk("%s: "FUNC
"(type:0x%X) FAILED\n", adev
->ndev
->name
, type
);
1020 /* dump_stack() is already done in issue_cmd() */
1026 #define FUNC "interrogate"
1029 acx_s_interrogate(acx_device_t
*adev
, void *pdr
, int type
)
1033 acx_s_interrogate_debug(acx_device_t
*adev
, void *pdr
, int type
,
1034 const char* typestr
)
1040 /* FIXME: no check whether this exceeds the array yet.
1041 * We should probably remember the number of entries... */
1043 len
= adev
->ie_len
[type
];
1045 len
= adev
->ie_len_dot11
[type
-0x1000];
1047 log(L_CTL
, FUNC
"(type:%s,len:%u)\n", typestr
, len
);
1049 ((acx_ie_generic_t
*)pdr
)->type
= cpu_to_le16(type
);
1050 ((acx_ie_generic_t
*)pdr
)->len
= cpu_to_le16(len
);
1051 res
= acx_s_issue_cmd(adev
, ACX1xx_CMD_INTERROGATE
, pdr
, len
+ 4);
1052 if (unlikely(OK
!= res
)) {
1054 printk("%s: "FUNC
"(type:%s) FAILED\n", adev
->ndev
->name
, typestr
);
1056 printk("%s: "FUNC
"(type:0x%X) FAILED\n", adev
->ndev
->name
, type
);
1058 /* dump_stack() is already done in issue_cmd() */
1065 great_inquisitor(acx_device_t
*adev
)
1070 /* 0x200 was too large here: */
1077 /* 0..0x20, 0x1000..0x1020 */
1078 for (type
= 0; type
<= 0x1020; type
++) {
1081 ie
.type
= cpu_to_le16(type
);
1082 ie
.len
= cpu_to_le16(sizeof(ie
) - 4);
1083 acx_s_issue_cmd(adev
, ACX1xx_CMD_INTERROGATE
, &ie
, sizeof(ie
));
1090 #ifdef CONFIG_PROC_FS
1091 /***********************************************************************
1094 /***********************************************************************
1095 ** acx_l_proc_output
1096 ** Generate content for our /proc entry
1099 ** buf is a pointer to write output to
1100 ** adev is the usual pointer to our private struct acx_device
1102 ** number of bytes actually written to buf
1107 acx_l_proc_output(char *buf
, acx_device_t
*adev
)
1115 "acx driver version:\t\t" ACX_RELEASE
"\n"
1116 "Wireless extension version:\t" STRING(WIRELESS_EXT
) "\n"
1117 "chip name:\t\t\t%s (0x%08X)\n"
1118 "radio type:\t\t\t0x%02X\n"
1119 "form factor:\t\t\t0x%02X\n"
1120 "EEPROM version:\t\t\t0x%02X\n"
1121 "firmware version:\t\t%s (0x%08X)\n",
1122 adev
->chip_name
, adev
->firmware_id
,
1125 adev
->eeprom_version
,
1126 adev
->firmware_version
, adev
->firmware_numver
);
1128 for (i
= 0; i
< VEC_SIZE(adev
->sta_list
); i
++) {
1129 struct client
*bss
= &adev
->sta_list
[i
];
1130 if (!bss
->used
) continue;
1131 p
+= sprintf(p
, "BSS %u BSSID "MACSTR
" ESSID %s channel %u "
1132 "Cap 0x%X SIR %u SNR %u\n",
1133 i
, MAC(bss
->bssid
), (char*)bss
->essid
, bss
->channel
,
1134 bss
->cap_info
, bss
->sir
, bss
->snr
);
1136 p
+= sprintf(p
, "status:\t\t\t%u (%s)\n",
1137 adev
->status
, acx_get_status_name(adev
->status
));
1144 /***********************************************************************
1147 acx_s_proc_diag_output(char *buf
, acx_device_t
*adev
)
1150 unsigned long flags
;
1151 unsigned int len
= 0, partlen
;
1157 fw_stats_t
*fw_stats
;
1158 char *part_str
= NULL
;
1159 fw_stats_tx_t
*tx
= NULL
;
1160 fw_stats_rx_t
*rx
= NULL
;
1161 fw_stats_dma_t
*dma
= NULL
;
1162 fw_stats_irq_t
*irq
= NULL
;
1163 fw_stats_wep_t
*wep
= NULL
;
1164 fw_stats_pwr_t
*pwr
= NULL
;
1165 fw_stats_mic_t
*mic
= NULL
;
1166 fw_stats_aes_t
*aes
= NULL
;
1167 fw_stats_event_t
*evt
= NULL
;
1171 acx_lock(adev
, flags
);
1173 #if defined (ACX_MEM)
1174 p
= acxmem_s_proc_diag_output(p
, adev
);
1177 p
= acxpci_s_proc_diag_output(p
, adev
);
1182 "** network status **\n"
1183 "dev_state_mask 0x%04X\n"
1185 "mode %u, channel %u, "
1186 "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
1187 adev
->dev_state_mask
,
1188 adev
->status
, acx_get_status_name(adev
->status
),
1189 adev
->mode
, adev
->channel
,
1190 adev
->reg_dom_id
, adev
->reg_dom_chanmask
1193 "ESSID \"%s\", essid_active %d, essid_len %d, "
1194 "essid_for_assoc \"%s\", nick \"%s\"\n"
1195 "WEP ena %d, restricted %d, idx %d\n",
1196 adev
->essid
, adev
->essid_active
, (int)adev
->essid_len
,
1197 adev
->essid_for_assoc
, adev
->nick
,
1198 adev
->wep_enabled
, adev
->wep_restricted
,
1199 adev
->wep_current_index
);
1200 p
+= sprintf(p
, "dev_addr "MACSTR
"\n", MAC(adev
->dev_addr
));
1201 p
+= sprintf(p
, "bssid "MACSTR
"\n", MAC(adev
->bssid
));
1202 p
+= sprintf(p
, "ap_filter "MACSTR
"\n", MAC(adev
->ap
));
1206 "** PHY status **\n"
1207 "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
1208 "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
1209 "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
1210 "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
1211 adev
->tx_disabled
, adev
->tx_level_dbm
, /* adev->tx_level_val, adev->tx_level_auto, */
1212 adev
->sensitivity
, adev
->antenna
, adev
->ed_threshold
, adev
->cca
, adev
->preamble_mode
,
1213 adev
->rts_threshold
, adev
->frag_threshold
, adev
->short_retry
, adev
->long_retry
,
1214 adev
->msdu_lifetime
, adev
->listen_interval
, adev
->beacon_interval
);
1216 acx_unlock(adev
, flags
);
1221 "NOTE: version dependent statistics layout, "
1222 "please report if you suspect wrong parsing!\n"
1224 "version \"%s\"\n", adev
->firmware_version
);
1226 /* TODO: may replace kmalloc/memset with kzalloc once
1227 * Linux 2.6.14 is widespread */
1228 fw_stats
= kmalloc(sizeof(*fw_stats
), GFP_KERNEL
);
1233 memset(fw_stats
, 0, sizeof(*fw_stats
));
1235 st
= (u8
*)fw_stats
;
1237 part_str
= "statistics query command";
1239 if (OK
!= acx_s_interrogate(adev
, st
, ACX1xx_IE_FIRMWARE_STATISTICS
))
1245 if (len
> sizeof(*fw_stats
)) {
1247 "firmware version with bigger fw_stats struct detected\n"
1248 "(%u vs. %u), please report\n", len
, sizeof(fw_stats_t
));
1249 if (len
> sizeof(*fw_stats
)) {
1250 p
+= sprintf(p
, "struct size exceeded allocation!\n");
1251 len
= sizeof(*fw_stats
);
1255 st_end
= st
- 2*sizeof(u16
) + len
;
1258 /* let's make one bold assumption here:
1259 * (hopefully!) *all* statistics fields are u32 only,
1260 * thus if we need to make endianness corrections
1261 * we can simply do them in one go, in advance */
1262 st2
= (u8
*)fw_stats
;
1263 for (temp1
= 0; temp1
< len
; temp1
+= 4, st2
+= 4)
1264 *(u32
*)st2
= le32_to_cpu(*(u32
*)st2
);
1269 /* directly at end of a struct part? --> no error! */
1273 tx
= (fw_stats_tx_t
*)st
;
1274 st
+= sizeof(fw_stats_tx_t
);
1275 rx
= (fw_stats_rx_t
*)st
;
1276 st
+= sizeof(fw_stats_rx_t
);
1277 partlen
= sizeof(fw_stats_tx_t
) + sizeof(fw_stats_rx_t
);
1279 if (IS_ACX100(adev
)) {
1280 /* at least ACX100 PCI F/W 1.9.8.b
1281 * and ACX100 USB F/W 1.0.7-USB
1282 * don't have those two fields... */
1283 st
-= 2*sizeof(u32
);
1285 /* our parsing doesn't quite match this firmware yet,
1289 temp1
= temp2
= 999999999;
1293 temp1
= rx
->rx_aci_events
;
1294 temp2
= rx
->rx_aci_resets
;
1299 " tx_desc_overfl %u\n"
1300 " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
1301 " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n"
1302 " rx_aci_events %u, rx_aci_resets %u\n",
1308 rx
->rx_dropped_frame
,
1309 rx
->rx_frame_ptr_err
,
1310 rx
->rx_xfr_hint_trig
,
1319 dma
= (fw_stats_dma_t
*)st
;
1320 partlen
= sizeof(fw_stats_dma_t
);
1328 " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n",
1340 irq
= (fw_stats_irq_t
*)st
;
1341 partlen
= sizeof(fw_stats_irq_t
);
1349 " cmd_cplt %u, fiq %u\n"
1350 " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
1351 " irqs %u, tx_procs %u, decrypt_done %u\n"
1352 " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
1353 " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
1354 " host_acks %u, pci_pm %u, acm_wakeups %u\n",
1367 irq
->tx_exch_complet
,
1370 irq
->hw_pm_mode_changes
,
1380 wep
= (fw_stats_wep_t
*)st
;
1381 partlen
= sizeof(fw_stats_wep_t
);
1385 (IS_PCI(adev
) && IS_ACX100(adev
))
1386 || (IS_USB(adev
) && IS_ACX100(adev
))
1387 || (IS_MEM(adev
) && IS_ACX100(adev
))
1389 /* at least ACX100 PCI F/W 1.9.8.b,
1390 * ACX100 USB F/W 1.0.7-USB
1391 * and ACX100 Generic Slave F/W 1.10.7.K
1392 * don't have those two fields...
1394 st
-= 2*sizeof(u32
);
1397 temp1
= temp2
= 999999999;
1401 temp1
= wep
->wep_pkt_decrypt
;
1402 temp2
= wep
->wep_decrypt_irqs
;
1407 " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
1408 " wep_key_not_found %u, wep_decrypt_fail %u\n"
1409 " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
1412 wep
->wep_default_key_count
,
1413 wep
->dot11_def_key_mib
,
1414 wep
->wep_key_not_found
,
1415 wep
->wep_decrypt_fail
,
1424 pwr
= (fw_stats_pwr_t
*)st
;
1425 partlen
= sizeof(fw_stats_pwr_t
);
1433 " tx_start_ctr %u, no_ps_tx_too_short %u\n"
1434 " rx_start_ctr %u, no_ps_rx_too_short %u\n"
1435 " lppd_started %u\n"
1436 " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n",
1439 pwr
->no_ps_tx_too_short
,
1441 pwr
->no_ps_rx_too_short
,
1443 pwr
->no_lppd_too_noisy
,
1444 pwr
->no_lppd_too_short
,
1445 pwr
->no_lppd_matching_frame
);
1452 mic
= (fw_stats_mic_t
*)st
;
1453 partlen
= sizeof(fw_stats_mic_t
);
1461 " mic_rx_pkts %u, mic_calc_fail %u\n",
1464 mic
->mic_calc_fail
);
1471 aes
= (fw_stats_aes_t
*)st
;
1472 partlen
= sizeof(fw_stats_aes_t
);
1480 " aes_enc_fail %u, aes_dec_fail %u\n"
1481 " aes_enc_pkts %u, aes_dec_pkts %u\n"
1482 " aes_enc_irq %u, aes_dec_irq %u\n",
1496 evt
= (fw_stats_event_t
*)st
;
1497 partlen
= sizeof(fw_stats_event_t
);
1505 " heartbeat %u, calibration %u\n"
1506 " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
1508 " phy_tx_err %u, tx_stuck %u\n",
1520 goto fw_stats_bigger
;
1527 "failed at %s part (size %u), offset %u (struct size %u), "
1528 "please report\n", part_str
, partlen
,
1529 (int)st
- (int)fw_stats
, len
);
1532 for (; st
< st_end
; st
+= 4)
1534 "UNKN%3d: %u\n", (int)st
- (int)fw_stats
, *(u32
*)st
);
1544 /***********************************************************************
1547 acx_s_proc_phy_output(char *buf
, acx_device_t
*adev
)
1555 if (RADIO_RFMD_11 != adev->radio_type) {
1556 printk("sorry, not yet adapted for radio types "
1557 "other than RFMD, please verify "
1558 "PHY size etc. first!\n");
1563 /* The PHY area is only 0x80 bytes long; further pages after that
1564 * only have some page number registers with altered value,
1565 * all other registers remain the same. */
1566 for (i
= 0; i
< 0x80; i
++) {
1567 acx_s_read_phy_reg(adev
, i
, p
++);
1575 /***********************************************************************
1576 ** acx_e_read_proc_XXXX
1577 ** Handle our /proc entry
1580 ** standard kernel read_proc interface
1582 ** number of bytes written to buf
1587 acx_e_read_proc(char *buf
, char **start
, off_t offset
, int count
,
1588 int *eof
, void *data
)
1590 acx_device_t
*adev
= (acx_device_t
*)data
;
1591 unsigned long flags
;
1597 acx_lock(adev
, flags
);
1599 length
= acx_l_proc_output(buf
, adev
);
1600 acx_unlock(adev
, flags
);
1601 acx_sem_unlock(adev
);
1604 if (length
<= offset
+ count
)
1606 *start
= buf
+ offset
;
1617 acx_e_read_proc_diag(char *buf
, char **start
, off_t offset
, int count
,
1618 int *eof
, void *data
)
1620 acx_device_t
*adev
= (acx_device_t
*)data
;
1627 length
= acx_s_proc_diag_output(buf
, adev
);
1628 acx_sem_unlock(adev
);
1631 if (length
<= offset
+ count
)
1633 *start
= buf
+ offset
;
1644 acx_e_read_proc_eeprom(char *buf
, char **start
, off_t offset
, int count
,
1645 int *eof
, void *data
)
1647 acx_device_t
*adev
= (acx_device_t
*)data
;
1654 #if defined (ACX_MEM)
1656 length
= acxmem_proc_eeprom_output(buf
, adev
);
1657 acx_sem_unlock(adev
);
1661 length
= acxpci_proc_eeprom_output(buf
, adev
);
1662 acx_sem_unlock(adev
);
1667 if (length
<= offset
+ count
)
1669 *start
= buf
+ offset
;
1680 acx_e_read_proc_phy(char *buf
, char **start
, off_t offset
, int count
,
1681 int *eof
, void *data
)
1683 acx_device_t
*adev
= (acx_device_t
*)data
;
1690 length
= acx_s_proc_phy_output(buf
, adev
);
1691 acx_sem_unlock(adev
);
1694 if (length
<= offset
+ count
)
1696 *start
= buf
+ offset
;
1707 /***********************************************************************
1708 ** /proc files registration
1710 static const char * const
1711 proc_files
[] = { "", "_diag", "_eeprom", "_phy" };
1713 static read_proc_t
* const
1716 acx_e_read_proc_diag
,
1717 acx_e_read_proc_eeprom
,
1722 manage_proc_entries(const struct net_device
*ndev
, int remove
)
1724 acx_device_t
*adev
= ndev2adev((struct net_device
*)ndev
);
1728 for (i
= 0; i
< VEC_SIZE(proc_files
); i
++) {
1729 snprintf(procbuf
, sizeof(procbuf
),
1730 "driver/acx_%s%s", ndev
->name
, proc_files
[i
]);
1731 log(L_INIT
, "%sing /proc entry %s\n",
1732 remove
? "remov" : "creat", procbuf
);
1734 if (!create_proc_read_entry(procbuf
, 0, 0, proc_funcs
[i
], adev
)) {
1735 printk("acx: cannot register /proc entry %s\n", procbuf
);
1739 remove_proc_entry(procbuf
, NULL
);
1746 acx_proc_register_entries(const struct net_device
*ndev
)
1748 return manage_proc_entries(ndev
, 0);
1752 acx_proc_unregister_entries(const struct net_device
*ndev
)
1754 return manage_proc_entries(ndev
, 1);
1756 #endif /* CONFIG_PROC_FS */
1759 /***********************************************************************
1760 ** acx_cmd_join_bssid
1762 ** Common code for both acx100 and acx111.
1764 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1766 bitpos2genframe_txrate
[] = {
1767 10, /* 0. 1 Mbit/s */
1768 20, /* 1. 2 Mbit/s */
1769 55, /* 2. 5.5 Mbit/s */
1770 0x0B, /* 3. 6 Mbit/s */
1771 0x0F, /* 4. 9 Mbit/s */
1772 110, /* 5. 11 Mbit/s */
1773 0x0A, /* 6. 12 Mbit/s */
1774 0x0E, /* 7. 18 Mbit/s */
1775 220, /* 8. 22 Mbit/s */
1776 0x09, /* 9. 24 Mbit/s */
1777 0x0D, /* 10. 36 Mbit/s */
1778 0x08, /* 11. 48 Mbit/s */
1779 0x0C, /* 12. 54 Mbit/s */
1780 10, /* 13. 1 Mbit/s, should never happen */
1781 10, /* 14. 1 Mbit/s, should never happen */
1782 10, /* 15. 1 Mbit/s, should never happen */
1786 ** Actually, each one compiled into one AND and one SHIFT,
1787 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1788 static inline unsigned int
1789 rate111to5bits(unsigned int rate
)
1792 | ( (rate
& RATE111_11
) / (RATE111_11
/JOINBSS_RATES_11
) )
1793 | ( (rate
& RATE111_22
) / (RATE111_22
/JOINBSS_RATES_22
) )
1798 acx_s_cmd_join_bssid(acx_device_t
*adev
, const u8
*bssid
)
1804 if (mac_is_zero(bssid
))
1809 dtim_interval
= (ACX_MODE_0_ADHOC
== adev
->mode
) ?
1810 1 : adev
->dtim_interval
;
1812 memset(&tmp
, 0, sizeof(tmp
));
1814 for (i
= 0; i
< ETH_ALEN
; i
++) {
1815 tmp
.bssid
[i
] = bssid
[ETH_ALEN
-1 - i
];
1818 tmp
.beacon_interval
= cpu_to_le16(adev
->beacon_interval
);
1820 /* Basic rate set. Control frame responses (such as ACK or CTS frames)
1821 ** are sent with one of these rates */
1822 if (IS_ACX111(adev
)) {
1823 /* It was experimentally determined that rates_basic
1824 ** can take 11g rates as well, not only rates
1825 ** defined with JOINBSS_RATES_BASIC111_nnn.
1826 ** Just use RATE111_nnn constants... */
1827 tmp
.u
.acx111
.dtim_interval
= dtim_interval
;
1828 tmp
.u
.acx111
.rates_basic
= cpu_to_le16(adev
->rate_basic
);
1829 log(L_ASSOC
, "rates_basic:%04X, rates_supported:%04X\n",
1830 adev
->rate_basic
, adev
->rate_oper
);
1832 tmp
.u
.acx100
.dtim_interval
= dtim_interval
;
1833 tmp
.u
.acx100
.rates_basic
= rate111to5bits(adev
->rate_basic
);
1834 tmp
.u
.acx100
.rates_supported
= rate111to5bits(adev
->rate_oper
);
1835 log(L_ASSOC
, "rates_basic:%04X->%02X, "
1836 "rates_supported:%04X->%02X\n",
1837 adev
->rate_basic
, tmp
.u
.acx100
.rates_basic
,
1838 adev
->rate_oper
, tmp
.u
.acx100
.rates_supported
);
1841 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1842 ** will be sent (rate/modulation/preamble) */
1843 tmp
.u
.txrate
.genfrm_txrate
= bitpos2genframe_txrate
[lowest_bit(adev
->rate_basic
)];
1844 tmp
.genfrm_mod_pre
= 0; /* FIXME: was = adev->capab_short (which was always 0); */
1845 /* we can use short pre *if* all peers can understand it */
1846 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1848 /* we switch fw to STA mode in MONITOR mode, it seems to be
1849 ** the only mode where fw does not emit beacons by itself
1850 ** but allows us to send anything (we really want to retain
1851 ** ability to tx arbitrary frames in MONITOR mode)
1853 tmp
.macmode
= (adev
->mode
!= ACX_MODE_MONITOR
? adev
->mode
: ACX_MODE_2_STA
);
1854 tmp
.channel
= adev
->channel
;
1855 tmp
.essid_len
= adev
->essid_len
;
1856 /* NOTE: the code memcpy'd essid_len + 1 before, which is WRONG! */
1857 memcpy(tmp
.essid
, adev
->essid
, tmp
.essid_len
);
1858 acx_s_issue_cmd(adev
, ACX1xx_CMD_JOIN
, &tmp
, tmp
.essid_len
+ 0x10);
1860 log(L_ASSOC
|L_DEBUG
, "BSS_Type = %u\n", tmp
.macmode
);
1861 acxlog_mac(L_ASSOC
|L_DEBUG
, "JoinBSSID MAC:", adev
->bssid
, "\n");
1863 acx_update_capabilities(adev
);
1868 /***********************************************************************
1869 ** acx_s_cmd_start_scan
1871 ** Issue scan command to the hardware
1873 ** unified function for both ACX111 and ACX100
1876 acx_s_scan_chan(acx_device_t
*adev
)
1879 acx111_scan_t acx111
;
1880 acx100_scan_t acx100
;
1885 memset(&s
, 0, sizeof(s
));
1887 /* first common positions... */
1889 s
.acx111
.count
= cpu_to_le16(adev
->scan_count
);
1890 s
.acx111
.rate
= adev
->scan_rate
;
1891 s
.acx111
.options
= adev
->scan_mode
;
1892 s
.acx111
.chan_duration
= cpu_to_le16(adev
->scan_duration
);
1893 s
.acx111
.max_probe_delay
= cpu_to_le16(adev
->scan_probe_delay
);
1895 /* ...then differences */
1897 if (IS_ACX111(adev
)) {
1898 s
.acx111
.channel_list_select
= 0; /* scan every allowed channel */
1899 /*s.acx111.channel_list_select = 1;*/ /* scan given channels */
1900 /*s.acx111.modulation = 0x40;*/ /* long preamble? OFDM? -> only for active scan */
1901 s
.acx111
.modulation
= 0;
1902 /*s.acx111.channel_list[0] = 6;
1903 s.acx111.channel_list[1] = 4;*/
1905 s
.acx100
.start_chan
= cpu_to_le16(1);
1906 s
.acx100
.flags
= cpu_to_le16(0x8000);
1909 acx_s_issue_cmd(adev
, ACX1xx_CMD_SCAN
, &s
, sizeof(s
));
1915 acx_s_cmd_start_scan(acx_device_t
*adev
)
1917 /* time_before check is 'just in case' thing */
1918 if (!(adev
->irq_status
& HOST_INT_SCAN_COMPLETE
)
1919 && time_before(jiffies
, adev
->scan_start
+ 10*HZ
)
1921 log(L_INIT
, "start_scan: seems like previous scan "
1922 "is still running. Not starting anew. Please report\n");
1926 log(L_INIT
, "starting radio scan\n");
1927 /* remember that fw is commanded to do scan */
1928 adev
->scan_start
= jiffies
;
1929 CLEAR_BIT(adev
->irq_status
, HOST_INT_SCAN_COMPLETE
);
1931 acx_s_scan_chan(adev
);
1935 /***********************************************************************
1936 ** acx111 feature config
1939 acx111_s_get_feature_config(acx_device_t
*adev
,
1940 u32
*feature_options
, u32
*data_flow_options
)
1942 struct acx111_ie_feature_config feat
;
1944 if (!IS_ACX111(adev
)) {
1948 memset(&feat
, 0, sizeof(feat
));
1950 if (OK
!= acx_s_interrogate(adev
, &feat
, ACX1xx_IE_FEATURE_CONFIG
)) {
1954 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1955 feat
.feature_options
,
1956 feat
.data_flow_options
);
1958 if (feature_options
)
1959 *feature_options
= le32_to_cpu(feat
.feature_options
);
1960 if (data_flow_options
)
1961 *data_flow_options
= le32_to_cpu(feat
.data_flow_options
);
1967 acx111_s_set_feature_config(acx_device_t
*adev
,
1968 u32 feature_options
, u32 data_flow_options
,
1969 unsigned int mode
/* 0 == remove, 1 == add, 2 == set */)
1971 struct acx111_ie_feature_config feat
;
1973 if (!IS_ACX111(adev
)) {
1977 if ((mode
< 0) || (mode
> 2))
1981 /* need to modify old data */
1982 acx111_s_get_feature_config(adev
, &feat
.feature_options
, &feat
.data_flow_options
);
1984 /* need to set a completely new value */
1985 feat
.feature_options
= 0;
1986 feat
.data_flow_options
= 0;
1989 if (mode
== 0) { /* remove */
1990 CLEAR_BIT(feat
.feature_options
, cpu_to_le32(feature_options
));
1991 CLEAR_BIT(feat
.data_flow_options
, cpu_to_le32(data_flow_options
));
1992 } else { /* add or set */
1993 SET_BIT(feat
.feature_options
, cpu_to_le32(feature_options
));
1994 SET_BIT(feat
.data_flow_options
, cpu_to_le32(data_flow_options
));
1998 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1999 "new: feature 0x%08X dataflow 0x%08X\n",
2000 feature_options
, data_flow_options
, mode
,
2001 le32_to_cpu(feat
.feature_options
),
2002 le32_to_cpu(feat
.data_flow_options
));
2004 if (OK
!= acx_s_configure(adev
, &feat
, ACX1xx_IE_FEATURE_CONFIG
)) {
2012 acx111_s_feature_off(acx_device_t
*adev
, u32 f
, u32 d
)
2014 return acx111_s_set_feature_config(adev
, f
, d
, 0);
2017 acx111_s_feature_on(acx_device_t
*adev
, u32 f
, u32 d
)
2019 return acx111_s_set_feature_config(adev
, f
, d
, 1);
2022 acx111_s_feature_set(acx_device_t
*adev
, u32 f
, u32 d
)
2024 return acx111_s_set_feature_config(adev
, f
, d
, 2);
2028 /***********************************************************************
2029 ** acx100_s_init_memory_pools
2032 acx100_s_init_memory_pools(acx_device_t
*adev
, const acx_ie_memmap_t
*mmt
)
2034 acx100_ie_memblocksize_t MemoryBlockSize
;
2035 acx100_ie_memconfigoption_t MemoryConfigOption
;
2036 int TotalMemoryBlocks
;
2038 int TotalRxBlockSize
;
2040 int TotalTxBlockSize
;
2044 /* Let's see if we can follow this:
2045 first we select our memory block size (which I think is
2046 completely arbitrary) */
2047 MemoryBlockSize
.size
= cpu_to_le16(adev
->memblocksize
);
2049 /* Then we alert the card to our decision of block size */
2050 if (OK
!= acx_s_configure(adev
, &MemoryBlockSize
, ACX100_IE_BLOCK_SIZE
)) {
2054 /* We figure out how many total blocks we can create, using
2055 the block size we chose, and the beginning and ending
2056 memory pointers, i.e.: end-start/size */
2057 TotalMemoryBlocks
= (le32_to_cpu(mmt
->PoolEnd
) - le32_to_cpu(mmt
->PoolStart
)) / adev
->memblocksize
;
2059 log(L_DEBUG
, "TotalMemoryBlocks=%u (%u bytes)\n",
2060 TotalMemoryBlocks
, TotalMemoryBlocks
*adev
->memblocksize
);
2062 /* MemoryConfigOption.DMA_config bitmask:
2063 access to ACX memory is to be done:
2064 0x00080000 using PCI conf space?!
2065 0x00040000 using IO instructions?
2066 0x00000000 using memory access instructions
2067 0x00020000 using local memory block linked list (else what?)
2068 0x00010000 using host indirect descriptors (else host must access ACX memory?)
2070 #if defined (ACX_MEM)
2072 * ACX ignores DMA_config for generic slave mode.
2074 MemoryConfigOption
.DMA_config
= 0;
2075 /* Declare start of the Rx host pool */
2076 MemoryConfigOption
.pRxHostDesc
= cpu2acx(0);
2077 log(L_DEBUG
, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
2078 acx2cpu(MemoryConfigOption
.pRxHostDesc
),
2079 (long)adev
->rxhostdesc_startphy
);
2082 MemoryConfigOption
.DMA_config
= cpu_to_le32(0x30000);
2083 /* Declare start of the Rx host pool */
2084 MemoryConfigOption
.pRxHostDesc
= cpu2acx(adev
->rxhostdesc_startphy
);
2085 log(L_DEBUG
, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
2086 acx2cpu(MemoryConfigOption
.pRxHostDesc
),
2087 (long)adev
->rxhostdesc_startphy
);
2089 MemoryConfigOption
.DMA_config
= cpu_to_le32(0x20000);
2093 /* 50% of the allotment of memory blocks go to tx descriptors */
2094 TxBlockNum
= TotalMemoryBlocks
/ 2;
2095 MemoryConfigOption
.TxBlockNum
= cpu_to_le16(TxBlockNum
);
2097 /* and 50% go to the rx descriptors */
2098 RxBlockNum
= TotalMemoryBlocks
- TxBlockNum
;
2099 MemoryConfigOption
.RxBlockNum
= cpu_to_le16(RxBlockNum
);
2101 /* size of the tx and rx descriptor queues */
2102 TotalTxBlockSize
= TxBlockNum
* adev
->memblocksize
;
2103 TotalRxBlockSize
= RxBlockNum
* adev
->memblocksize
;
2104 log(L_DEBUG
, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u "
2105 "TotalRxBlockSize %u\n", TxBlockNum
, RxBlockNum
,
2106 TotalTxBlockSize
, TotalRxBlockSize
);
2109 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
2110 MemoryConfigOption
.rx_mem
=
2111 cpu_to_le32((le32_to_cpu(mmt
->PoolStart
) + 0x1f) & ~0x1f);
2113 /* align the rx descriptor queue to units of 0x20
2114 * and offset it by the tx descriptor queue */
2115 MemoryConfigOption
.tx_mem
=
2116 cpu_to_le32((le32_to_cpu(mmt
->PoolStart
) + TotalRxBlockSize
+ 0x1f) & ~0x1f);
2117 log(L_DEBUG
, "tx_mem %08X rx_mem %08X\n",
2118 MemoryConfigOption
.tx_mem
, MemoryConfigOption
.rx_mem
);
2120 /* alert the device to our decision */
2121 if (OK
!= acx_s_configure(adev
, &MemoryConfigOption
, ACX1xx_IE_MEMORY_CONFIG_OPTIONS
)) {
2125 /* and tell the device to kick it into gear */
2126 if (OK
!= acx_s_issue_cmd(adev
, ACX100_CMD_INIT_MEMORY
, NULL
, 0)) {
2131 * slave memory interface has to manage the transmit pools for the ACX,
2132 * so it needs to know what we chose here.
2134 adev
->acx_txbuf_start
= MemoryConfigOption
.tx_mem
;
2135 adev
->acx_txbuf_numblocks
= MemoryConfigOption
.TxBlockNum
;
2146 /***********************************************************************
2147 ** acx100_s_create_dma_regions
2149 ** Note that this fn messes up heavily with hardware, but we cannot
2150 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2153 acx100_s_create_dma_regions(acx_device_t
*adev
)
2155 acx100_ie_queueconfig_t queueconf
;
2156 acx_ie_memmap_t memmap
;
2158 u32 tx_queue_start
, rx_queue_start
;
2162 /* read out the acx100 physical start address for the queues */
2163 if (OK
!= acx_s_interrogate(adev
, &memmap
, ACX1xx_IE_MEMORY_MAP
)) {
2167 tx_queue_start
= le32_to_cpu(memmap
.QueueStart
);
2168 rx_queue_start
= tx_queue_start
+ TX_CNT
* sizeof(txdesc_t
);
2170 log(L_DEBUG
, "initializing Queue Indicator\n");
2172 memset(&queueconf
, 0, sizeof(queueconf
));
2174 /* Not needed for PCI or slave memory, so we can avoid setting them altogether */
2176 queueconf
.NumTxDesc
= USB_TX_CNT
;
2177 queueconf
.NumRxDesc
= USB_RX_CNT
;
2180 /* calculate size of queues */
2181 queueconf
.AreaSize
= cpu_to_le32(
2182 TX_CNT
* sizeof(txdesc_t
) +
2183 RX_CNT
* sizeof(rxdesc_t
) + 8
2185 queueconf
.NumTxQueues
= 1; /* number of tx queues */
2186 /* sets the beginning of the tx descriptor queue */
2187 queueconf
.TxQueueStart
= memmap
.QueueStart
;
2188 /* done by memset: queueconf.TxQueuePri = 0; */
2189 queueconf
.RxQueueStart
= cpu_to_le32(rx_queue_start
);
2190 queueconf
.QueueOptions
= 1; /* auto reset descriptor */
2191 /* sets the end of the rx descriptor queue */
2192 queueconf
.QueueEnd
= cpu_to_le32(
2193 rx_queue_start
+ RX_CNT
* sizeof(rxdesc_t
)
2196 /* sets the beginning of the next queue */
2197 queueconf
.HostQueueEnd
=
2198 cpu_to_le32(le32_to_cpu(queueconf
.QueueEnd
) + sizeof (queueindicator_t
));
2199 if (OK
!= acx_s_configure(adev
, &queueconf
, ACX1xx_IE_QUEUE_CONFIG
)) {
2203 #if defined (ACX_MEM)
2204 /* sets the beginning of the rx descriptor queue, after the tx descrs */
2205 adev
->acx_queue_indicator
=
2206 (queueindicator_t
*) le32_to_cpu (queueconf
.QueueEnd
);
2207 if (OK
!= acxmem_s_create_hostdesc_queues(adev
))
2210 acxmem_create_desc_queues(adev
, tx_queue_start
, rx_queue_start
);
2213 /* sets the beginning of the rx descriptor queue, after the tx descrs */
2214 if (OK
!= acxpci_s_create_hostdesc_queues(adev
))
2216 acxpci_create_desc_queues(adev
, tx_queue_start
, rx_queue_start
);
2220 if (OK
!= acx_s_interrogate(adev
, &memmap
, ACX1xx_IE_MEMORY_MAP
)) {
2225 * Have to make sure we skip past the Queue Indicator (QueueEnd) and Host Queue Indicator
2226 * maps, each of which are 8 bytes and follow immediately after the transmit and
2229 memmap
.PoolStart
= cpu_to_le32(
2230 (le32_to_cpu(memmap
.QueueEnd
) +
2231 2*sizeof(queueindicator_t
) + 0x1f) & ~0x1f
2234 if (OK
!= acx_s_configure(adev
, &memmap
, ACX1xx_IE_MEMORY_MAP
)) {
2238 if (OK
!= acx100_s_init_memory_pools(adev
, &memmap
)) {
2246 acx_s_msleep(1000); /* ? */
2247 #if defined (ACX_MEM)
2248 acxmem_free_desc_queues(adev
);
2251 acxpci_free_desc_queues(adev
);
2259 /***********************************************************************
2260 ** acx111_s_create_dma_regions
2262 ** Note that this fn messes heavily with hardware, but we cannot
2263 ** lock it (we need to sleep). Not a problem since IRQs can't happen
2265 #define ACX111_PERCENT(percent) ((percent)/5)
2268 acx111_s_create_dma_regions(acx_device_t
*adev
)
2270 struct acx111_ie_memoryconfig memconf
;
2271 struct acx111_ie_queueconfig queueconf
;
2272 u32 tx_queue_start
, rx_queue_start
;
2276 /* Calculate memory positions and queue sizes */
2278 /* Set up our host descriptor pool + data pool */
2279 #if defined (ACX_MEM)
2280 if (OK
!= acxmem_s_create_hostdesc_queues(adev
))
2284 if (OK
!= acxpci_s_create_hostdesc_queues(adev
))
2289 memset(&memconf
, 0, sizeof(memconf
));
2290 /* the number of STAs (STA contexts) to support
2291 ** NB: was set to 1 and everything seemed to work nevertheless... */
2292 memconf
.no_of_stations
= cpu_to_le16(VEC_SIZE(adev
->sta_list
));
2293 /* specify the memory block size. Default is 256 */
2294 memconf
.memory_block_size
= cpu_to_le16(adev
->memblocksize
);
2295 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
2296 memconf
.tx_rx_memory_block_allocation
= ACX111_PERCENT(50);
2297 /* set the count of our queues
2298 ** NB: struct acx111_ie_memoryconfig shall be modified
2299 ** if we ever will switch to more than one rx and/or tx queue */
2300 memconf
.count_rx_queues
= 1;
2301 memconf
.count_tx_queues
= 1;
2302 /* 0 == Busmaster Indirect Memory Organization, which is what we want
2303 * (using linked host descs with their allocated mem).
2304 * 2 == Generic Bus Slave */
2305 /* done by memset: memconf.options = 0; */
2306 /* let's use 25% for fragmentations and 75% for frame transfers
2307 * (specified in units of 5%) */
2308 memconf
.fragmentation
= ACX111_PERCENT(75);
2309 /* Rx descriptor queue config */
2310 memconf
.rx_queue1_count_descs
= RX_CNT
;
2311 memconf
.rx_queue1_type
= 7; /* must be set to 7 */
2312 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
2313 #if defined (ACX_MEM)
2314 memconf
.rx_queue1_host_rx_start
= cpu2acx(adev
->rxhostdesc_startphy
);
2317 memconf
.rx_queue1_host_rx_start
= cpu2acx(adev
->rxhostdesc_startphy
);
2320 /* Tx descriptor queue config */
2321 memconf
.tx_queue1_count_descs
= TX_CNT
;
2322 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
2324 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
2325 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
2326 ** But it is actually correct wrt IE numbers.
2327 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
2328 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
2329 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
2330 if (OK
!= acx_s_configure(adev
, &memconf
, ACX1xx_IE_QUEUE_CONFIG
)) {
2334 acx_s_interrogate(adev
, &queueconf
, ACX1xx_IE_MEMORY_CONFIG_OPTIONS
);
2336 tx_queue_start
= le32_to_cpu(queueconf
.tx1_queue_address
);
2337 rx_queue_start
= le32_to_cpu(queueconf
.rx1_queue_address
);
2339 log(L_INIT
, "dump queue head (from card):\n"
2341 "tx_memory_block_address: %X\n"
2342 "rx_memory_block_address: %X\n"
2343 "tx1_queue address: %X\n"
2344 "rx1_queue address: %X\n",
2345 le16_to_cpu(queueconf
.len
),
2346 le32_to_cpu(queueconf
.tx_memory_block_address
),
2347 le32_to_cpu(queueconf
.rx_memory_block_address
),
2351 #if defined (ACX_MEM)
2352 acxmem_create_desc_queues(adev
, tx_queue_start
, rx_queue_start
);
2355 acxpci_create_desc_queues(adev
, tx_queue_start
, rx_queue_start
);
2361 #if defined (ACX_MEM)
2362 acxmem_free_desc_queues(adev
);
2365 acxpci_free_desc_queues(adev
);
2373 /***********************************************************************
2376 acx_s_initialize_rx_config(acx_device_t
*adev
)
2385 switch (adev
->mode
) {
2387 adev
->rx_config_1
= (u16
) (0
2388 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2389 /* | RX_CFG1_FILTER_SSID */
2390 /* | RX_CFG1_FILTER_BCAST */
2391 /* | RX_CFG1_RCV_MC_ADDR1 */
2392 /* | RX_CFG1_RCV_MC_ADDR0 */
2393 /* | RX_CFG1_FILTER_ALL_MULTI */
2394 /* | RX_CFG1_FILTER_BSSID */
2395 /* | RX_CFG1_FILTER_MAC */
2396 /* | RX_CFG1_RCV_PROMISCUOUS */
2397 /* | RX_CFG1_INCLUDE_FCS */
2398 /* | RX_CFG1_INCLUDE_PHY_HDR */
2400 adev
->rx_config_2
= (u16
) (0
2401 /*| RX_CFG2_RCV_ASSOC_REQ */
2402 /*| RX_CFG2_RCV_AUTH_FRAMES */
2403 /*| RX_CFG2_RCV_BEACON_FRAMES */
2404 /*| RX_CFG2_RCV_CONTENTION_FREE */
2405 /*| RX_CFG2_RCV_CTRL_FRAMES */
2406 /*| RX_CFG2_RCV_DATA_FRAMES */
2407 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2408 /*| RX_CFG2_RCV_MGMT_FRAMES */
2409 /*| RX_CFG2_RCV_PROBE_REQ */
2410 /*| RX_CFG2_RCV_PROBE_RESP */
2411 /*| RX_CFG2_RCV_ACK_FRAMES */
2412 /*| RX_CFG2_RCV_OTHER */
2415 case ACX_MODE_MONITOR
:
2416 adev
->rx_config_1
= (u16
) (0
2417 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2418 /* | RX_CFG1_FILTER_SSID */
2419 /* | RX_CFG1_FILTER_BCAST */
2420 /* | RX_CFG1_RCV_MC_ADDR1 */
2421 /* | RX_CFG1_RCV_MC_ADDR0 */
2422 /* | RX_CFG1_FILTER_ALL_MULTI */
2423 /* | RX_CFG1_FILTER_BSSID */
2424 /* | RX_CFG1_FILTER_MAC */
2425 | RX_CFG1_RCV_PROMISCUOUS
2426 /* | RX_CFG1_INCLUDE_FCS */
2427 /* | RX_CFG1_INCLUDE_PHY_HDR */
2429 adev
->rx_config_2
= (u16
) (0
2430 | RX_CFG2_RCV_ASSOC_REQ
2431 | RX_CFG2_RCV_AUTH_FRAMES
2432 | RX_CFG2_RCV_BEACON_FRAMES
2433 | RX_CFG2_RCV_CONTENTION_FREE
2434 | RX_CFG2_RCV_CTRL_FRAMES
2435 | RX_CFG2_RCV_DATA_FRAMES
2436 | RX_CFG2_RCV_BROKEN_FRAMES
2437 | RX_CFG2_RCV_MGMT_FRAMES
2438 | RX_CFG2_RCV_PROBE_REQ
2439 | RX_CFG2_RCV_PROBE_RESP
2440 | RX_CFG2_RCV_ACK_FRAMES
2445 adev
->rx_config_1
= (u16
) (0
2446 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
2447 /* | RX_CFG1_FILTER_SSID */
2448 /* | RX_CFG1_FILTER_BCAST */
2449 /* | RX_CFG1_RCV_MC_ADDR1 */
2450 /* | RX_CFG1_RCV_MC_ADDR0 */
2451 /* | RX_CFG1_FILTER_ALL_MULTI */
2452 /* | RX_CFG1_FILTER_BSSID */
2453 | RX_CFG1_FILTER_MAC
2454 /* | RX_CFG1_RCV_PROMISCUOUS */
2455 /* | RX_CFG1_INCLUDE_FCS */
2456 /* | RX_CFG1_INCLUDE_PHY_HDR */
2458 adev
->rx_config_2
= (u16
) (0
2459 | RX_CFG2_RCV_ASSOC_REQ
2460 | RX_CFG2_RCV_AUTH_FRAMES
2461 | RX_CFG2_RCV_BEACON_FRAMES
2462 | RX_CFG2_RCV_CONTENTION_FREE
2463 | RX_CFG2_RCV_CTRL_FRAMES
2464 | RX_CFG2_RCV_DATA_FRAMES
2465 /*| RX_CFG2_RCV_BROKEN_FRAMES */
2466 | RX_CFG2_RCV_MGMT_FRAMES
2467 | RX_CFG2_RCV_PROBE_REQ
2468 | RX_CFG2_RCV_PROBE_RESP
2469 /*| RX_CFG2_RCV_ACK_FRAMES */
2474 adev
->rx_config_1
|= RX_CFG1_INCLUDE_RXBUF_HDR
;
2476 if ((adev
->rx_config_1
& RX_CFG1_INCLUDE_PHY_HDR
)
2477 || (adev
->firmware_numver
>= 0x02000000))
2478 adev
->phy_header_len
= IS_ACX111(adev
) ? 8 : 4;
2480 adev
->phy_header_len
= 0;
2482 log(L_INIT
, "setting RXconfig to %04X:%04X\n",
2483 adev
->rx_config_1
, adev
->rx_config_2
);
2484 cfg
.rx_cfg1
= cpu_to_le16(adev
->rx_config_1
);
2485 cfg
.rx_cfg2
= cpu_to_le16(adev
->rx_config_2
);
2486 acx_s_configure(adev
, &cfg
, ACX1xx_IE_RXCONFIG
);
2490 /***********************************************************************
2491 ** acx_s_set_defaults
2494 acx_s_set_defaults(acx_device_t
*adev
)
2496 unsigned long flags
;
2500 /* do it before getting settings, prevent bogus channel 0 warning */
2503 /* query some settings from the card.
2504 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
2505 * query is REQUIRED, otherwise the card won't work correctly! */
2506 adev
->get_mask
= GETSET_ANTENNA
|GETSET_SENSITIVITY
|GETSET_STATION_ID
|GETSET_REG_DOMAIN
;
2507 /* Only ACX100 supports ED and CCA */
2508 if (IS_ACX100(adev
))
2509 adev
->get_mask
|= GETSET_CCA
|GETSET_ED_THRESH
;
2511 acx_s_update_card_settings(adev
);
2513 acx_lock(adev
, flags
);
2515 /* set our global interrupt mask */
2516 #if defined (ACX_MEM)
2517 acxmem_set_interrupt_mask(adev
);
2520 acxpci_set_interrupt_mask(adev
);
2523 adev
->led_power
= 1; /* LED is active on startup */
2524 adev
->brange_max_quality
= 60; /* LED blink max quality is 60 */
2525 adev
->brange_time_last_state_change
= jiffies
;
2527 /* copy the MAC address we just got from the card
2528 * into our MAC address used during current 802.11 session */
2529 MAC_COPY(adev
->dev_addr
, adev
->ndev
->dev_addr
);
2530 MAC_BCAST(adev
->ap
);
2533 snprintf(adev
->essid
, sizeof(adev
->essid
), "STA%02X%02X%02X",
2534 adev
->dev_addr
[3], adev
->dev_addr
[4], adev
->dev_addr
[5]);
2535 adev
->essid_active
= 1;
2537 /* we have a nick field to waste, so why not abuse it
2538 * to announce the driver version? ;-) */
2539 strncpy(adev
->nick
, "acx " ACX_RELEASE
, IW_ESSID_MAX_SIZE
);
2541 #if defined (ACX_MEM)
2542 adev
->reg_dom_id
= adev
->cfgopt_domains
.list
[0];
2544 if (IS_PCI(adev
)) { /* FIXME: this should be made to apply to USB, too! */
2545 /* first regulatory domain entry in EEPROM == default reg. domain */
2546 adev
->reg_dom_id
= adev
->cfgopt_domains
.list
[0];
2550 /* 0xffff would be better, but then we won't get a "scan complete"
2551 * interrupt, so our current infrastructure will fail: */
2552 adev
->scan_count
= 1;
2553 adev
->scan_mode
= ACX_SCAN_OPT_ACTIVE
;
2554 adev
->scan_duration
= 100;
2555 adev
->scan_probe_delay
= 200;
2556 /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
2557 adev
->scan_rate
= ACX_SCAN_RATE_1
;
2559 adev
->mode
= ACX_MODE_2_STA
;
2560 adev
->auth_alg
= WLAN_AUTH_ALG_OPENSYSTEM
;
2561 adev
->listen_interval
= 100;
2562 adev
->beacon_interval
= DEFAULT_BEACON_INTERVAL
;
2563 adev
->dtim_interval
= DEFAULT_DTIM_INTERVAL
;
2565 adev
->msdu_lifetime
= DEFAULT_MSDU_LIFETIME
;
2567 adev
->rts_threshold
= DEFAULT_RTS_THRESHOLD
;
2568 adev
->frag_threshold
= 2346;
2570 /* use standard default values for retry limits */
2571 adev
->short_retry
= 7; /* max. retries for (short) non-RTS packets */
2572 adev
->long_retry
= 4; /* max. retries for long (RTS) packets */
2574 adev
->preamble_mode
= 2; /* auto */
2575 adev
->fallback_threshold
= 3;
2576 adev
->stepup_threshold
= 10;
2577 adev
->rate_bcast
= RATE111_1
;
2578 adev
->rate_bcast100
= RATE100_1
;
2579 adev
->rate_basic
= RATE111_1
| RATE111_2
;
2580 adev
->rate_auto
= 1;
2581 if (IS_ACX111(adev
)) {
2582 adev
->rate_oper
= RATE111_ALL
;
2584 adev
->rate_oper
= RATE111_ACX100_COMPAT
;
2587 /* Supported Rates element - the rates here are given in units of
2588 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
2589 acx_l_update_ratevector(adev
);
2591 /* set some more defaults */
2592 if (IS_ACX111(adev
)) {
2593 /* 30mW (15dBm) is default, at least in my acx111 card: */
2594 adev
->tx_level_dbm
= 15;
2596 /* don't use max. level, since it might be dangerous
2597 * (e.g. WRT54G people experience
2598 * excessive Tx power damage!) */
2599 adev
->tx_level_dbm
= 18;
2601 /* adev->tx_level_auto = 1; */
2602 if (IS_ACX111(adev
)) {
2603 /* start with sensitivity level 1 out of 3: */
2604 adev
->sensitivity
= 1;
2607 /* #define ENABLE_POWER_SAVE */
2608 #ifdef ENABLE_POWER_SAVE
2609 adev
->ps_wakeup_cfg
= PS_CFG_ENABLE
| PS_CFG_WAKEUP_ALL_BEAC
;
2610 adev
->ps_listen_interval
= 1;
2611 adev
->ps_options
= PS_OPT_ENA_ENHANCED_PS
| PS_OPT_TX_PSPOLL
| PS_OPT_STILL_RCV_BCASTS
;
2612 adev
->ps_hangover_period
= 30;
2613 adev
->ps_enhanced_transition_time
= 0;
2615 adev
->ps_wakeup_cfg
= 0;
2616 adev
->ps_listen_interval
= 0;
2617 adev
->ps_options
= 0;
2618 adev
->ps_hangover_period
= 0;
2619 adev
->ps_enhanced_transition_time
= 0;
2622 /* These settings will be set in fw on ifup */
2626 /* configure card to do rate fallback when in auto rate mode */
2630 /* better re-init the antenna value we got above */
2632 #if POWER_SAVE_80211
2633 | GETSET_POWER_80211
2637 acx_unlock(adev
, flags
);
2638 acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
2640 acx_s_initialize_rx_config(adev
);
2646 /***********************************************************************
2647 ** FIXME: this should be solved in a general way for all radio types
2648 ** by decoding the radio firmware module,
2649 ** since it probably has some standard structure describing how to
2650 ** set the power level of the radio module which it controls.
2651 ** Or maybe not, since the radio module probably has a function interface
2652 ** instead which then manages Tx level programming :-\
2655 acx111_s_set_tx_level(acx_device_t
*adev
, u8 level_dbm
)
2657 struct acx111_ie_tx_level tx_level
;
2659 /* my acx111 card has two power levels in its configoptions (== EEPROM):
2662 * For now, just assume all other acx111 cards have the same.
2663 * FIXME: Ideally we would query it here, but we first need a
2664 * standard way to query individual configoptions easily.
2665 * Well, now we have proper cfgopt txpower variables, but this still
2666 * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
2667 if (level_dbm
<= 12) {
2668 tx_level
.level
= 2; /* 10 dBm */
2669 adev
->tx_level_dbm
= 10;
2671 tx_level
.level
= 1; /* 15 dBm */
2672 adev
->tx_level_dbm
= 15;
2674 if (level_dbm
!= adev
->tx_level_dbm
)
2675 log(L_INIT
, "acx111 firmware has specific "
2676 "power levels only: adjusted %d dBm to %d dBm!\n",
2677 level_dbm
, adev
->tx_level_dbm
);
2679 return acx_s_configure(adev
, &tx_level
, ACX1xx_IE_DOT11_TX_POWER_LEVEL
);
2683 acx_s_set_tx_level(acx_device_t
*adev
, u8 level_dbm
)
2685 if (IS_ACX111(adev
)) {
2686 return acx111_s_set_tx_level(adev
, level_dbm
);
2688 #if defined (ACX_MEM)
2689 return acx100mem_s_set_tx_level(adev
, level_dbm
);
2692 return acx100pci_s_set_tx_level(adev
, level_dbm
);
2699 /***********************************************************************
2702 /* Returns the current tx level (ACX111) */
2704 acx111_s_get_tx_level(acx_device_t
*adev
)
2706 struct acx111_ie_tx_level tx_level
;
2709 acx_s_interrogate(adev
, &tx_level
, ACX1xx_IE_DOT11_TX_POWER_LEVEL
);
2710 return tx_level
.level
;
2715 /***********************************************************************
2717 ** Called from IRQ context only
2720 acx_l_rxmonitor(acx_device_t
*adev
, const rxbuffer_t
*rxbuf
)
2723 struct sk_buff
*skb
;
2725 unsigned int skb_len
;
2730 /* we are in big luck: the acx100 doesn't modify any of the fields */
2731 /* in the 802.11 frame. just pass this packet into the PF_PACKET */
2732 /* subsystem. yeah. */
2733 payload_offset
= ((u8
*)acx_get_wlan_hdr(adev
, rxbuf
) - (u8
*)rxbuf
);
2734 skb_len
= RXBUF_BYTES_USED(rxbuf
) - payload_offset
;
2737 if (unlikely(skb_len
> WLAN_A4FR_MAXLEN_WEP
)) {
2738 printk("%s: monitor mode panic: oversized frame!\n",
2743 if (adev
->ndev
->type
== ARPHRD_IEEE80211_PRISM
)
2744 skb_len
+= sizeof(*msg
);
2747 skb
= dev_alloc_skb(skb_len
);
2748 if (unlikely(!skb
)) {
2749 printk("%s: no memory for skb (%u bytes)\n",
2750 adev
->ndev
->name
, skb_len
);
2754 skb_put(skb
, skb_len
);
2756 if (adev
->ndev
->type
== ARPHRD_IEEE80211
) {
2757 /* when in raw 802.11 mode, just copy frame as-is */
2759 } else if (adev
->ndev
->type
== ARPHRD_IEEE80211_PRISM
) {
2760 /* emulate prism header */
2761 msg
= (wlansniffrm_t
*)skb
->data
;
2764 msg
->msgcode
= WLANSNIFFFRM
;
2765 msg
->msglen
= sizeof(*msg
);
2766 strncpy(msg
->devname
, adev
->ndev
->name
, sizeof(msg
->devname
)-1);
2767 msg
->devname
[sizeof(msg
->devname
)-1] = '\0';
2769 msg
->hosttime
.did
= WLANSNIFFFRM_hosttime
;
2770 msg
->hosttime
.status
= WLANITEM_STATUS_data_ok
;
2771 msg
->hosttime
.len
= 4;
2772 msg
->hosttime
.data
= jiffies
;
2774 msg
->mactime
.did
= WLANSNIFFFRM_mactime
;
2775 msg
->mactime
.status
= WLANITEM_STATUS_data_ok
;
2776 msg
->mactime
.len
= 4;
2777 msg
->mactime
.data
= rxbuf
->time
;
2779 msg
->channel
.did
= WLANSNIFFFRM_channel
;
2780 msg
->channel
.status
= WLANITEM_STATUS_data_ok
;
2781 msg
->channel
.len
= 4;
2782 msg
->channel
.data
= adev
->channel
;
2784 msg
->rssi
.did
= WLANSNIFFFRM_rssi
;
2785 msg
->rssi
.status
= WLANITEM_STATUS_no_value
;
2789 msg
->sq
.did
= WLANSNIFFFRM_sq
;
2790 msg
->sq
.status
= WLANITEM_STATUS_no_value
;
2794 msg
->signal
.did
= WLANSNIFFFRM_signal
;
2795 msg
->signal
.status
= WLANITEM_STATUS_data_ok
;
2796 msg
->signal
.len
= 4;
2797 msg
->signal
.data
= rxbuf
->phy_snr
;
2799 msg
->noise
.did
= WLANSNIFFFRM_noise
;
2800 msg
->noise
.status
= WLANITEM_STATUS_data_ok
;
2802 msg
->noise
.data
= rxbuf
->phy_level
;
2804 msg
->rate
.did
= WLANSNIFFFRM_rate
;
2805 msg
->rate
.status
= WLANITEM_STATUS_data_ok
;
2807 msg
->rate
.data
= rxbuf
->phy_plcp_signal
/ 5;
2809 msg
->istx
.did
= WLANSNIFFFRM_istx
;
2810 msg
->istx
.status
= WLANITEM_STATUS_data_ok
;
2812 msg
->istx
.data
= 0; /* tx=0: it's not a tx packet */
2814 skb_len
-= sizeof(*msg
);
2816 msg
->frmlen
.did
= WLANSNIFFFRM_signal
;
2817 msg
->frmlen
.status
= WLANITEM_STATUS_data_ok
;
2818 msg
->frmlen
.len
= 4;
2819 msg
->frmlen
.data
= skb_len
;
2821 printk("acx: unsupported netdev type %d!\n", adev
->ndev
->type
);
2826 /* sanity check (keep it here) */
2827 if (unlikely((int)skb_len
< 0)) {
2828 printk("acx: skb_len=%d. Driver bug, please report\n", (int)skb_len
);
2832 memcpy(datap
, ((unsigned char*)rxbuf
)+payload_offset
, skb_len
);
2834 skb
->dev
= adev
->ndev
;
2835 skb
->dev
->last_rx
= jiffies
;
2837 skb
->mac
.raw
= skb
->data
;
2838 skb
->ip_summed
= CHECKSUM_NONE
;
2839 skb
->pkt_type
= PACKET_OTHERHOST
;
2840 skb
->protocol
= htons(ETH_P_80211_RAW
);
2843 adev
->stats
.rx_packets
++;
2844 adev
->stats
.rx_bytes
+= skb
->len
;
2851 /***********************************************************************
2852 ** acx_l_rx_ieee802_11_frame
2854 ** Called from IRQ context only
2857 /* All these contortions are for saner dup logging
2859 ** We want: (a) to know about excessive dups
2860 ** (b) to not spam kernel log about occasional dups
2862 ** 1/64 threshold was chosen by running "ping -A"
2863 ** It gave "rx: 59 DUPs in 2878 packets" only with 4 parallel
2864 ** "ping -A" streams running. */
2865 /* 2005-10-11: bumped up to 1/8
2866 ** subtract a $smallint from dup_count in order to
2867 ** avoid "2 DUPs in 19 packets" messages */
2869 acx_l_handle_dup(acx_device_t
*adev
, u16 seq
)
2871 if (adev
->dup_count
) {
2872 adev
->nondup_count
++;
2873 if (time_after(jiffies
, adev
->dup_msg_expiry
)) {
2874 /* Log only if more than 1 dup in 64 packets */
2875 if (adev
->nondup_count
/8 < adev
->dup_count
-5) {
2876 printk(KERN_INFO
"%s: rx: %d DUPs in "
2877 "%d packets received in 10 secs\n",
2880 adev
->nondup_count
);
2882 adev
->dup_count
= 0;
2883 adev
->nondup_count
= 0;
2886 if (unlikely(seq
== adev
->last_seq_ctrl
)) {
2887 if (!adev
->dup_count
++)
2888 adev
->dup_msg_expiry
= jiffies
+ 10*HZ
;
2889 adev
->stats
.rx_errors
++;
2890 return 1; /* a dup */
2892 adev
->last_seq_ctrl
= seq
;
2897 acx_l_rx_ieee802_11_frame(acx_device_t
*adev
, rxbuffer_t
*rxbuf
)
2899 unsigned int ftype
, fstype
;
2900 const wlan_hdr_t
*hdr
;
2901 int result
= NOT_OK
;
2905 hdr
= acx_get_wlan_hdr(adev
, rxbuf
);
2907 /* see IEEE 802.11-1999.pdf chapter 7 "MAC frame formats" */
2908 if (unlikely((hdr
->fc
& WF_FC_PVERi
) != 0)) {
2909 printk_ratelimited(KERN_INFO
"rx: unsupported 802.11 protocol\n");
2913 ftype
= hdr
->fc
& WF_FC_FTYPEi
;
2914 fstype
= hdr
->fc
& WF_FC_FSTYPEi
;
2917 /* check data frames first, for speed */
2918 case WF_FTYPE_DATAi
:
2920 case WF_FSTYPE_DATAONLYi
:
2921 if (acx_l_handle_dup(adev
, hdr
->seq
))
2922 break; /* a dup, simply discard it */
2925 if (WF_FC_FROMTODSi == (hdr->fc & WF_FC_FROMTODSi)) {
2926 result = acx_l_process_data_frame_wds(adev, rxbuf);
2931 switch (adev
->mode
) {
2933 result
= acx_l_process_data_frame_master(adev
, rxbuf
);
2935 case ACX_MODE_0_ADHOC
:
2936 case ACX_MODE_2_STA
:
2937 result
= acx_l_process_data_frame_client(adev
, rxbuf
);
2940 case WF_FSTYPE_DATA_CFACKi
:
2941 case WF_FSTYPE_DATA_CFPOLLi
:
2942 case WF_FSTYPE_DATA_CFACK_CFPOLLi
:
2943 case WF_FSTYPE_CFPOLLi
:
2944 case WF_FSTYPE_CFACK_CFPOLLi
:
2946 acx_process_class_frame(adev, rxbuf, 3); */
2948 case WF_FSTYPE_NULLi
:
2949 /* acx_l_process_NULL_frame(adev, rxbuf, 3); */
2951 /* FIXME: same here, see above */
2952 case WF_FSTYPE_CFACKi
:
2957 case WF_FTYPE_MGMTi
:
2958 result
= acx_l_process_mgmt_frame(adev
, rxbuf
);
2961 if (fstype
== WF_FSTYPE_PSPOLLi
)
2963 /* this call is irrelevant, since
2964 * acx_process_class_frame is a stub, so return
2965 * immediately instead.
2966 * return acx_process_class_frame(adev, rxbuf, 3); */
2977 /***********************************************************************
2978 ** acx_l_process_rxbuf
2980 ** NB: used by USB code also
2983 acx_l_process_rxbuf(acx_device_t
*adev
, rxbuffer_t
*rxbuf
)
2985 struct wlan_hdr
*hdr
;
2990 hdr
= acx_get_wlan_hdr(adev
, rxbuf
);
2991 fc
= le16_to_cpu(hdr
->fc
);
2992 /* length of frame from control field to first byte of FCS */
2993 buf_len
= RXBUF_BYTES_RCVD(adev
, rxbuf
);
2995 if ( ((WF_FC_FSTYPE
& fc
) != WF_FSTYPE_BEACON
)
2996 || (acx_debug
& L_XFER_BEACON
)
2998 log(L_XFER
|L_DATA
, "rx: %s "
2999 "time:%u len:%u signal:%u SNR:%u macstat:%02X "
3000 "phystat:%02X phyrate:%u status:%u\n",
3001 acx_get_packet_type_string(fc
),
3002 le32_to_cpu(rxbuf
->time
),
3004 acx_signal_to_winlevel(rxbuf
->phy_level
),
3005 acx_signal_to_winlevel(rxbuf
->phy_snr
),
3007 rxbuf
->phy_stat_baseband
,
3008 rxbuf
->phy_plcp_signal
,
3012 if (unlikely(acx_debug
& L_DATA
)) {
3013 printk("rx: 802.11 buf[%u]: ", buf_len
);
3014 acx_dump_bytes(hdr
, buf_len
);
3017 /* FIXME: should check for Rx errors (rxbuf->mac_status?
3018 * discard broken packets - but NOT for monitor!)
3019 * and update Rx packet statistics here */
3021 if (unlikely(adev
->mode
== ACX_MODE_MONITOR
)) {
3022 acx_l_rxmonitor(adev
, rxbuf
);
3023 } else if (likely(buf_len
>= WLAN_HDR_A3_LEN
)) {
3024 acx_l_rx_ieee802_11_frame(adev
, rxbuf
);
3026 log(L_DEBUG
|L_XFER
|L_DATA
,
3027 "rx: NOT receiving packet (%s): "
3028 "size too small (%u)\n",
3029 acx_get_packet_type_string(fc
),
3033 /* Now check Rx quality level, AFTER processing packet.
3034 * I tried to figure out how to map these levels to dBm
3035 * values, but for the life of me I really didn't
3036 * manage to get it. Either these values are not meant to
3037 * be expressed in dBm, or it's some pretty complicated
3040 #ifdef FROM_SCAN_SOURCE_ONLY
3041 /* only consider packets originating from the MAC
3042 * address of the device that's managing our BSSID.
3043 * Disable it for now, since it removes information (levels
3044 * from different peers) and slows the Rx path. */
3046 && mac_is_equal(hdr
->a2
, adev
->ap_client
->address
)) {
3048 adev
->wstats
.qual
.level
= acx_signal_to_winlevel(rxbuf
->phy_level
);
3049 adev
->wstats
.qual
.noise
= acx_signal_to_winlevel(rxbuf
->phy_snr
);
3051 qual
= acx_signal_determine_quality(adev
->wstats
.qual
.level
,
3052 adev
->wstats
.qual
.noise
);
3054 qual
= (adev
->wstats
.qual
.noise
<= 100) ?
3055 100 - adev
->wstats
.qual
.noise
: 0;
3057 adev
->wstats
.qual
.qual
= qual
;
3058 adev
->wstats
.qual
.updated
= 7; /* all 3 indicators updated */
3059 #ifdef FROM_SCAN_SOURCE_ONLY
3065 /***********************************************************************
3066 ** acx_l_handle_txrate_auto
3068 ** Theory of operation:
3069 ** client->rate_cap is a bitmask of rates client is capable of.
3070 ** client->rate_cfg is a bitmask of allowed (configured) rates.
3071 ** It is set as a result of iwconfig rate N [auto]
3072 ** or iwpriv set_rates "N,N,N N,N,N" commands.
3073 ** It can be fixed (e.g. 0x0080 == 18Mbit only),
3074 ** auto (0x00ff == 18Mbit or any lower value),
3075 ** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
3077 ** client->rate_cur is a value for rate111 field in tx descriptor.
3078 ** It is always set to txrate_cfg sans zero or more most significant
3079 ** bits. This routine handles selection of new rate_cur value depending on
3080 ** outcome of last tx event.
3082 ** client->rate_100 is a precalculated rate value for acx100
3083 ** (we can do without it, but will need to calculate it on each tx).
3085 ** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
3086 ** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
3087 ** In theory you can implement it, but so far it is considered not worth doing.
3089 ** 22Mbit, of course, is PBCC always. */
3091 /* maps acx100 tx descr rate field to acx111 one */
3096 case RATE100_1
: return RATE111_1
;
3097 case RATE100_2
: return RATE111_2
;
3099 case (RATE100_5
| RATE100_PBCC511
): return RATE111_5
;
3101 case (RATE100_11
| RATE100_PBCC511
): return RATE111_11
;
3102 case RATE100_22
: return RATE111_22
;
3104 printk("acx: unexpected acx100 txrate: %u! "
3105 "Please report\n", r
);
3112 acx_l_handle_txrate_auto(acx_device_t
*adev
, struct client
*txc
,
3113 u16 cur
, u8 rate100
, u16 rate111
,
3114 u8 error
, int pkts_to_ignore
)
3117 int slower_rate_was_used
;
3119 /* vda: hmm. current code will do this:
3120 ** 1. send packets at 11 Mbit, stepup++
3121 ** 2. will try to send at 22Mbit. hardware will see no ACK,
3122 ** retries at 11Mbit, success. code notes that used rate
3123 ** is lower. stepup = 0, fallback++
3124 ** 3. repeat step 2 fallback_count times. Fall back to
3125 ** 11Mbit. go to step 1.
3126 ** If stepup_count is large (say, 16) and fallback_count
3127 ** is small (3), this wouldn't be too bad wrt throughput */
3129 if (unlikely(!cur
)) {
3130 printk("acx: BUG! ratemask is empty\n");
3131 return; /* or else we may lock up the box */
3134 /* do some preparations, i.e. calculate the one rate that was
3135 * used to send this packet */
3136 if (IS_ACX111(adev
)) {
3137 sent_rate
= 1 << highest_bit(rate111
& RATE111_ALL
);
3139 sent_rate
= rate100to111(rate100
);
3141 /* sent_rate has only one bit set now, corresponding to tx rate
3142 * which was used by hardware to tx this particular packet */
3144 /* now do the actual auto rate management */
3145 log(L_XFER
, "tx: %sclient=%p/"MACSTR
" used=%04X cur=%04X cfg=%04X "
3146 "__=%u/%u ^^=%u/%u\n",
3147 (txc
->ignore_count
> 0) ? "[IGN] " : "",
3148 txc
, MAC(txc
->address
), sent_rate
, cur
, txc
->rate_cfg
,
3149 txc
->fallback_count
, adev
->fallback_threshold
,
3150 txc
->stepup_count
, adev
->stepup_threshold
3153 /* we need to ignore old packets already in the tx queue since
3154 * they use older rate bytes configured before our last rate change,
3155 * otherwise our mechanism will get confused by interpreting old data.
3156 * Do it after logging above */
3157 if (txc
->ignore_count
) {
3158 txc
->ignore_count
--;
3162 /* true only if the only nonzero bit in sent_rate is
3163 ** less significant than highest nonzero bit in cur */
3164 slower_rate_was_used
= ( cur
> ((sent_rate
<<1)-1) );
3166 if (slower_rate_was_used
|| error
) {
3167 txc
->stepup_count
= 0;
3168 if (++txc
->fallback_count
<= adev
->fallback_threshold
)
3170 txc
->fallback_count
= 0;
3172 /* clear highest 1 bit in cur */
3173 sent_rate
= RATE111_54
;
3174 while (!(cur
& sent_rate
)) sent_rate
>>= 1;
3175 CLEAR_BIT(cur
, sent_rate
);
3176 if (!cur
) /* we can't disable all rates! */
3178 log(L_XFER
, "tx: falling back to ratemask %04X\n", cur
);
3180 } else { /* there was neither lower rate nor error */
3181 txc
->fallback_count
= 0;
3182 if (++txc
->stepup_count
<= adev
->stepup_threshold
)
3184 txc
->stepup_count
= 0;
3186 /* Sanitize. Sort of not needed, but I dont trust hw that much...
3187 ** what if it can report bogus tx rates sometimes? */
3188 while (!(cur
& sent_rate
)) sent_rate
>>= 1;
3190 /* try to find a higher sent_rate that isn't yet in our
3191 * current set, but is an allowed cfg */
3194 if (sent_rate
> txc
->rate_cfg
)
3195 /* no higher rates allowed by config */
3197 if (!(cur
& sent_rate
) && (txc
->rate_cfg
& sent_rate
))
3200 /* not found, try higher one */
3202 SET_BIT(cur
, sent_rate
);
3203 log(L_XFER
, "tx: stepping up to ratemask %04X\n", cur
);
3206 txc
->rate_cur
= cur
;
3207 txc
->ignore_count
= pkts_to_ignore
;
3208 /* calculate acx100 style rate byte if needed */
3209 if (IS_ACX100(adev
)) {
3210 txc
->rate_100
= acx_bitpos2rate100
[highest_bit(cur
)];
3215 /***********************************************************************
3218 ** Called by network core. Can be called outside of process context.
3221 acx_i_start_xmit(struct sk_buff
*skb
, struct net_device
*ndev
)
3223 acx_device_t
*adev
= ndev2adev(ndev
);
3226 unsigned long flags
;
3227 int txresult
= NOT_OK
;
3232 if (unlikely(!skb
)) {
3233 /* indicate success */
3237 if (unlikely(!adev
)) {
3241 acx_lock(adev
, flags
);
3243 if (unlikely(!(adev
->dev_state_mask
& ACX_STATE_IFACE_UP
))) {
3246 if (unlikely(adev
->mode
== ACX_MODE_OFF
)) {
3249 if (unlikely(acx_queue_stopped(ndev
))) {
3250 log(L_DEBUG
, "%s: called when queue stopped\n", __func__
);
3253 if (unlikely(ACX_STATUS_4_ASSOCIATED
!= adev
->status
)) {
3254 log(L_XFER
, "trying to xmit, but not associated yet: "
3256 /* silently drop the packet, since we're not connected yet */
3258 /* ...but indicate an error nevertheless */
3259 adev
->stats
.tx_errors
++;
3263 tx
= acx_l_alloc_tx(adev
);
3264 if (unlikely(!tx
)) {
3267 * generic slave interface has to make do with the tiny amount, around
3268 * 7k, of transmit buffer space on the ACX itself. It is likely this will
3269 * frequently be full.
3271 printk_ratelimited("%s: start_xmit: txdesc ring is full, "
3272 "dropping tx\n", ndev
->name
);
3277 txbuf
= acx_l_get_txbuf(adev
, tx
);
3278 if (unlikely(!txbuf
)) {
3279 /* Card was removed */
3281 acx_l_dealloc_tx(adev
, tx
);
3284 len
= acx_ether_to_txbuf(adev
, txbuf
, skb
);
3285 if (unlikely(len
< 0)) {
3286 /* Error in packet conversion */
3288 acx_l_dealloc_tx(adev
, tx
);
3291 acx_l_tx_data(adev
, tx
, len
);
3292 ndev
->trans_start
= jiffies
;
3295 adev
->stats
.tx_packets
++;
3296 adev
->stats
.tx_bytes
+= skb
->len
;
3299 acx_unlock(adev
, flags
);
3302 if ((txresult
== OK
) && skb
)
3303 dev_kfree_skb_any(skb
);
3310 /***********************************************************************
3311 ** acx_l_update_ratevector
3313 ** Updates adev->rate_supported[_len] according to rate_{basic,oper}
3316 acx_bitpos2ratebyte
[] = {
3333 acx_l_update_ratevector(acx_device_t
*adev
)
3335 u16 bcfg
= adev
->rate_basic
;
3336 u16 ocfg
= adev
->rate_oper
;
3337 u8
*supp
= adev
->rate_supported
;
3338 const u8
*dot11
= acx_bitpos2ratebyte
;
3354 adev
->rate_supported_len
= supp
- adev
->rate_supported
;
3355 if (acx_debug
& L_ASSOC
) {
3356 printk("new ratevector: ");
3357 acx_dump_bytes(adev
->rate_supported
, adev
->rate_supported_len
);
3363 /***********************************************************************
3364 ** acx_l_sta_list_init
3367 acx_l_sta_list_init(acx_device_t
*adev
)
3370 memset(adev
->sta_hash_tab
, 0, sizeof(adev
->sta_hash_tab
));
3371 memset(adev
->sta_list
, 0, sizeof(adev
->sta_list
));
3376 /***********************************************************************
3377 ** acx_l_sta_list_get_from_hash
3379 static inline client_t
*
3380 acx_l_sta_list_get_from_hash(acx_device_t
*adev
, const u8
*address
)
3382 return adev
->sta_hash_tab
[address
[5] % VEC_SIZE(adev
->sta_hash_tab
)];
3386 /***********************************************************************
3387 ** acx_l_sta_list_get
3390 acx_l_sta_list_get(acx_device_t
*adev
, const u8
*address
)
3394 client
= acx_l_sta_list_get_from_hash(adev
, address
);
3396 if (mac_is_equal(address
, client
->address
)) {
3397 client
->mtime
= jiffies
;
3400 client
= client
->next
;
3407 /***********************************************************************
3408 ** acx_l_sta_list_del
3411 acx_l_sta_list_del(acx_device_t
*adev
, client_t
*victim
)
3413 client_t
*client
, *next
;
3415 client
= acx_l_sta_list_get_from_hash(adev
, victim
->address
);
3417 /* tricky. next = client on first iteration only,
3418 ** on all other iters next = client->next */
3420 if (next
== victim
) {
3421 client
->next
= victim
->next
;
3423 memset(victim
, 0, sizeof(*victim
));
3427 next
= client
->next
;
3432 /***********************************************************************
3433 ** acx_l_sta_list_alloc
3435 ** Never fails - will evict oldest client if needed
3438 acx_l_sta_list_alloc(acx_device_t
*adev
)
3441 unsigned long age
, oldest_age
;
3442 client_t
*client
, *oldest
;
3446 oldest
= &adev
->sta_list
[0];
3448 for (i
= 0; i
< VEC_SIZE(adev
->sta_list
); i
++) {
3449 client
= &adev
->sta_list
[i
];
3451 if (!client
->used
) {
3454 age
= jiffies
- client
->mtime
;
3455 if (oldest_age
< age
) {
3461 acx_l_sta_list_del(adev
, oldest
);
3464 memset(client
, 0, sizeof(*client
));
3470 /***********************************************************************
3471 ** acx_l_sta_list_add
3473 ** Never fails - will evict oldest client if needed
3475 /* In case we will reimplement it differently... */
3476 #define STA_LIST_ADD_CAN_FAIL 0
3479 acx_l_sta_list_add(acx_device_t
*adev
, const u8
*address
)
3486 client
= acx_l_sta_list_alloc(adev
);
3488 client
->mtime
= jiffies
;
3489 MAC_COPY(client
->address
, address
);
3490 client
->used
= CLIENT_EXIST_1
;
3491 client
->auth_alg
= WLAN_AUTH_ALG_SHAREDKEY
;
3492 client
->auth_step
= 1;
3493 /* give some tentative peer rate values
3494 ** (needed because peer may do auth without probing us first,
3495 ** thus we'll have no idea of peer's ratevector yet).
3496 ** Will be overwritten by scanning or assoc code */
3497 client
->rate_cap
= adev
->rate_basic
;
3498 client
->rate_cfg
= adev
->rate_basic
;
3499 client
->rate_cur
= 1 << lowest_bit(adev
->rate_basic
);
3501 index
= address
[5] % VEC_SIZE(adev
->sta_hash_tab
);
3502 client
->next
= adev
->sta_hash_tab
[index
];
3503 adev
->sta_hash_tab
[index
] = client
;
3505 acxlog_mac(L_ASSOC
, "sta_list_add: sta=", address
, "\n");
3512 /***********************************************************************
3513 ** acx_l_sta_list_get_or_add
3515 ** Never fails - will evict oldest client if needed
3518 acx_l_sta_list_get_or_add(acx_device_t
*adev
, const u8
*address
)
3520 client_t
*client
= acx_l_sta_list_get(adev
, address
);
3522 client
= acx_l_sta_list_add(adev
, address
);
3527 /***********************************************************************
3530 ** This function is called in many atomic regions, must not sleep
3532 ** This function does not need locking UNLESS you call it
3533 ** as acx_set_status(ACX_STATUS_4_ASSOCIATED), bacause this can
3534 ** wake queue. This can race with stop_queue elsewhere.
3535 ** See acx_stop_queue comment. */
3537 acx_set_status(acx_device_t
*adev
, u16 new_status
)
3539 #define QUEUE_OPEN_AFTER_ASSOC 1 /* this really seems to be needed now */
3540 u16 old_status
= adev
->status
;
3544 log(L_ASSOC
, "%s(%d):%s\n",
3545 __func__
, new_status
, acx_get_status_name(new_status
));
3547 /* wireless_send_event never sleeps */
3548 if (ACX_STATUS_4_ASSOCIATED
== new_status
) {
3549 union iwreq_data wrqu
;
3551 wrqu
.data
.length
= 0;
3552 wrqu
.data
.flags
= 0;
3553 wireless_send_event(adev
->ndev
, SIOCGIWSCAN
, &wrqu
, NULL
);
3555 wrqu
.data
.length
= 0;
3556 wrqu
.data
.flags
= 0;
3557 MAC_COPY(wrqu
.ap_addr
.sa_data
, adev
->bssid
);
3558 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
3559 wireless_send_event(adev
->ndev
, SIOCGIWAP
, &wrqu
, NULL
);
3561 union iwreq_data wrqu
;
3563 /* send event with empty BSSID to indicate we're not associated */
3564 MAC_ZERO(wrqu
.ap_addr
.sa_data
);
3565 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
3566 wireless_send_event(adev
->ndev
, SIOCGIWAP
, &wrqu
, NULL
);
3569 adev
->status
= new_status
;
3571 switch (new_status
) {
3572 case ACX_STATUS_1_SCANNING
:
3573 adev
->scan_retries
= 0;
3574 /* 1.0 s initial scan time */
3575 acx_set_timer(adev
, 1000000);
3577 case ACX_STATUS_2_WAIT_AUTH
:
3578 case ACX_STATUS_3_AUTHENTICATED
:
3579 adev
->auth_or_assoc_retries
= 0;
3580 acx_set_timer(adev
, 1500000); /* 1.5 s */
3584 #if QUEUE_OPEN_AFTER_ASSOC
3585 if (new_status
== ACX_STATUS_4_ASSOCIATED
) {
3586 if (old_status
< ACX_STATUS_4_ASSOCIATED
) {
3587 /* ah, we're newly associated now,
3588 * so let's indicate carrier */
3589 acx_carrier_on(adev
->ndev
, "after association");
3590 acx_wake_queue(adev
->ndev
, "after association");
3593 /* not associated any more, so let's kill carrier */
3594 if (old_status
>= ACX_STATUS_4_ASSOCIATED
) {
3595 acx_carrier_off(adev
->ndev
, "after losing association");
3596 acx_stop_queue(adev
->ndev
, "after losing association");
3604 /***********************************************************************
3607 ** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
3610 acx_i_timer(unsigned long address
)
3612 unsigned long flags
;
3613 acx_device_t
*adev
= (acx_device_t
*)address
;
3617 acx_lock(adev
, flags
);
3619 log(L_DEBUG
|L_ASSOC
, "%s: adev->status=%d (%s)\n",
3620 __func__
, adev
->status
, acx_get_status_name(adev
->status
));
3622 switch (adev
->status
) {
3623 case ACX_STATUS_1_SCANNING
:
3624 /* was set to 0 by set_status() */
3625 if (++adev
->scan_retries
< 7) {
3626 acx_set_timer(adev
, 1000000);
3627 /* used to interrogate for scan status.
3628 ** We rely on SCAN_COMPLETE IRQ instead */
3629 log(L_ASSOC
, "continuing scan (%d sec)\n",
3630 adev
->scan_retries
);
3632 log(L_ASSOC
, "stopping scan\n");
3633 /* send stop_scan cmd when we leave the interrupt context,
3634 * and make a decision what to do next (COMPLETE_SCAN) */
3635 acx_schedule_task(adev
,
3636 ACX_AFTER_IRQ_CMD_STOP_SCAN
+ ACX_AFTER_IRQ_COMPLETE_SCAN
);
3639 case ACX_STATUS_2_WAIT_AUTH
:
3640 /* was set to 0 by set_status() */
3641 if (++adev
->auth_or_assoc_retries
< 10) {
3642 log(L_ASSOC
, "resend authen1 request (attempt %d)\n",
3643 adev
->auth_or_assoc_retries
+ 1);
3644 acx_l_transmit_authen1(adev
);
3646 /* time exceeded: fall back to scanning mode */
3648 "authen1 request reply timeout, giving up\n");
3649 /* we are a STA, need to find AP anyhow */
3650 acx_set_status(adev
, ACX_STATUS_1_SCANNING
);
3651 acx_schedule_task(adev
, ACX_AFTER_IRQ_RESTART_SCAN
);
3653 /* used to be 1500000, but some other driver uses 2.5s */
3654 acx_set_timer(adev
, 2500000);
3656 case ACX_STATUS_3_AUTHENTICATED
:
3657 /* was set to 0 by set_status() */
3658 if (++adev
->auth_or_assoc_retries
< 10) {
3659 log(L_ASSOC
, "resend assoc request (attempt %d)\n",
3660 adev
->auth_or_assoc_retries
+ 1);
3661 acx_l_transmit_assoc_req(adev
);
3663 /* time exceeded: give up */
3665 "association request reply timeout, giving up\n");
3666 /* we are a STA, need to find AP anyhow */
3667 acx_set_status(adev
, ACX_STATUS_1_SCANNING
);
3668 acx_schedule_task(adev
, ACX_AFTER_IRQ_RESTART_SCAN
);
3670 acx_set_timer(adev
, 2500000); /* see above */
3672 case ACX_STATUS_4_ASSOCIATED
:
3677 acx_unlock(adev
, flags
);
3683 /***********************************************************************
3686 ** Sets the 802.11 state management timer's timeout.
3689 acx_set_timer(acx_device_t
*adev
, int timeout_us
)
3693 log(L_DEBUG
|L_IRQ
, "%s(%u ms)\n", __func__
, timeout_us
/1000);
3694 if (!(adev
->dev_state_mask
& ACX_STATE_IFACE_UP
)) {
3695 printk("attempt to set the timer "
3696 "when the card interface is not up!\n");
3700 /* first check if the timer was already initialized, THEN modify it */
3701 if (adev
->mgmt_timer
.function
) {
3702 mod_timer(&adev
->mgmt_timer
,
3703 jiffies
+ (timeout_us
* HZ
/ 1000000));
3710 /***********************************************************************
3711 ** acx_l_transmit_assocresp
3713 ** We are an AP here
3733 find_pos(const u8
*p
, int size
, u8 v
)
3736 for (i
= 0; i
< size
; i
++)
3739 /* printk a message about strange byte? */
3744 add_bits_to_ratemasks(u8
* ratevec
, int len
, u16
* brate
, u16
* orate
)
3747 int n
= 1 << find_pos(dot11ratebyte
,
3748 sizeof(dot11ratebyte
), *ratevec
& 0x7f);
3749 if (*ratevec
& 0x80)
3757 acx_l_transmit_assocresp(acx_device_t
*adev
, const wlan_fr_assocreq_t
*req
)
3760 struct wlan_hdr_mgmt
*head
;
3761 struct assocresp_frame_body
*body
;
3770 /* sa = req->hdr->a1; */
3772 bssid
= req
->hdr
->a3
;
3774 clt
= acx_l_sta_list_get(adev
, da
);
3778 /* Assoc without auth is a big no-no */
3779 /* Let's be liberal: if already assoc'ed STA sends assoc req again,
3780 ** we won't be rude */
3781 if (clt
->used
!= CLIENT_AUTHENTICATED_2
3782 && clt
->used
!= CLIENT_ASSOCIATED_3
) {
3783 acx_l_transmit_deauthen(adev
, da
, WLAN_MGMT_REASON_CLASS2_NONAUTH
);
3787 clt
->used
= CLIENT_ASSOCIATED_3
;
3790 clt
->aid
= ++adev
->aid
;
3791 clt
->cap_info
= ieee2host16(*(req
->cap_info
));
3793 /* We cheat here a bit. We don't really care which rates are flagged
3794 ** as basic by the client, so we stuff them in single ratemask */
3796 if (req
->supp_rates
)
3797 add_bits_to_ratemasks(req
->supp_rates
->rates
,
3798 req
->supp_rates
->len
, &clt
->rate_cap
, &clt
->rate_cap
);
3800 add_bits_to_ratemasks(req
->ext_rates
->rates
,
3801 req
->ext_rates
->len
, &clt
->rate_cap
, &clt
->rate_cap
);
3802 /* We can check that client supports all basic rates,
3803 ** and deny assoc if not. But let's be liberal, right? ;) */
3804 clt
->rate_cfg
= clt
->rate_cap
& adev
->rate_oper
;
3805 if (!clt
->rate_cfg
) clt
->rate_cfg
= 1 << lowest_bit(adev
->rate_oper
);
3806 clt
->rate_cur
= 1 << lowest_bit(clt
->rate_cfg
);
3807 if (IS_ACX100(adev
))
3808 clt
->rate_100
= acx_bitpos2rate100
[lowest_bit(clt
->rate_cfg
)];
3809 clt
->fallback_count
= clt
->stepup_count
= 0;
3810 clt
->ignore_count
= 16;
3812 tx
= acx_l_alloc_tx(adev
);
3815 head
= acx_l_get_txbuf(adev
, tx
);
3817 acx_l_dealloc_tx(adev
, tx
);
3820 body
= (void*)(head
+ 1);
3822 head
->fc
= WF_FSTYPE_ASSOCRESPi
;
3823 head
->dur
= req
->hdr
->dur
;
3824 MAC_COPY(head
->da
, da
);
3825 MAC_COPY(head
->sa
, adev
->dev_addr
);
3826 MAC_COPY(head
->bssid
, bssid
);
3827 head
->seq
= req
->hdr
->seq
;
3829 body
->cap_info
= host2ieee16(adev
->capabilities
);
3830 body
->status
= host2ieee16(0);
3831 body
->aid
= host2ieee16(clt
->aid
);
3832 p
= wlan_fill_ie_rates((u8
*)&body
->rates
, adev
->rate_supported_len
,
3833 adev
->rate_supported
);
3834 p
= wlan_fill_ie_rates_ext(p
, adev
->rate_supported_len
,
3835 adev
->rate_supported
);
3837 acx_l_tx_data(adev
, tx
, p
- (u8
*)head
);
3847 /***********************************************************************
3848 * acx_l_transmit_reassocresp
3850 You may be wondering, just like me, what the hell ReAuth is.
3851 In practice it was seen sent by STA when STA feels like losing connection.
3855 5.4.2.3 Reassociation
3857 Association is sufficient for no-transition message delivery between
3858 IEEE 802.11 stations. Additional functionality is needed to support
3859 BSS-transition mobility. The additional required functionality
3860 is provided by the reassociation service. Reassociation is a DSS.
3861 The reassociation service is invoked to 'move' a current association
3862 from one AP to another. This keeps the DS informed of the current
3863 mapping between AP and STA as the station moves from BSS to BSS within
3864 an ESS. Reassociation also enables changing association attributes
3865 of an established association while the STA remains associated with
3866 the same AP. Reassociation is always initiated by the mobile STA.
3868 5.4.3.1 Authentication
3870 A STA may be authenticated with many other STAs at any given instant.
3872 5.4.3.1.1 Preauthentication
3874 Because the authentication process could be time-consuming (depending
3875 on the authentication protocol in use), the authentication service can
3876 be invoked independently of the association service. Preauthentication
3877 is typically done by a STA while it is already associated with an AP
3878 (with which it previously authenticated). IEEE 802.11 does not require
3879 that STAs preauthenticate with APs. However, authentication is required
3880 before an association can be established. If the authentication is left
3881 until reassociation time, this may impact the speed with which a STA can
3882 reassociate between APs, limiting BSS-transition mobility performance.
3883 The use of preauthentication takes the authentication service overhead
3884 out of the time-critical reassociation process.
3888 For a STA to reassociate, the reassociation service causes the following
3891 Reassociation request
3893 * Message type: Management
3894 * Message subtype: Reassociation request
3895 * Information items:
3896 - IEEE address of the STA
3897 - IEEE address of the AP with which the STA will reassociate
3898 - IEEE address of the AP with which the STA is currently associated
3900 * Direction of message: From STA to 'new' AP
3902 The address of the current AP is included for efficiency. The inclusion
3903 of the current AP address facilitates MAC reassociation to be independent
3904 of the DS implementation.
3906 Reassociation response
3907 * Message type: Management
3908 * Message subtype: Reassociation response
3909 * Information items:
3910 - Result of the requested reassociation. (success/failure)
3911 - If the reassociation is successful, the response shall include the AID.
3912 * Direction of message: From AP to STA
3914 7.2.3.6 Reassociation Request frame format
3916 The frame body of a management frame of subtype Reassociation Request
3917 contains the information shown in Table 9.
3919 Table 9 Reassociation Request frame body
3921 1 Capability information
3923 3 Current AP address
3927 7.2.3.7 Reassociation Response frame format
3929 The frame body of a management frame of subtype Reassociation Response
3930 contains the information shown in Table 10.
3932 Table 10 Reassociation Response frame body
3934 1 Capability information
3936 3 Association ID (AID)
3941 acx_l_transmit_reassocresp(acx_device_t
*adev
, const wlan_fr_reassocreq_t
*req
)
3944 struct wlan_hdr_mgmt
*head
;
3945 struct reassocresp_frame_body
*body
;
3954 /* sa = req->hdr->a1; */
3956 bssid
= req
->hdr
->a3
;
3958 /* Must be already authenticated, so it must be in the list */
3959 clt
= acx_l_sta_list_get(adev
, da
);
3963 /* Assoc without auth is a big no-no */
3964 /* Already assoc'ed STAs sending ReAssoc req are ok per 802.11 */
3965 if (clt
->used
!= CLIENT_AUTHENTICATED_2
3966 && clt
->used
!= CLIENT_ASSOCIATED_3
) {
3967 acx_l_transmit_deauthen(adev
, da
, WLAN_MGMT_REASON_CLASS2_NONAUTH
);
3971 clt
->used
= CLIENT_ASSOCIATED_3
;
3972 if (clt
->aid
== 0) {
3973 clt
->aid
= ++adev
->aid
;
3976 clt
->cap_info
= ieee2host16(*(req
->cap_info
));
3978 /* We cheat here a bit. We don't really care which rates are flagged
3979 ** as basic by the client, so we stuff them in single ratemask */
3981 if (req
->supp_rates
)
3982 add_bits_to_ratemasks(req
->supp_rates
->rates
,
3983 req
->supp_rates
->len
, &clt
->rate_cap
, &clt
->rate_cap
);
3985 add_bits_to_ratemasks(req
->ext_rates
->rates
,
3986 req
->ext_rates
->len
, &clt
->rate_cap
, &clt
->rate_cap
);
3987 /* We can check that client supports all basic rates,
3988 ** and deny assoc if not. But let's be liberal, right? ;) */
3989 clt
->rate_cfg
= clt
->rate_cap
& adev
->rate_oper
;
3990 if (!clt
->rate_cfg
) clt
->rate_cfg
= 1 << lowest_bit(adev
->rate_oper
);
3991 clt
->rate_cur
= 1 << lowest_bit(clt
->rate_cfg
);
3992 if (IS_ACX100(adev
))
3993 clt
->rate_100
= acx_bitpos2rate100
[lowest_bit(clt
->rate_cfg
)];
3995 clt
->fallback_count
= clt
->stepup_count
= 0;
3996 clt
->ignore_count
= 16;
3998 tx
= acx_l_alloc_tx(adev
);
4001 head
= acx_l_get_txbuf(adev
, tx
);
4003 acx_l_dealloc_tx(adev
, tx
);
4006 body
= (void*)(head
+ 1);
4008 head
->fc
= WF_FSTYPE_REASSOCRESPi
;
4009 head
->dur
= req
->hdr
->dur
;
4010 MAC_COPY(head
->da
, da
);
4011 MAC_COPY(head
->sa
, adev
->dev_addr
);
4012 MAC_COPY(head
->bssid
, bssid
);
4013 head
->seq
= req
->hdr
->seq
;
4016 body
->cap_info
= host2ieee16(adev
->capabilities
);
4017 /* 2. status code */
4018 body
->status
= host2ieee16(0);
4020 body
->aid
= host2ieee16(clt
->aid
);
4022 p
= wlan_fill_ie_rates((u8
*)&body
->rates
, adev
->rate_supported_len
,
4023 adev
->rate_supported
);
4024 /* 5. ext supp rates */
4025 p
= wlan_fill_ie_rates_ext(p
, adev
->rate_supported_len
,
4026 adev
->rate_supported
);
4028 acx_l_tx_data(adev
, tx
, p
- (u8
*)head
);
4038 /***********************************************************************
4039 ** acx_l_process_disassoc_from_sta
4042 acx_l_process_disassoc_from_sta(acx_device_t
*adev
, const wlan_fr_disassoc_t
*req
)
4050 clt
= acx_l_sta_list_get(adev
, ta
);
4054 if (clt
->used
!= CLIENT_ASSOCIATED_3
4055 && clt
->used
!= CLIENT_AUTHENTICATED_2
) {
4056 /* it's disassociating, but it's
4057 ** not even authenticated! Let it know that */
4058 acxlog_mac(L_ASSOC
|L_XFER
, "peer ", ta
, "has sent disassoc "
4059 "req but it is not even auth'ed! sending deauth\n");
4060 acx_l_transmit_deauthen(adev
, ta
,
4061 WLAN_MGMT_REASON_CLASS2_NONAUTH
);
4062 clt
->used
= CLIENT_EXIST_1
;
4064 /* mark it as auth'ed only */
4065 clt
->used
= CLIENT_AUTHENTICATED_2
;
4072 /***********************************************************************
4073 ** acx_l_process_deauthen_from_sta
4076 acx_l_process_deauth_from_sta(acx_device_t
*adev
, const wlan_fr_deauthen_t
*req
)
4078 const wlan_hdr_t
*hdr
;
4085 if (acx_debug
& L_ASSOC
) {
4086 acx_print_mac("got deauth from sta:", hdr
->a2
, " ");
4087 acx_print_mac("a1:", hdr
->a1
, " ");
4088 acx_print_mac("a3:", hdr
->a3
, " ");
4089 acx_print_mac("adev->addr:", adev
->dev_addr
, " ");
4090 acx_print_mac("adev->bssid:", adev
->bssid
, "\n");
4093 if (!mac_is_equal(adev
->dev_addr
, hdr
->a1
)) {
4097 client
= acx_l_sta_list_get(adev
, hdr
->a2
);
4101 client
->used
= CLIENT_EXIST_1
;
4107 /***********************************************************************
4108 ** acx_l_process_disassoc_from_ap
4111 acx_l_process_disassoc_from_ap(acx_device_t
*adev
, const wlan_fr_disassoc_t
*req
)
4115 if (!adev
->ap_client
) {
4116 /* Hrm, we aren't assoc'ed yet anyhow... */
4120 printk("%s: got disassoc frame with reason %d (%s)\n",
4121 adev
->ndev
->name
, *req
->reason
,
4122 acx_wlan_reason_str(*req
->reason
));
4124 if (mac_is_equal(adev
->dev_addr
, req
->hdr
->a1
)) {
4125 acx_l_transmit_deauthen(adev
, adev
->bssid
,
4126 WLAN_MGMT_REASON_DEAUTH_LEAVING
);
4127 SET_BIT(adev
->set_mask
, GETSET_RESCAN
);
4128 acx_schedule_task(adev
, ACX_AFTER_IRQ_UPDATE_CARD_CFG
);
4135 /***********************************************************************
4136 ** acx_l_process_deauth_from_ap
4139 acx_l_process_deauth_from_ap(acx_device_t
*adev
, const wlan_fr_deauthen_t
*req
)
4143 if (!adev
->ap_client
) {
4144 /* Hrm, we aren't assoc'ed yet anyhow... */
4148 printk("%s: got deauth frame with reason %d (%s)\n",
4149 adev
->ndev
->name
, *req
->reason
,
4150 acx_wlan_reason_str(*req
->reason
));
4152 /* Chk: is ta verified to be from our AP? */
4153 if (mac_is_equal(adev
->dev_addr
, req
->hdr
->a1
)) {
4154 log(L_DEBUG
, "AP sent us deauth packet\n");
4155 SET_BIT(adev
->set_mask
, GETSET_RESCAN
);
4156 acx_schedule_task(adev
, ACX_AFTER_IRQ_UPDATE_CARD_CFG
);
4163 /***********************************************************************
4166 ** The end of the Rx path. Pulls data from a rxhostdesc into a socket
4167 ** buffer and feeds it to the network stack via netif_rx().
4170 acx_l_rx(acx_device_t
*adev
, rxbuffer_t
*rxbuf
)
4173 if (likely(adev
->dev_state_mask
& ACX_STATE_IFACE_UP
)) {
4174 struct sk_buff
*skb
;
4175 skb
= acx_rxbuf_to_ether(adev
, rxbuf
);
4178 adev
->ndev
->last_rx
= jiffies
;
4179 adev
->stats
.rx_packets
++;
4180 adev
->stats
.rx_bytes
+= skb
->len
;
4187 /***********************************************************************
4188 ** acx_l_process_data_frame_master
4191 acx_l_process_data_frame_master(acx_device_t
*adev
, rxbuffer_t
*rxbuf
)
4193 struct wlan_hdr
*hdr
;
4197 int result
= NOT_OK
;
4201 hdr
= acx_get_wlan_hdr(adev
, rxbuf
);
4203 switch (WF_FC_FROMTODSi
& hdr
->fc
) {
4206 log(L_DEBUG
, "ap->sta or adhoc->adhoc data frame ignored\n");
4210 default: /* WF_FC_FROMTODSi */
4211 log(L_DEBUG
, "wds data frame ignored (TODO)\n");
4215 /* check if it is our BSSID, if not, leave */
4216 if (!mac_is_equal(adev
->bssid
, hdr
->a1
)) {
4220 if (mac_is_equal(adev
->dev_addr
, hdr
->a3
)) {
4221 /* this one is for us */
4222 acx_l_rx(adev
, rxbuf
);
4224 if (mac_is_bcast(hdr
->a3
)) {
4225 /* this one is bcast, rx it too */
4226 acx_l_rx(adev
, rxbuf
);
4228 tx
= acx_l_alloc_tx(adev
);
4232 /* repackage, tx, and hope it someday reaches its destination */
4233 /* order is important, we do it in-place */
4234 MAC_COPY(hdr
->a1
, hdr
->a3
);
4235 MAC_COPY(hdr
->a3
, hdr
->a2
);
4236 MAC_COPY(hdr
->a2
, adev
->bssid
);
4237 /* To_DS = 0, From_DS = 1 */
4238 hdr
->fc
= WF_FC_FROMDSi
+ WF_FTYPE_DATAi
;
4240 txbuf
= acx_l_get_txbuf(adev
, tx
);
4242 len
= RXBUF_BYTES_RCVD(adev
, rxbuf
);
4243 memcpy(txbuf
, hdr
, len
);
4244 acx_l_tx_data(adev
, tx
, len
);
4246 acx_l_dealloc_tx(adev
, tx
);
4257 /***********************************************************************
4258 ** acx_l_process_data_frame_client
4261 acx_l_process_data_frame_client(acx_device_t
*adev
, rxbuffer_t
*rxbuf
)
4263 const u8
*da
, *bssid
;
4264 const wlan_hdr_t
*hdr
;
4265 struct net_device
*ndev
= adev
->ndev
;
4266 int result
= NOT_OK
;
4270 if (ACX_STATUS_4_ASSOCIATED
!= adev
->status
)
4273 hdr
= acx_get_wlan_hdr(adev
, rxbuf
);
4275 switch (WF_FC_FROMTODSi
& hdr
->fc
) {
4277 if (adev
->mode
!= ACX_MODE_0_ADHOC
) {
4278 log(L_DEBUG
, "adhoc->adhoc data frame ignored\n");
4284 if (adev
->mode
!= ACX_MODE_2_STA
) {
4285 log(L_DEBUG
, "ap->sta data frame ignored\n");
4291 log(L_DEBUG
, "sta->ap data frame ignored\n");
4293 default: /* WF_FC_FROMTODSi: wds->wds */
4294 log(L_DEBUG
, "wds data frame ignored (todo)\n");
4300 if (unlikely(acx_debug
& L_DEBUG
)) {
4301 acx_print_mac("rx: da=", da
, "");
4302 acx_print_mac(" bssid=", bssid
, "");
4303 acx_print_mac(" adev->bssid=", adev
->bssid
, "");
4304 acx_print_mac(" adev->addr=", adev
->dev_addr
, "\n");
4307 /* promiscuous mode --> receive all packets */
4308 if (unlikely(ndev
->flags
& IFF_PROMISC
))
4311 /* FIRST, check if it is our BSSID */
4312 if (!mac_is_equal(adev
->bssid
, bssid
)) {
4313 /* is not our BSSID, so bail out */
4317 /* then, check if it is our address */
4318 if (mac_is_equal(adev
->dev_addr
, da
)) {
4322 /* then, check if it is broadcast */
4323 if (mac_is_bcast(da
)) {
4327 if (mac_is_mcast(da
)) {
4328 /* unconditionally receive all multicasts */
4329 if (ndev
->flags
& IFF_ALLMULTI
)
4332 /* FIXME: need to check against the list of
4333 * multicast addresses that are configured
4334 * for the interface (ifconfig) */
4335 log(L_XFER
, "FIXME: multicast packet, need to check "
4336 "against a list of multicast addresses "
4337 "(to be created!); accepting packet for now\n");
4338 /* for now, just accept it here */
4342 log(L_DEBUG
, "rx: foreign packet, dropping\n");
4345 /* receive packet */
4346 acx_l_rx(adev
, rxbuf
);
4355 /***********************************************************************
4356 ** acx_l_process_mgmt_frame
4358 ** Theory of operation: mgmt packet gets parsed (to make it easy
4359 ** to access variable-sized IEs), results stored in 'parsed'.
4360 ** Then we react to the packet.
4362 typedef union parsed_mgmt_req
{
4363 wlan_fr_mgmt_t mgmt
;
4364 wlan_fr_assocreq_t assocreq
;
4365 wlan_fr_reassocreq_t reassocreq
;
4366 wlan_fr_assocresp_t assocresp
;
4367 wlan_fr_reassocresp_t reassocresp
;
4368 wlan_fr_beacon_t beacon
;
4369 wlan_fr_disassoc_t disassoc
;
4370 wlan_fr_authen_t authen
;
4371 wlan_fr_deauthen_t deauthen
;
4372 wlan_fr_proberesp_t proberesp
;
4373 } parsed_mgmt_req_t
;
4375 void BUG_excessive_stack_usage(void);
4378 acx_l_process_mgmt_frame(acx_device_t
*adev
, rxbuffer_t
*rxbuf
)
4380 parsed_mgmt_req_t parsed
; /* takes ~100 bytes of stack */
4382 int adhoc
, sta_scan
, sta
, ap
;
4385 if (sizeof(parsed
) > 256)
4386 BUG_excessive_stack_usage();
4390 hdr
= acx_get_wlan_hdr(adev
, rxbuf
);
4392 /* Management frames never have these set */
4393 if (WF_FC_FROMTODSi
& hdr
->fc
) {
4398 len
= RXBUF_BYTES_RCVD(adev
, rxbuf
);
4399 if (WF_FC_ISWEPi
& hdr
->fc
)
4402 adhoc
= (adev
->mode
== ACX_MODE_0_ADHOC
);
4403 sta_scan
= ((adev
->mode
== ACX_MODE_2_STA
)
4404 && (adev
->status
!= ACX_STATUS_4_ASSOCIATED
));
4405 sta
= ((adev
->mode
== ACX_MODE_2_STA
)
4406 && (adev
->status
== ACX_STATUS_4_ASSOCIATED
));
4407 ap
= (adev
->mode
== ACX_MODE_3_AP
);
4409 switch (WF_FC_FSTYPEi
& hdr
->fc
) {
4410 /* beacons first, for speed */
4411 case WF_FSTYPE_BEACONi
:
4412 memset(&parsed
.beacon
, 0, sizeof(parsed
.beacon
));
4413 parsed
.beacon
.hdr
= hdr
;
4414 parsed
.beacon
.len
= len
;
4415 if (acx_debug
& L_DATA
) {
4416 printk("beacon len:%d fc:%04X dur:%04X seq:%04X",
4417 len
, hdr
->fc
, hdr
->dur
, hdr
->seq
);
4418 acx_print_mac(" a1:", hdr
->a1
, "");
4419 acx_print_mac(" a2:", hdr
->a2
, "");
4420 acx_print_mac(" a3:", hdr
->a3
, "\n");
4422 wlan_mgmt_decode_beacon(&parsed
.beacon
);
4423 /* beacon and probe response are very similar, so... */
4424 acx_l_process_probe_response(adev
, &parsed
.beacon
, rxbuf
);
4426 case WF_FSTYPE_ASSOCREQi
:
4429 memset(&parsed
.assocreq
, 0, sizeof(parsed
.assocreq
));
4430 parsed
.assocreq
.hdr
= hdr
;
4431 parsed
.assocreq
.len
= len
;
4432 wlan_mgmt_decode_assocreq(&parsed
.assocreq
);
4433 if (mac_is_equal(hdr
->a1
, adev
->bssid
)
4434 && mac_is_equal(hdr
->a3
, adev
->bssid
)) {
4435 acx_l_transmit_assocresp(adev
, &parsed
.assocreq
);
4438 case WF_FSTYPE_REASSOCREQi
:
4441 memset(&parsed
.assocreq
, 0, sizeof(parsed
.assocreq
));
4442 parsed
.assocreq
.hdr
= hdr
;
4443 parsed
.assocreq
.len
= len
;
4444 wlan_mgmt_decode_assocreq(&parsed
.assocreq
);
4445 /* reassocreq and assocreq are equivalent */
4446 acx_l_transmit_reassocresp(adev
, &parsed
.reassocreq
);
4448 case WF_FSTYPE_ASSOCRESPi
:
4451 memset(&parsed
.assocresp
, 0, sizeof(parsed
.assocresp
));
4452 parsed
.assocresp
.hdr
= hdr
;
4453 parsed
.assocresp
.len
= len
;
4454 wlan_mgmt_decode_assocresp(&parsed
.assocresp
);
4455 acx_l_process_assocresp(adev
, &parsed
.assocresp
);
4457 case WF_FSTYPE_REASSOCRESPi
:
4460 memset(&parsed
.assocresp
, 0, sizeof(parsed
.assocresp
));
4461 parsed
.assocresp
.hdr
= hdr
;
4462 parsed
.assocresp
.len
= len
;
4463 wlan_mgmt_decode_assocresp(&parsed
.assocresp
);
4464 acx_l_process_reassocresp(adev
, &parsed
.reassocresp
);
4466 case WF_FSTYPE_PROBEREQi
:
4468 /* FIXME: since we're supposed to be an AP,
4469 ** we need to return a Probe Response packet.
4470 ** Currently firmware is doing it for us,
4471 ** but firmware is buggy! See comment elsewhere --vda */
4474 case WF_FSTYPE_PROBERESPi
:
4475 memset(&parsed
.proberesp
, 0, sizeof(parsed
.proberesp
));
4476 parsed
.proberesp
.hdr
= hdr
;
4477 parsed
.proberesp
.len
= len
;
4478 wlan_mgmt_decode_proberesp(&parsed
.proberesp
);
4479 acx_l_process_probe_response(adev
, &parsed
.proberesp
, rxbuf
);
4485 case WF_FSTYPE_ATIMi
:
4488 case WF_FSTYPE_DISASSOCi
:
4491 memset(&parsed
.disassoc
, 0, sizeof(parsed
.disassoc
));
4492 parsed
.disassoc
.hdr
= hdr
;
4493 parsed
.disassoc
.len
= len
;
4494 wlan_mgmt_decode_disassoc(&parsed
.disassoc
);
4496 acx_l_process_disassoc_from_ap(adev
, &parsed
.disassoc
);
4498 acx_l_process_disassoc_from_sta(adev
, &parsed
.disassoc
);
4500 case WF_FSTYPE_AUTHENi
:
4501 if (!sta_scan
&& !ap
)
4503 memset(&parsed
.authen
, 0, sizeof(parsed
.authen
));
4504 parsed
.authen
.hdr
= hdr
;
4505 parsed
.authen
.len
= len
;
4506 wlan_mgmt_decode_authen(&parsed
.authen
);
4507 acx_l_process_authen(adev
, &parsed
.authen
);
4509 case WF_FSTYPE_DEAUTHENi
:
4512 memset(&parsed
.deauthen
, 0, sizeof(parsed
.deauthen
));
4513 parsed
.deauthen
.hdr
= hdr
;
4514 parsed
.deauthen
.len
= len
;
4515 wlan_mgmt_decode_deauthen(&parsed
.deauthen
);
4517 acx_l_process_deauth_from_ap(adev
, &parsed
.deauthen
);
4519 acx_l_process_deauth_from_sta(adev
, &parsed
.deauthen
);
4529 /***********************************************************************
4530 ** acx_process_class_frame
4532 ** Called from IRQ context only
4535 acx_process_class_frame(acx_device_t
*adev
, rxbuffer_t
*rxbuf
, int vala
)
4542 /***********************************************************************
4543 ** acx_l_process_NULL_frame
4545 #ifdef BOGUS_ITS_NOT_A_NULL_FRAME_HANDLER_AT_ALL
4547 acx_l_process_NULL_frame(acx_device_t
*adev
, rxbuffer_t
*rxbuf
, int vala
)
4549 const signed char *esi
;
4551 const wlan_hdr_t
*hdr
;
4552 const client_t
*client
;
4553 int result
= NOT_OK
;
4555 hdr
= acx_get_wlan_hdr(adev
, rxbuf
);
4557 switch (WF_FC_FROMTODSi
& hdr
->fc
) {
4570 default: /* WF_FC_FROMTODSi */
4571 esi
= hdr
->a1
; /* added by me! --vda */
4580 client
= acx_l_sta_list_get(adev
, ebx
);
4585 log(L_DEBUG
|L_XFER
, "<transmit_deauth 7>\n");
4586 acx_l_transmit_deauthen(adev
, ebx
,
4587 WLAN_MGMT_REASON_CLASS2_NONAUTH
);
4589 log(L_DEBUG
, "received NULL frame from unknown client! "
4590 "We really shouldn't send deauthen here, right?\n");
4600 /***********************************************************************
4601 ** acx_l_process_probe_response
4604 acx_l_process_probe_response(acx_device_t
*adev
, wlan_fr_proberesp_t
*req
,
4605 const rxbuffer_t
*rxbuf
)
4614 if (mac_is_equal(hdr
->a3
, adev
->dev_addr
)) {
4615 log(L_ASSOC
, "huh, scan found our own MAC!?\n");
4616 goto ok
; /* just skip this one silently */
4619 bss
= acx_l_sta_list_get_or_add(adev
, hdr
->a2
);
4621 /* NB: be careful modifying bss data! It may be one
4622 ** of the already known clients (like our AP if we are a STA)
4623 ** Thus do not blindly modify e.g. current ratemask! */
4625 if (STA_LIST_ADD_CAN_FAIL
&& !bss
) {
4626 /* uh oh, we found more sites/stations than we can handle with
4627 * our current setup: pull the emergency brake and stop scanning! */
4628 acx_schedule_task(adev
, ACX_AFTER_IRQ_CMD_STOP_SCAN
);
4629 /* TODO: a nice comment what below call achieves --vda */
4630 acx_set_status(adev
, ACX_STATUS_2_WAIT_AUTH
);
4633 /* NB: get_or_add already filled bss->address = hdr->a2 */
4634 MAC_COPY(bss
->bssid
, hdr
->a3
);
4636 /* copy the ESSID element */
4637 if (req
->ssid
&& req
->ssid
->len
<= IW_ESSID_MAX_SIZE
) {
4638 bss
->essid_len
= req
->ssid
->len
;
4639 memcpy(bss
->essid
, req
->ssid
->ssid
, req
->ssid
->len
);
4640 bss
->essid
[req
->ssid
->len
] = '\0';
4642 /* Either no ESSID IE or oversized one */
4643 printk("%s: received packet has bogus ESSID\n",
4648 bss
->channel
= req
->ds_parms
->curr_ch
;
4650 bss
->cap_info
= ieee2host16(*req
->cap_info
);
4652 bss
->sir
= acx_signal_to_winlevel(rxbuf
->phy_level
);
4653 bss
->snr
= acx_signal_to_winlevel(rxbuf
->phy_snr
);
4655 bss
->rate_cap
= 0; /* operational mask */
4656 bss
->rate_bas
= 0; /* basic mask */
4657 if (req
->supp_rates
)
4658 add_bits_to_ratemasks(req
->supp_rates
->rates
,
4659 req
->supp_rates
->len
, &bss
->rate_bas
, &bss
->rate_cap
);
4661 add_bits_to_ratemasks(req
->ext_rates
->rates
,
4662 req
->ext_rates
->len
, &bss
->rate_bas
, &bss
->rate_cap
);
4663 /* Fix up any possible bogosity - code elsewhere
4664 * is not expecting empty masks */
4666 bss
->rate_cap
= adev
->rate_basic
;
4668 bss
->rate_bas
= 1 << lowest_bit(bss
->rate_cap
);
4670 bss
->rate_cur
= 1 << lowest_bit(bss
->rate_bas
);
4672 /* People moan about this being too noisy at L_ASSOC */
4674 "found %s: ESSID='%s' ch=%d "
4675 "BSSID="MACSTR
" caps=0x%04X SIR=%d SNR=%d\n",
4676 (bss
->cap_info
& WF_MGMT_CAP_IBSS
) ? "Ad-Hoc peer" : "AP",
4677 bss
->essid
, bss
->channel
, MAC(bss
->bssid
), bss
->cap_info
,
4678 bss
->sir
, bss
->snr
);
4685 /***********************************************************************
4686 ** acx_l_process_assocresp
4689 acx_l_process_assocresp(acx_device_t
*adev
, const wlan_fr_assocresp_t
*req
)
4691 const wlan_hdr_t
*hdr
;
4698 if ((ACX_MODE_2_STA
== adev
->mode
)
4699 && mac_is_equal(adev
->dev_addr
, hdr
->a1
)) {
4700 u16 st
= ieee2host16(*(req
->status
));
4701 if (WLAN_MGMT_STATUS_SUCCESS
== st
) {
4702 adev
->aid
= ieee2host16(*(req
->aid
));
4703 /* tell the card we are associated when
4704 ** we are out of interrupt context */
4705 acx_schedule_task(adev
, ACX_AFTER_IRQ_CMD_ASSOCIATE
);
4708 /* TODO: we shall delete peer from sta_list, and try
4709 ** other candidates... */
4711 printk("%s: association FAILED: peer sent "
4712 "response code %d (%s)\n",
4713 adev
->ndev
->name
, st
, get_status_string(st
));
4723 /***********************************************************************
4724 ** acx_l_process_reassocresp
4727 acx_l_process_reassocresp(acx_device_t
*adev
, const wlan_fr_reassocresp_t
*req
)
4729 const wlan_hdr_t
*hdr
;
4730 int result
= NOT_OK
;
4737 if (!mac_is_equal(adev
->dev_addr
, hdr
->a1
)) {
4740 st
= ieee2host16(*(req
->status
));
4741 if (st
== WLAN_MGMT_STATUS_SUCCESS
) {
4742 acx_set_status(adev
, ACX_STATUS_4_ASSOCIATED
);
4745 printk("%s: reassociation FAILED: peer sent "
4746 "response code %d (%s)\n",
4747 adev
->ndev
->name
, st
, get_status_string(st
));
4755 /***********************************************************************
4756 ** acx_l_process_authen
4758 ** Called only in STA_SCAN or AP mode
4761 acx_l_process_authen(acx_device_t
*adev
, const wlan_fr_authen_t
*req
)
4763 const wlan_hdr_t
*hdr
;
4765 wlan_ie_challenge_t
*chal
;
4766 u16 alg
, seq
, status
;
4773 if (acx_debug
& L_ASSOC
) {
4774 acx_print_mac("AUTHEN adev->addr=", adev
->dev_addr
, " ");
4775 acx_print_mac("a1=", hdr
->a1
, " ");
4776 acx_print_mac("a2=", hdr
->a2
, " ");
4777 acx_print_mac("a3=", hdr
->a3
, " ");
4778 acx_print_mac("adev->bssid=", adev
->bssid
, "\n");
4781 if (!mac_is_equal(adev
->dev_addr
, hdr
->a1
)
4782 || !mac_is_equal(adev
->bssid
, hdr
->a3
)) {
4787 alg
= ieee2host16(*(req
->auth_alg
));
4788 seq
= ieee2host16(*(req
->auth_seq
));
4789 status
= ieee2host16(*(req
->status
));
4791 ap
= (adev
->mode
== ACX_MODE_3_AP
);
4793 if (adev
->auth_alg
<= 1) {
4794 if (adev
->auth_alg
!= alg
) {
4795 log(L_ASSOC
, "auth algorithm mismatch: "
4796 "our:%d peer:%d\n", adev
->auth_alg
, alg
);
4801 log(L_ASSOC
, "algorithm is ok\n");
4804 clt
= acx_l_sta_list_get_or_add(adev
, hdr
->a2
);
4805 if (STA_LIST_ADD_CAN_FAIL
&& !clt
) {
4806 log(L_ASSOC
, "could not allocate room for client\n");
4811 clt
= adev
->ap_client
;
4812 if (!mac_is_equal(clt
->address
, hdr
->a2
)) {
4813 printk("%s: malformed auth frame from AP?!\n",
4820 /* now check which step in the authentication sequence we are
4821 * currently in, and act accordingly */
4822 log(L_ASSOC
, "acx_process_authen auth seq step %d\n", seq
);
4827 acx_l_transmit_authen2(adev
, req
, clt
);
4832 if (status
== WLAN_MGMT_STATUS_SUCCESS
) {
4833 if (alg
== WLAN_AUTH_ALG_OPENSYSTEM
) {
4834 acx_set_status(adev
, ACX_STATUS_3_AUTHENTICATED
);
4835 acx_l_transmit_assoc_req(adev
);
4837 if (alg
== WLAN_AUTH_ALG_SHAREDKEY
) {
4838 acx_l_transmit_authen3(adev
, req
);
4841 printk("%s: auth FAILED: peer sent "
4842 "response code %d (%s), "
4843 "still waiting for authentication\n",
4845 status
, get_status_string(status
));
4846 acx_set_status(adev
, ACX_STATUS_2_WAIT_AUTH
);
4852 if ((clt
->auth_alg
!= WLAN_AUTH_ALG_SHAREDKEY
)
4853 || (alg
!= WLAN_AUTH_ALG_SHAREDKEY
)
4854 || (clt
->auth_step
!= 2))
4856 chal
= req
->challenge
;
4858 || memcmp(chal
->challenge
, clt
->challenge_text
, WLAN_CHALLENGE_LEN
)
4859 || (chal
->eid
!= WLAN_EID_CHALLENGE
)
4860 || (chal
->len
!= WLAN_CHALLENGE_LEN
)
4863 acx_l_transmit_authen4(adev
, req
);
4864 MAC_COPY(clt
->address
, hdr
->a2
);
4865 clt
->used
= CLIENT_AUTHENTICATED_2
;
4867 clt
->seq
= ieee2host16(hdr
->seq
);
4872 /* ok, we're through: we're authenticated. Woohoo!! */
4873 acx_set_status(adev
, ACX_STATUS_3_AUTHENTICATED
);
4874 log(L_ASSOC
, "Authenticated!\n");
4875 /* now that we're authenticated, request association */
4876 acx_l_transmit_assoc_req(adev
);
4886 /***********************************************************************
4887 ** acx_gen_challenge
4890 acx_gen_challenge(wlan_ie_challenge_t
* d
)
4893 d
->eid
= WLAN_EID_CHALLENGE
;
4894 d
->len
= WLAN_CHALLENGE_LEN
;
4895 get_random_bytes(d
->challenge
, WLAN_CHALLENGE_LEN
);
4900 /***********************************************************************
4901 ** acx_l_transmit_deauthen
4904 acx_l_transmit_deauthen(acx_device_t
*adev
, const u8
*addr
, u16 reason
)
4907 struct wlan_hdr_mgmt
*head
;
4908 struct deauthen_frame_body
*body
;
4912 tx
= acx_l_alloc_tx(adev
);
4915 head
= acx_l_get_txbuf(adev
, tx
);
4917 acx_l_dealloc_tx(adev
, tx
);
4920 body
= (void*)(head
+ 1);
4922 head
->fc
= (WF_FTYPE_MGMTi
| WF_FSTYPE_DEAUTHENi
);
4924 MAC_COPY(head
->da
, addr
);
4925 MAC_COPY(head
->sa
, adev
->dev_addr
);
4926 MAC_COPY(head
->bssid
, adev
->bssid
);
4929 log(L_DEBUG
|L_ASSOC
|L_XFER
,
4930 "sending deauthen to "MACSTR
" for %d\n",
4933 body
->reason
= host2ieee16(reason
);
4935 /* body is fixed size here, but beware of cutting-and-pasting this -
4936 ** do not use sizeof(*body) for variable sized mgmt packets! */
4937 acx_l_tx_data(adev
, tx
, WLAN_HDR_A3_LEN
+ sizeof(*body
));
4947 /***********************************************************************
4948 ** acx_l_transmit_authen1
4951 acx_l_transmit_authen1(acx_device_t
*adev
)
4954 struct wlan_hdr_mgmt
*head
;
4955 struct auth_frame_body
*body
;
4959 log(L_ASSOC
, "sending authentication1 request, "
4960 "awaiting response\n");
4962 tx
= acx_l_alloc_tx(adev
);
4965 head
= acx_l_get_txbuf(adev
, tx
);
4967 acx_l_dealloc_tx(adev
, tx
);
4970 body
= (void*)(head
+ 1);
4972 head
->fc
= WF_FSTYPE_AUTHENi
;
4973 head
->dur
= host2ieee16(0x8000);
4974 MAC_COPY(head
->da
, adev
->bssid
);
4975 MAC_COPY(head
->sa
, adev
->dev_addr
);
4976 MAC_COPY(head
->bssid
, adev
->bssid
);
4979 body
->auth_alg
= host2ieee16(adev
->auth_alg
);
4980 body
->auth_seq
= host2ieee16(1);
4981 body
->status
= host2ieee16(0);
4983 acx_l_tx_data(adev
, tx
, WLAN_HDR_A3_LEN
+ 2 + 2 + 2);
4993 /***********************************************************************
4994 ** acx_l_transmit_authen2
4997 acx_l_transmit_authen2(acx_device_t
*adev
, const wlan_fr_authen_t
*req
,
5001 struct wlan_hdr_mgmt
*head
;
5002 struct auth_frame_body
*body
;
5003 unsigned int packet_len
;
5010 MAC_COPY(clt
->address
, req
->hdr
->a2
);
5012 clt
->ps
= ((WF_FC_PWRMGTi
& req
->hdr
->fc
) != 0);
5014 clt
->auth_alg
= ieee2host16(*(req
->auth_alg
));
5016 clt
->seq
= ieee2host16(req
->hdr
->seq
);
5018 tx
= acx_l_alloc_tx(adev
);
5021 head
= acx_l_get_txbuf(adev
, tx
);
5023 acx_l_dealloc_tx(adev
, tx
);
5026 body
= (void*)(head
+ 1);
5028 head
->fc
= WF_FSTYPE_AUTHENi
;
5029 head
->dur
= req
->hdr
->dur
;
5030 MAC_COPY(head
->da
, req
->hdr
->a2
);
5031 MAC_COPY(head
->sa
, adev
->dev_addr
);
5032 MAC_COPY(head
->bssid
, req
->hdr
->a3
);
5033 head
->seq
= req
->hdr
->seq
;
5035 /* already in IEEE format, no endianness conversion */
5036 body
->auth_alg
= *(req
->auth_alg
);
5037 body
->auth_seq
= host2ieee16(2);
5038 body
->status
= host2ieee16(0);
5040 packet_len
= WLAN_HDR_A3_LEN
+ 2 + 2 + 2;
5041 if (ieee2host16(*(req
->auth_alg
)) == WLAN_AUTH_ALG_OPENSYSTEM
) {
5042 clt
->used
= CLIENT_AUTHENTICATED_2
;
5043 } else { /* shared key */
5044 acx_gen_challenge(&body
->challenge
);
5045 memcpy(&clt
->challenge_text
, body
->challenge
.challenge
, WLAN_CHALLENGE_LEN
);
5046 packet_len
+= 2 + 2 + 2 + 1+1+WLAN_CHALLENGE_LEN
;
5049 acxlog_mac(L_ASSOC
|L_XFER
,
5050 "transmit_auth2: BSSID=", head
->bssid
, "\n");
5052 acx_l_tx_data(adev
, tx
, packet_len
);
5062 /***********************************************************************
5063 ** acx_l_transmit_authen3
5066 acx_l_transmit_authen3(acx_device_t
*adev
, const wlan_fr_authen_t
*req
)
5069 struct wlan_hdr_mgmt
*head
;
5070 struct auth_frame_body
*body
;
5071 unsigned int packet_len
;
5075 tx
= acx_l_alloc_tx(adev
);
5078 head
= acx_l_get_txbuf(adev
, tx
);
5080 acx_l_dealloc_tx(adev
, tx
);
5083 body
= (void*)(head
+ 1);
5085 head
->fc
= WF_FC_ISWEPi
+ WF_FSTYPE_AUTHENi
;
5086 /* FIXME: is this needed?? authen4 does it...
5087 head->dur = req->hdr->dur;
5088 head->seq = req->hdr->seq;
5090 MAC_COPY(head
->da
, adev
->bssid
);
5091 MAC_COPY(head
->sa
, adev
->dev_addr
);
5092 MAC_COPY(head
->bssid
, adev
->bssid
);
5094 /* already in IEEE format, no endianness conversion */
5095 body
->auth_alg
= *(req
->auth_alg
);
5096 body
->auth_seq
= host2ieee16(3);
5097 body
->status
= host2ieee16(0);
5098 memcpy(&body
->challenge
, req
->challenge
, req
->challenge
->len
+ 2);
5099 packet_len
= WLAN_HDR_A3_LEN
+ 8 + req
->challenge
->len
;
5101 log(L_ASSOC
|L_XFER
, "transmit_authen3!\n");
5103 acx_l_tx_data(adev
, tx
, packet_len
);
5110 /***********************************************************************
5111 ** acx_l_transmit_authen4
5114 acx_l_transmit_authen4(acx_device_t
*adev
, const wlan_fr_authen_t
*req
)
5117 struct wlan_hdr_mgmt
*head
;
5118 struct auth_frame_body
*body
;
5122 tx
= acx_l_alloc_tx(adev
);
5125 head
= acx_l_get_txbuf(adev
, tx
);
5127 acx_l_dealloc_tx(adev
, tx
);
5130 body
= (void*)(head
+ 1);
5132 head
->fc
= WF_FSTYPE_AUTHENi
; /* 0xb0 */
5133 head
->dur
= req
->hdr
->dur
;
5134 MAC_COPY(head
->da
, req
->hdr
->a2
);
5135 MAC_COPY(head
->sa
, adev
->dev_addr
);
5136 MAC_COPY(head
->bssid
, req
->hdr
->a3
);
5137 head
->seq
= req
->hdr
->seq
;
5139 /* already in IEEE format, no endianness conversion */
5140 body
->auth_alg
= *(req
->auth_alg
);
5141 body
->auth_seq
= host2ieee16(4);
5142 body
->status
= host2ieee16(0);
5144 acx_l_tx_data(adev
, tx
, WLAN_HDR_A3_LEN
+ 2 + 2 + 2);
5151 /***********************************************************************
5152 ** acx_l_transmit_assoc_req
5154 ** adev->ap_client is a current candidate AP here
5157 acx_l_transmit_assoc_req(acx_device_t
*adev
)
5160 struct wlan_hdr_mgmt
*head
;
5161 u8
*body
, *p
, *prate
;
5162 unsigned int packet_len
;
5167 log(L_ASSOC
, "sending association request, "
5168 "awaiting response. NOT ASSOCIATED YET\n");
5169 tx
= acx_l_alloc_tx(adev
);
5172 head
= acx_l_get_txbuf(adev
, tx
);
5174 acx_l_dealloc_tx(adev
, tx
);
5177 body
= (void*)(head
+ 1);
5179 head
->fc
= WF_FSTYPE_ASSOCREQi
;
5180 head
->dur
= host2ieee16(0x8000);
5181 MAC_COPY(head
->da
, adev
->bssid
);
5182 MAC_COPY(head
->sa
, adev
->dev_addr
);
5183 MAC_COPY(head
->bssid
, adev
->bssid
);
5187 /* now start filling the AssocReq frame body */
5189 /* since this assoc request will most likely only get
5190 * sent in the STA to AP case (and not when Ad-Hoc IBSS),
5191 * the cap combination indicated here will thus be
5192 * WF_MGMT_CAP_ESSi *always* (no IBSS ever)
5193 * The specs are more than non-obvious on all that:
5195 * 802.11 7.3.1.4 Capability Information field
5196 ** APs set the ESS subfield to 1 and the IBSS subfield to 0 within
5197 ** Beacon or Probe Response management frames. STAs within an IBSS
5198 ** set the ESS subfield to 0 and the IBSS subfield to 1 in transmitted
5199 ** Beacon or Probe Response management frames
5201 ** APs set the Privacy subfield to 1 within transmitted Beacon,
5202 ** Probe Response, Association Response, and Reassociation Response
5203 ** if WEP is required for all data type frames within the BSS.
5204 ** STAs within an IBSS set the Privacy subfield to 1 in Beacon
5205 ** or Probe Response management frames if WEP is required
5206 ** for all data type frames within the IBSS */
5208 /* note that returning 0 will be refused by several APs...
5209 * (so this indicates that you're probably supposed to
5210 * "confirm" the ESS mode) */
5211 cap
= WF_MGMT_CAP_ESSi
;
5213 /* this one used to be a check on wep_restricted,
5214 * but more likely it's wep_enabled instead */
5215 if (adev
->wep_enabled
)
5216 SET_BIT(cap
, WF_MGMT_CAP_PRIVACYi
);
5218 /* Probably we can just set these always, because our hw is
5219 ** capable of shortpre and PBCC --vda */
5220 /* only ask for short preamble if the peer station supports it */
5221 if (adev
->ap_client
->cap_info
& WF_MGMT_CAP_SHORT
)
5222 SET_BIT(cap
, WF_MGMT_CAP_SHORTi
);
5223 /* only ask for PBCC support if the peer station supports it */
5224 if (adev
->ap_client
->cap_info
& WF_MGMT_CAP_PBCC
)
5225 SET_BIT(cap
, WF_MGMT_CAP_PBCCi
);
5228 *(u16
*)p
= cap
; p
+= 2;
5229 /* 2. listen interval */
5230 *(u16
*)p
= host2ieee16(adev
->listen_interval
); p
+= 2;
5232 p
= wlan_fill_ie_ssid(p
,
5233 strlen(adev
->essid_for_assoc
), adev
->essid_for_assoc
);
5236 p
= wlan_fill_ie_rates(p
,
5237 adev
->rate_supported_len
, adev
->rate_supported
);
5238 /* 5. ext supp rates */
5239 p
= wlan_fill_ie_rates_ext(p
,
5240 adev
->rate_supported_len
, adev
->rate_supported
);
5242 if (acx_debug
& L_DEBUG
) {
5243 printk("association: rates element\n");
5244 acx_dump_bytes(prate
, p
- prate
);
5247 /* calculate lengths */
5248 packet_len
= WLAN_HDR_A3_LEN
+ (p
- body
);
5250 log(L_ASSOC
, "association: requesting caps 0x%04X, ESSID '%s'\n",
5251 cap
, adev
->essid_for_assoc
);
5253 acx_l_tx_data(adev
, tx
, packet_len
);
5262 /***********************************************************************
5263 ** acx_l_transmit_disassoc
5265 ** FIXME: looks like incomplete implementation of a helper:
5266 ** acx_l_transmit_disassoc(adev, clt) - kick this client (we're an AP)
5267 ** acx_l_transmit_disassoc(adev, NULL) - leave BSSID (we're a STA)
5271 acx_l_transmit_disassoc(acx_device_t
*adev
, client_t
*clt
)
5274 struct wlan_hdr_mgmt
*head
;
5275 struct disassoc_frame_body
*body
;
5278 /* if (clt != NULL) { */
5279 tx
= acx_l_alloc_tx(adev
);
5282 head
= acx_l_get_txbuf(adev
, tx
);
5284 acx_l_dealloc_tx(adev
, tx
);
5287 body
= (void*)(head
+ 1);
5289 /* clt->used = CLIENT_AUTHENTICATED_2; - not (yet?) associated */
5291 head
->fc
= WF_FSTYPE_DISASSOCi
;
5293 /* huh? It muchly depends on whether we're STA or AP...
5294 ** sta->ap: da=bssid, sa=own, bssid=bssid
5295 ** ap->sta: da=sta, sa=bssid, bssid=bssid. FIXME! */
5296 MAC_COPY(head
->da
, adev
->bssid
);
5297 MAC_COPY(head
->sa
, adev
->dev_addr
);
5298 MAC_COPY(head
->bssid
, adev
->dev_addr
);
5301 /* "Class 3 frame received from nonassociated station." */
5302 body
->reason
= host2ieee16(7);
5304 /* fixed size struct, ok to sizeof */
5305 acx_l_tx_data(adev
, tx
, WLAN_HDR_A3_LEN
+ sizeof(*body
));
5316 /***********************************************************************
5317 ** acx_s_complete_scan
5319 ** Called either from after_interrupt_task() if:
5320 ** 1) there was Scan_Complete IRQ, or
5321 ** 2) scanning expired in timer()
5322 ** We need to decide which ESS or IBSS to join.
5323 ** Iterates thru adev->sta_list:
5324 ** if adev->ap is not bcast, will join only specified
5325 ** ESS or IBSS with this bssid
5326 ** checks peers' caps for ESS/IBSS bit
5327 ** checks peers' SSID, allows exact match or hidden SSID
5328 ** If station to join is chosen:
5329 ** points adev->ap_client to the chosen struct client
5330 ** sets adev->essid_for_assoc for future assoc attempt
5331 ** Auth/assoc is not yet performed
5332 ** Returns OK if there is no need to restart scan
5335 acx_s_complete_scan(acx_device_t
*adev
)
5338 unsigned long flags
;
5346 switch (adev
->mode
) {
5347 case ACX_MODE_0_ADHOC
:
5348 needed_cap
= WF_MGMT_CAP_IBSS
; /* 2, we require Ad-Hoc */
5350 case ACX_MODE_2_STA
:
5351 needed_cap
= WF_MGMT_CAP_ESS
; /* 1, we require Managed */
5354 printk("acx: driver bug: mode=%d in complete_scan()\n", adev
->mode
);
5359 acx_lock(adev
, flags
);
5361 /* TODO: sta_iterator hiding implementation would be nice here... */
5363 for (i
= 0; i
< VEC_SIZE(adev
->sta_list
); i
++) {
5364 bss
= &adev
->sta_list
[i
];
5365 if (!bss
->used
) continue;
5367 log(L_ASSOC
, "scan table: SSID='%s' CH=%d SIR=%d SNR=%d\n",
5368 bss
->essid
, bss
->channel
, bss
->sir
, bss
->snr
);
5370 if (!mac_is_bcast(adev
->ap
))
5371 if (!mac_is_equal(bss
->bssid
, adev
->ap
))
5372 continue; /* keep looking */
5374 /* broken peer with no mode flags set? */
5375 if (unlikely(!(bss
->cap_info
& (WF_MGMT_CAP_ESS
| WF_MGMT_CAP_IBSS
)))) {
5376 printk("%s: strange peer "MACSTR
" found with "
5377 "neither ESS (AP) nor IBSS (Ad-Hoc) "
5378 "capability - skipped\n",
5379 adev
->ndev
->name
, MAC(bss
->address
));
5382 log(L_ASSOC
, "peer_cap 0x%04X, needed_cap 0x%04X\n",
5383 bss
->cap_info
, needed_cap
);
5385 /* does peer station support what we need? */
5386 if ((bss
->cap_info
& needed_cap
) != needed_cap
)
5387 continue; /* keep looking */
5389 /* strange peer with NO basic rates?! */
5390 if (unlikely(!bss
->rate_bas
)) {
5391 printk("%s: strange peer "MACSTR
" with empty rate set "
5393 adev
->ndev
->name
, MAC(bss
->address
));
5397 /* do we support all basic rates of this peer? */
5398 if ((bss
->rate_bas
& adev
->rate_oper
) != bss
->rate_bas
) {
5399 /* we probably need to have all rates as operational rates,
5400 even in case of an 11M-only configuration */
5401 #ifdef THIS_IS_TROUBLESOME
5402 printk("%s: peer "MACSTR
": incompatible basic rates "
5403 "(AP requests 0x%04X, we have 0x%04X) "
5405 adev
->ndev
->name
, MAC(bss
->address
),
5406 bss
->rate_bas
, adev
->rate_oper
);
5409 printk("%s: peer "MACSTR
": incompatible basic rates "
5410 "(AP requests 0x%04X, we have 0x%04X). "
5411 "Considering anyway...\n",
5412 adev
->ndev
->name
, MAC(bss
->address
),
5413 bss
->rate_bas
, adev
->rate_oper
);
5417 if ( !(adev
->reg_dom_chanmask
& (1<<(bss
->channel
-1))) ) {
5418 printk("%s: warning: peer "MACSTR
" is on channel %d "
5419 "outside of channel range of current "
5420 "regulatory domain - couldn't join "
5421 "even if other settings match. "
5422 "You might want to adapt your config\n",
5423 adev
->ndev
->name
, MAC(bss
->address
),
5425 continue; /* keep looking */
5428 if (!adev
->essid_active
|| !strcmp(bss
->essid
, adev
->essid
)) {
5430 "found station with matching ESSID! ('%s' "
5431 "station, '%s' config)\n",
5433 (adev
->essid_active
) ? adev
->essid
: "[any]");
5434 /* TODO: continue looking for peer with better SNR */
5435 bss
->used
= CLIENT_JOIN_CANDIDATE
;
5438 /* stop searching if this station is
5439 * on the current channel, otherwise
5440 * keep looking for an even better match */
5441 if (bss
->channel
== adev
->channel
)
5445 || ((' ' == bss
->essid
[0]) && !bss
->essid
[1])
5447 /* hmm, station with empty or single-space SSID:
5448 * using hidden SSID broadcast?
5450 /* This behaviour is broken: which AP from zillion
5451 ** of APs with hidden SSID you'd try?
5452 ** We should use Probe requests to get Probe responses
5453 ** and check for real SSID (are those never hidden?) */
5454 bss
->used
= CLIENT_JOIN_CANDIDATE
;
5455 if (idx_found
== -1)
5457 log(L_ASSOC
, "found station with empty or "
5458 "single-space (hidden) SSID, considering "
5459 "for assoc attempt\n");
5460 /* ...and keep looking for better matches */
5462 log(L_ASSOC
, "ESSID doesn't match! ('%s' "
5463 "station, '%s' config)\n",
5465 (adev
->essid_active
) ? adev
->essid
: "[any]");
5469 /* TODO: iterate thru join candidates instead */
5470 /* TODO: rescan if not associated within some timeout */
5471 if (idx_found
!= -1) {
5475 bss
= &adev
->sta_list
[idx_found
];
5476 adev
->ap_client
= bss
;
5478 if (bss
->essid
[0] == '\0') {
5479 /* if the ESSID of the station we found is empty
5480 * (no broadcast), then use user-configured ESSID
5482 essid_src
= adev
->essid
;
5483 essid_len
= adev
->essid_len
;
5485 essid_src
= bss
->essid
;
5486 essid_len
= strlen(bss
->essid
);
5489 acx_update_capabilities(adev
);
5491 memcpy(adev
->essid_for_assoc
, essid_src
, essid_len
);
5492 adev
->essid_for_assoc
[essid_len
] = '\0';
5493 adev
->channel
= bss
->channel
;
5494 MAC_COPY(adev
->bssid
, bss
->bssid
);
5496 bss
->rate_cfg
= (bss
->rate_cap
& adev
->rate_oper
);
5497 bss
->rate_cur
= 1 << lowest_bit(bss
->rate_cfg
);
5498 bss
->rate_100
= acx_rate111to100(bss
->rate_cur
);
5501 "matching station found: ", adev
->bssid
, ", joining\n");
5503 /* TODO: do we need to switch to the peer's channel first? */
5505 if (ACX_MODE_0_ADHOC
== adev
->mode
) {
5506 acx_set_status(adev
, ACX_STATUS_4_ASSOCIATED
);
5508 acx_l_transmit_authen1(adev
);
5509 acx_set_status(adev
, ACX_STATUS_2_WAIT_AUTH
);
5511 } else { /* idx_found == -1 */
5512 /* uh oh, no station found in range */
5513 if (ACX_MODE_0_ADHOC
== adev
->mode
) {
5514 printk("%s: no matching station found in range, "
5515 "generating our own IBSS instead\n",
5517 /* we do it the HostAP way: */
5518 MAC_COPY(adev
->bssid
, adev
->dev_addr
);
5519 adev
->bssid
[0] |= 0x02; /* 'local assigned addr' bit */
5520 /* add IBSS bit to our caps... */
5521 acx_update_capabilities(adev
);
5522 acx_set_status(adev
, ACX_STATUS_4_ASSOCIATED
);
5523 /* In order to cmd_join be called below */
5526 /* we shall scan again, AP can be
5527 ** just temporarily powered off */
5529 "no matching station found in range yet\n");
5530 acx_set_status(adev
, ACX_STATUS_1_SCANNING
);
5535 acx_unlock(adev
, flags
);
5537 if (idx_found
!= -1) {
5538 if (ACX_MODE_0_ADHOC
== adev
->mode
) {
5539 /* need to update channel in beacon template */
5540 SET_BIT(adev
->set_mask
, SET_TEMPLATES
);
5541 if (ACX_STATE_IFACE_UP
& adev
->dev_state_mask
)
5542 acx_s_update_card_settings(adev
);
5544 /* Inform firmware on our decision to start or join BSS */
5545 acx_s_cmd_join_bssid(adev
, adev
->bssid
);
5554 /***********************************************************************
5557 ** Loads a firmware image
5560 ** 0 unable to load file
5561 ** pointer to firmware success
5564 acx_s_read_fw(struct device
*dev
, const char *file
, u32
*size
)
5566 firmware_image_t
*res
;
5567 const struct firmware
*fw_entry
;
5570 log(L_INIT
, "requesting firmware image '%s'\n", file
);
5571 if (!request_firmware(&fw_entry
, file
, dev
)) {
5573 if (fw_entry
->size
>= 8)
5574 *size
= 8 + le32_to_cpu(*(u32
*)(fw_entry
->data
+ 4));
5575 if (fw_entry
->size
!= *size
) {
5576 printk("acx: firmware size does not match "
5577 "firmware header: %d != %d, "
5578 "aborting fw upload\n",
5579 (int) fw_entry
->size
, (int) *size
);
5582 res
= vmalloc(*size
);
5584 printk("acx: no memory for firmware "
5585 "(%u bytes)\n", *size
);
5588 memcpy(res
, fw_entry
->data
, fw_entry
->size
);
5590 release_firmware(fw_entry
);
5593 printk("acx: firmware image '%s' was not provided. "
5594 "Check your hotplug scripts\n", file
);
5596 /* checksum will be verified in write_fw, so don't bother here */
5601 /***********************************************************************
5605 acx100_s_set_wepkey(acx_device_t
*adev
)
5607 ie_dot11WEPDefaultKey_t dk
;
5610 for (i
= 0; i
< DOT11_MAX_DEFAULT_WEP_KEYS
; i
++) {
5611 if (adev
->wep_keys
[i
].size
!= 0) {
5612 log(L_INIT
, "setting WEP key: %d with "
5613 "total size: %d\n", i
, (int) adev
->wep_keys
[i
].size
);
5615 dk
.keySize
= adev
->wep_keys
[i
].size
;
5616 dk
.defaultKeyNum
= i
;
5617 memcpy(dk
.key
, adev
->wep_keys
[i
].key
, dk
.keySize
);
5618 acx_s_configure(adev
, &dk
, ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE
);
5624 acx111_s_set_wepkey(acx_device_t
*adev
)
5626 acx111WEPDefaultKey_t dk
;
5629 for (i
= 0; i
< DOT11_MAX_DEFAULT_WEP_KEYS
; i
++) {
5630 if (adev
->wep_keys
[i
].size
!= 0) {
5631 log(L_INIT
, "setting WEP key: %d with "
5632 "total size: %d\n", i
, (int) adev
->wep_keys
[i
].size
);
5633 memset(&dk
, 0, sizeof(dk
));
5634 dk
.action
= cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
5635 dk
.keySize
= adev
->wep_keys
[i
].size
;
5637 /* are these two lines necessary? */
5638 dk
.type
= 0; /* default WEP key */
5639 dk
.index
= 0; /* ignored when setting default key */
5641 dk
.defaultKeyNum
= i
;
5642 memcpy(dk
.key
, adev
->wep_keys
[i
].key
, dk
.keySize
);
5643 acx_s_issue_cmd(adev
, ACX1xx_CMD_WEP_MGMT
, &dk
, sizeof(dk
));
5649 acx_s_set_wepkey(acx_device_t
*adev
)
5651 if (IS_ACX111(adev
))
5652 acx111_s_set_wepkey(adev
);
5654 acx100_s_set_wepkey(adev
);
5658 /***********************************************************************
5659 ** acx100_s_init_wep
5661 ** FIXME: this should probably be moved into the new card settings
5662 ** management, but since we're also modifying the memory map layout here
5663 ** due to the WEP key space we want, we should take care...
5666 acx100_s_init_wep(acx_device_t
*adev
)
5668 acx100_ie_wep_options_t options
;
5669 ie_dot11WEPDefaultKeyID_t dk
;
5675 if (OK
!= acx_s_interrogate(adev
, &pt
, ACX1xx_IE_MEMORY_MAP
)) {
5679 log(L_DEBUG
, "CodeEnd:%X\n", pt
.CodeEnd
);
5682 * Firmware sets the wep cache start to 4 after the code, so we may as
5683 * well request it be there.
5685 pt
.WEPCacheStart
= cpu_to_le16(le16_to_cpu(pt
.CodeEnd
) + 4);
5687 if (OK
!= acx_s_configure(adev
, &pt
, ACX1xx_IE_MEMORY_MAP
)) {
5691 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
5692 options
.NumKeys
= cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS
+ 10);
5693 options
.WEPOption
= 0x00;
5695 log(L_ASSOC
, "%s: writing WEP options\n", __func__
);
5696 acx_s_configure(adev
, &options
, ACX100_IE_WEP_OPTIONS
);
5698 acx100_s_set_wepkey(adev
);
5700 if (adev
->wep_keys
[adev
->wep_current_index
].size
!= 0) {
5701 log(L_ASSOC
, "setting active default WEP key number: %d\n",
5702 adev
->wep_current_index
);
5703 dk
.KeyID
= adev
->wep_current_index
;
5704 acx_s_configure(adev
, &dk
, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET
); /* 0x1010 */
5706 /* FIXME!!! wep_key_struct is filled nowhere! But adev
5707 * is initialized to 0, and we don't REALLY need those keys either */
5708 /* for (i = 0; i < 10; i++) {
5709 if (adev->wep_key_struct[i].len != 0) {
5710 MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
5711 wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
5712 memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
5713 wep_mgmt.Action = cpu_to_le16(1);
5714 log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
5715 if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
5716 adev->wep_key_struct[i].index = i;
5722 /* now retrieve the updated WEPCacheEnd pointer... */
5723 if (OK
!= acx_s_interrogate(adev
, &pt
, ACX1xx_IE_MEMORY_MAP
)) {
5724 printk("%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
5728 /* ...and tell it to start allocating templates at that location */
5729 /* (no endianness conversion needed) */
5730 pt
.PacketTemplateStart
= pt
.WEPCacheEnd
;
5732 if (OK
!= acx_s_configure(adev
, &pt
, ACX1xx_IE_MEMORY_MAP
)) {
5733 printk("%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
5746 acx_s_init_max_template_generic(acx_device_t
*adev
, unsigned int len
, unsigned int cmd
)
5750 acx_template_nullframe_t null
;
5751 acx_template_beacon_t b
;
5752 acx_template_tim_t tim
;
5753 acx_template_probereq_t preq
;
5754 acx_template_proberesp_t presp
;
5757 memset(&templ
, 0, len
);
5758 templ
.null
.size
= cpu_to_le16(len
- 2);
5759 res
= acx_s_issue_cmd(adev
, cmd
, &templ
, len
);
5764 acx_s_init_max_null_data_template(acx_device_t
*adev
)
5766 return acx_s_init_max_template_generic(
5767 adev
, sizeof(acx_template_nullframe_t
), ACX1xx_CMD_CONFIG_NULL_DATA
5772 acx_s_init_max_beacon_template(acx_device_t
*adev
)
5774 return acx_s_init_max_template_generic(
5775 adev
, sizeof(acx_template_beacon_t
), ACX1xx_CMD_CONFIG_BEACON
5780 acx_s_init_max_tim_template(acx_device_t
*adev
)
5782 return acx_s_init_max_template_generic(
5783 adev
, sizeof(acx_template_tim_t
), ACX1xx_CMD_CONFIG_TIM
5788 acx_s_init_max_probe_response_template(acx_device_t
*adev
)
5790 return acx_s_init_max_template_generic(
5791 adev
, sizeof(acx_template_proberesp_t
), ACX1xx_CMD_CONFIG_PROBE_RESPONSE
5796 acx_s_init_max_probe_request_template(acx_device_t
*adev
)
5798 return acx_s_init_max_template_generic(
5799 adev
, sizeof(acx_template_probereq_t
), ACX1xx_CMD_CONFIG_PROBE_REQUEST
5803 /***********************************************************************
5804 ** acx_s_set_tim_template
5806 ** FIXME: In full blown driver we will regularly update partial virtual bitmap
5807 ** by calling this function
5808 ** (it can be done by irq handler on each DTIM irq or by timer...)
5810 [802.11 7.3.2.6] TIM information element:
5814 indicates how many beacons (including this) appear before next DTIM
5815 (0=this one is a DTIM)
5817 number of beacons between successive DTIMs
5818 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
5820 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
5821 set to 1 in TIM elements with a value of 0 in the DTIM Count field
5822 when one or more broadcast or multicast frames are buffered at the AP.
5823 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
5824 4 n Partial Virtual Bitmap
5825 Visible part of traffic-indication bitmap.
5826 Full bitmap consists of 2008 bits (251 octets) such that bit number N
5827 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
5828 in octet number N/8 where the low-order bit of each octet is bit0,
5829 and the high order bit is bit7.
5830 Each set bit in virtual bitmap corresponds to traffic buffered by AP
5831 for a specific station (with corresponding AID?).
5832 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
5833 Bitmap Offset is a number of skipped zero octets (see above).
5834 'Missing' octets at the tail are also assumed to be zero.
5835 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
5836 This means that traffic-indication bitmap is:
5837 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
5838 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
5841 acx_s_set_tim_template(acx_device_t
*adev
)
5843 /* For now, configure smallish test bitmap, all zero ("no pending data") */
5844 enum { bitmap_size
= 5 };
5846 acx_template_tim_t t
;
5851 memset(&t
, 0, sizeof(t
));
5852 t
.size
= 5 + bitmap_size
; /* eid+len+count+period+bmap_ctrl + bmap */
5853 t
.tim_eid
= WLAN_EID_TIM
;
5854 t
.len
= 3 + bitmap_size
; /* count+period+bmap_ctrl + bmap */
5855 result
= acx_s_issue_cmd(adev
, ACX1xx_CMD_CONFIG_TIM
, &t
, sizeof(t
));
5861 /***********************************************************************
5862 ** acx_fill_beacon_or_proberesp_template
5864 ** For frame format info, please see 802.11-1999.pdf item 7.2.3.9 and below!!
5866 ** NB: we use the fact that
5867 ** struct acx_template_proberesp and struct acx_template_beacon are the same
5868 ** (well, almost...)
5870 ** [802.11] Beacon's body consist of these IEs:
5872 ** 2 Beacon interval
5873 ** 3 Capability information
5875 ** 5 Supported rates (up to 8 rates)
5876 ** 6 FH Parameter Set (frequency-hopping PHYs only)
5877 ** 7 DS Parameter Set (direct sequence PHYs only)
5878 ** 8 CF Parameter Set (only if PCF is supported)
5879 ** 9 IBSS Parameter Set (ad-hoc only)
5882 ** 10 TIM (AP only) (see 802.11 7.3.2.6)
5883 ** 11 Country Information (802.11d)
5884 ** 12 FH Parameters (802.11d)
5885 ** 13 FH Pattern Table (802.11d)
5886 ** ... (?!! did not yet find relevant PDF file... --vda)
5887 ** 19 ERP Information (extended rate PHYs)
5888 ** 20 Extended Supported Rates (if more than 8 rates)
5891 ** 10 Country information (802.11d)
5892 ** 11 FH Parameters (802.11d)
5893 ** 12 FH Pattern Table (802.11d)
5894 ** 13-n Requested information elements (802.11d)
5896 ** 18 ERP Information (extended rate PHYs)
5897 ** 19 Extended Supported Rates (if more than 8 rates)
5900 acx_fill_beacon_or_proberesp_template(acx_device_t
*adev
,
5901 struct acx_template_beacon
*templ
,
5902 u16 fc
/* in host order! */)
5909 memset(templ
, 0, sizeof(*templ
));
5910 MAC_BCAST(templ
->da
);
5911 MAC_COPY(templ
->sa
, adev
->dev_addr
);
5912 MAC_COPY(templ
->bssid
, adev
->bssid
);
5914 templ
->beacon_interval
= cpu_to_le16(adev
->beacon_interval
);
5915 acx_update_capabilities(adev
);
5916 templ
->cap
= cpu_to_le16(adev
->capabilities
);
5918 p
= templ
->variable
;
5919 p
= wlan_fill_ie_ssid(p
, adev
->essid_len
, adev
->essid
);
5920 p
= wlan_fill_ie_rates(p
, adev
->rate_supported_len
, adev
->rate_supported
);
5921 p
= wlan_fill_ie_ds_parms(p
, adev
->channel
);
5922 /* NB: should go AFTER tim, but acx seem to keep tim last always */
5923 p
= wlan_fill_ie_rates_ext(p
, adev
->rate_supported_len
, adev
->rate_supported
);
5925 switch (adev
->mode
) {
5926 case ACX_MODE_0_ADHOC
:
5928 p
= wlan_fill_ie_ibss_parms(p
, 0); break;
5930 /* TIM IE is set up as separate template */
5934 len
= p
- (u8
*)templ
;
5935 templ
->fc
= cpu_to_le16(WF_FTYPE_MGMT
| fc
);
5936 /* - 2: do not count 'u16 size' field */
5937 templ
->size
= cpu_to_le16(len
- 2);
5944 #if POWER_SAVE_80211
5945 /***********************************************************************
5946 ** acx_s_set_null_data_template
5949 acx_s_set_null_data_template(acx_device_t
*adev
)
5951 struct acx_template_nullframe b
;
5956 /* memset(&b, 0, sizeof(b)); not needed, setting all members */
5958 b
.size
= cpu_to_le16(sizeof(b
) - 2);
5959 b
.hdr
.fc
= WF_FTYPE_MGMTi
| WF_FSTYPE_NULLi
;
5961 MAC_BCAST(b
.hdr
.a1
);
5962 MAC_COPY(b
.hdr
.a2
, adev
->dev_addr
);
5963 MAC_COPY(b
.hdr
.a3
, adev
->bssid
);
5966 result
= acx_s_issue_cmd(adev
, ACX1xx_CMD_CONFIG_NULL_DATA
, &b
, sizeof(b
));
5974 /***********************************************************************
5975 ** acx_s_set_beacon_template
5978 acx_s_set_beacon_template(acx_device_t
*adev
)
5980 struct acx_template_beacon bcn
;
5985 len
= acx_fill_beacon_or_proberesp_template(adev
, &bcn
, WF_FSTYPE_BEACON
);
5986 result
= acx_s_issue_cmd(adev
, ACX1xx_CMD_CONFIG_BEACON
, &bcn
, len
);
5993 /***********************************************************************
5994 ** acx_s_set_probe_response_template
5997 acx_s_set_probe_response_template(acx_device_t
*adev
)
5999 struct acx_template_proberesp pr
;
6004 len
= acx_fill_beacon_or_proberesp_template(adev
, &pr
, WF_FSTYPE_PROBERESP
);
6005 result
= acx_s_issue_cmd(adev
, ACX1xx_CMD_CONFIG_PROBE_RESPONSE
, &pr
, len
);
6012 /***********************************************************************
6013 ** acx_s_init_packet_templates()
6015 ** NOTE: order is very important here, to have a correct memory layout!
6016 ** init templates: max Probe Request (station mode), max NULL data,
6017 ** max Beacon, max TIM, max Probe Response.
6020 acx_s_init_packet_templates(acx_device_t
*adev
)
6022 acx_ie_memmap_t mm
; /* ACX100 only */
6023 int result
= NOT_OK
;
6027 log(L_DEBUG
|L_INIT
, "initializing max packet templates\n");
6029 if (OK
!= acx_s_init_max_probe_request_template(adev
))
6032 if (OK
!= acx_s_init_max_null_data_template(adev
))
6035 if (OK
!= acx_s_init_max_beacon_template(adev
))
6038 if (OK
!= acx_s_init_max_tim_template(adev
))
6041 if (OK
!= acx_s_init_max_probe_response_template(adev
))
6044 if (IS_ACX111(adev
)) {
6045 /* ACX111 doesn't need the memory map magic below,
6046 * and the other templates will be set later (acx_start) */
6051 /* ACX100 will have its TIM template set,
6052 * and we also need to update the memory map */
6054 if (OK
!= acx_s_set_tim_template(adev
))
6057 log(L_DEBUG
, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm
));
6059 if (OK
!= acx_s_interrogate(adev
, &mm
, ACX1xx_IE_MEMORY_MAP
))
6062 mm
.QueueStart
= cpu_to_le32(le32_to_cpu(mm
.PacketTemplateEnd
) + 4);
6063 if (OK
!= acx_s_configure(adev
, &mm
, ACX1xx_IE_MEMORY_MAP
))
6075 ".WEPCacheStart=0x%X\n"
6076 ".WEPCacheEnd=0x%X\n"
6077 ".PacketTemplateStart=0x%X\n"
6078 ".PacketTemplateEnd=0x%X\n",
6080 le32_to_cpu(mm
.CodeStart
),
6081 le32_to_cpu(mm
.CodeEnd
),
6082 le32_to_cpu(mm
.WEPCacheStart
),
6083 le32_to_cpu(mm
.WEPCacheEnd
),
6084 le32_to_cpu(mm
.PacketTemplateStart
),
6085 le32_to_cpu(mm
.PacketTemplateEnd
));
6088 printk("%s: %s() FAILED\n", adev
->ndev
->name
, __func__
);
6096 /***********************************************************************
6099 acx_s_set_probe_request_template(acx_device_t
*adev
)
6101 struct acx_template_probereq probereq
;
6108 memset(&probereq
, 0, sizeof(probereq
));
6110 probereq
.fc
= WF_FTYPE_MGMTi
| WF_FSTYPE_PROBEREQi
;
6111 MAC_BCAST(probereq
.da
);
6112 MAC_COPY(probereq
.sa
, adev
->dev_addr
);
6113 MAC_BCAST(probereq
.bssid
);
6115 p
= probereq
.variable
;
6116 p
= wlan_fill_ie_ssid(p
, adev
->essid_len
, adev
->essid
);
6117 p
= wlan_fill_ie_rates(p
, adev
->rate_supported_len
, adev
->rate_supported
);
6118 p
= wlan_fill_ie_rates_ext(p
, adev
->rate_supported_len
, adev
->rate_supported
);
6119 frame_len
= p
- (char*)&probereq
;
6120 probereq
.size
= cpu_to_le16(frame_len
- 2);
6122 res
= acx_s_issue_cmd(adev
, ACX1xx_CMD_CONFIG_PROBE_REQUEST
, &probereq
, frame_len
);
6129 /***********************************************************************
6133 acx_s_init_mac(acx_device_t
*adev
)
6135 int result
= NOT_OK
;
6139 if (IS_ACX111(adev
)) {
6140 adev
->ie_len
= acx111_ie_len
;
6141 adev
->ie_len_dot11
= acx111_ie_len_dot11
;
6143 adev
->ie_len
= acx100_ie_len
;
6144 adev
->ie_len_dot11
= acx100_ie_len_dot11
;
6147 #if defined (ACX_MEM)
6148 adev
->memblocksize
= 256; /* 256 is default */
6149 /* try to load radio for both ACX100 and ACX111, since both
6150 * chips have at least some firmware versions making use of an
6151 * external radio module */
6152 acxmem_s_upload_radio(adev
);
6155 adev
->memblocksize
= 256; /* 256 is default */
6156 /* try to load radio for both ACX100 and ACX111, since both
6157 * chips have at least some firmware versions making use of an
6158 * external radio module */
6159 acxpci_s_upload_radio(adev
);
6161 adev
->memblocksize
= 128;
6165 if (IS_ACX111(adev
)) {
6166 /* for ACX111, the order is different from ACX100
6167 1. init packet templates
6168 2. create station context and create dma regions
6169 3. init wep default keys
6171 if (OK
!= acx_s_init_packet_templates(adev
))
6173 if (OK
!= acx111_s_create_dma_regions(adev
)) {
6174 printk("%s: acx111_create_dma_regions FAILED\n",
6179 if (OK
!= acx100_s_init_wep(adev
))
6181 if (OK
!= acx_s_init_packet_templates(adev
))
6183 if (OK
!= acx100_s_create_dma_regions(adev
)) {
6184 printk("%s: acx100_create_dma_regions FAILED\n",
6190 MAC_COPY(adev
->ndev
->dev_addr
, adev
->dev_addr
);
6195 printk("acx: init_mac() FAILED\n");
6202 acx_s_set_sane_reg_domain(acx_device_t
*adev
, int do_set
)
6208 for (i
= 0; i
< sizeof(acx_reg_domain_ids
); i
++)
6209 if (acx_reg_domain_ids
[i
] == adev
->reg_dom_id
)
6212 if (sizeof(acx_reg_domain_ids
) == i
) {
6213 log(L_INIT
, "Invalid or unsupported regulatory domain"
6214 " 0x%02X specified, falling back to FCC (USA)!"
6215 " Please report if this sounds fishy!\n",
6218 adev
->reg_dom_id
= acx_reg_domain_ids
[i
];
6220 /* since there was a mismatch, we need to force updating */
6225 acx_ie_generic_t dom
;
6226 dom
.m
.bytes
[0] = adev
->reg_dom_id
;
6227 acx_s_configure(adev
, &dom
, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN
);
6230 adev
->reg_dom_chanmask
= reg_domain_channel_masks
[i
];
6232 mask
= (1 << (adev
->channel
- 1));
6233 if (!(adev
->reg_dom_chanmask
& mask
)) {
6234 /* hmm, need to adjust our channel to reside within domain */
6236 for (i
= 1; i
<= 14; i
++) {
6237 if (adev
->reg_dom_chanmask
& mask
) {
6238 printk("%s: adjusting selected channel from %d "
6239 "to %d due to new regulatory domain\n",
6240 adev
->ndev
->name
, adev
->channel
, i
);
6250 #if POWER_SAVE_80211
6252 acx_s_update_80211_powersave_mode(acx_device_t
*adev
)
6254 /* merge both structs in a union to be able to have common code */
6256 acx111_ie_powersave_t acx111
;
6257 acx100_ie_powersave_t acx100
;
6260 /* change 802.11 power save mode settings */
6261 log(L_INIT
, "updating 802.11 power save mode settings: "
6262 "wakeup_cfg 0x%02X, listen interval %u, "
6263 "options 0x%02X, hangover period %u, "
6264 "enhanced_ps_transition_time %u\n",
6265 adev
->ps_wakeup_cfg
, adev
->ps_listen_interval
,
6266 adev
->ps_options
, adev
->ps_hangover_period
,
6267 adev
->ps_enhanced_transition_time
);
6268 acx_s_interrogate(adev
, &pm
, ACX1xx_IE_POWER_MGMT
);
6269 log(L_INIT
, "Previous PS mode settings: wakeup_cfg 0x%02X, "
6270 "listen interval %u, options 0x%02X, "
6271 "hangover period %u, "
6272 "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
6273 pm
.acx111
.wakeup_cfg
,
6274 pm
.acx111
.listen_interval
,
6276 pm
.acx111
.hangover_period
,
6278 pm
.acx111
.enhanced_ps_transition_time
6279 : pm
.acx100
.enhanced_ps_transition_time
,
6281 pm
.acx111
.beacon_rx_time
6284 pm
.acx111
.wakeup_cfg
= adev
->ps_wakeup_cfg
;
6285 pm
.acx111
.listen_interval
= adev
->ps_listen_interval
;
6286 pm
.acx111
.options
= adev
->ps_options
;
6287 pm
.acx111
.hangover_period
= adev
->ps_hangover_period
;
6288 if (IS_ACX111(adev
)) {
6289 pm
.acx111
.beacon_rx_time
= cpu_to_le32(adev
->ps_beacon_rx_time
);
6290 pm
.acx111
.enhanced_ps_transition_time
= cpu_to_le32(adev
->ps_enhanced_transition_time
);
6292 pm
.acx100
.enhanced_ps_transition_time
= cpu_to_le16(adev
->ps_enhanced_transition_time
);
6294 acx_s_configure(adev
, &pm
, ACX1xx_IE_POWER_MGMT
);
6295 acx_s_interrogate(adev
, &pm
, ACX1xx_IE_POWER_MGMT
);
6296 log(L_INIT
, "wakeup_cfg: 0x%02X\n", pm
.acx111
.wakeup_cfg
);
6298 acx_s_interrogate(adev
, &pm
, ACX1xx_IE_POWER_MGMT
);
6299 log(L_INIT
, "wakeup_cfg: 0x%02X\n", pm
.acx111
.wakeup_cfg
);
6300 log(L_INIT
, "power save mode change %s\n",
6301 (pm
.acx111
.wakeup_cfg
& PS_CFG_PENDING
) ? "FAILED" : "was successful");
6302 /* FIXME: maybe verify via PS_CFG_PENDING bit here
6303 * that power save mode change was successful. */
6304 /* FIXME: we shouldn't trigger a scan immediately after
6305 * fiddling with power save mode (since the firmware is sending
6306 * a NULL frame then). */
6311 /***********************************************************************
6312 ** acx_s_update_card_settings
6314 ** Applies accumulated changes in various adev->xxxx members
6315 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
6316 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
6319 acx111_s_sens_radio_16_17(acx_device_t
*adev
)
6321 u32 feature1
, feature2
;
6323 if ((adev
->sensitivity
< 1) || (adev
->sensitivity
> 3)) {
6324 printk("%s: invalid sensitivity setting (1..3), "
6325 "setting to 1\n", adev
->ndev
->name
);
6326 adev
->sensitivity
= 1;
6328 acx111_s_get_feature_config(adev
, &feature1
, &feature2
);
6329 CLEAR_BIT(feature1
, FEATURE1_LOW_RX
|FEATURE1_EXTRA_LOW_RX
);
6330 if (adev
->sensitivity
> 1)
6331 SET_BIT(feature1
, FEATURE1_LOW_RX
);
6332 if (adev
->sensitivity
> 2)
6333 SET_BIT(feature1
, FEATURE1_EXTRA_LOW_RX
);
6334 acx111_s_feature_set(adev
, feature1
, feature2
);
6339 acx_s_update_card_settings(acx_device_t
*adev
)
6341 unsigned long flags
;
6342 unsigned int start_scan
= 0;
6347 log(L_INIT
, "get_mask 0x%08X, set_mask 0x%08X\n",
6348 adev
->get_mask
, adev
->set_mask
);
6350 /* Track dependencies betweed various settings */
6352 if (adev
->set_mask
& (GETSET_MODE
|GETSET_RESCAN
|GETSET_WEP
)) {
6353 log(L_INIT
, "important setting has been changed. "
6354 "Need to update packet templates, too\n");
6355 SET_BIT(adev
->set_mask
, SET_TEMPLATES
);
6357 if (adev
->set_mask
& GETSET_CHANNEL
) {
6358 /* This will actually tune RX/TX to the channel */
6359 SET_BIT(adev
->set_mask
, GETSET_RX
|GETSET_TX
);
6360 switch (adev
->mode
) {
6361 case ACX_MODE_0_ADHOC
:
6363 /* Beacons contain channel# - update them */
6364 SET_BIT(adev
->set_mask
, SET_TEMPLATES
);
6366 switch (adev
->mode
) {
6367 case ACX_MODE_0_ADHOC
:
6368 case ACX_MODE_2_STA
:
6373 /* Apply settings */
6375 #ifdef WHY_SHOULD_WE_BOTHER /* imagine we were just powered off */
6376 /* send a disassoc request in case it's required */
6377 if (adev
->set_mask
& (GETSET_MODE
|GETSET_RESCAN
|GETSET_CHANNEL
|GETSET_WEP
)) {
6378 if (ACX_MODE_2_STA
== adev
->mode
) {
6379 if (ACX_STATUS_4_ASSOCIATED
== adev
->status
) {
6380 log(L_ASSOC
, "we were ASSOCIATED - "
6381 "sending disassoc request\n");
6382 acx_lock(adev
, flags
);
6383 acx_l_transmit_disassoc(adev
, NULL
);
6384 /* FIXME: deauth? */
6385 acx_unlock(adev
, flags
);
6387 /* need to reset some other stuff as well */
6388 log(L_DEBUG
, "resetting bssid\n");
6389 MAC_ZERO(adev
->bssid
);
6390 SET_BIT(adev
->set_mask
, SET_TEMPLATES
|SET_STA_LIST
);
6396 if (adev
->get_mask
& GETSET_STATION_ID
) {
6397 u8 stationID
[4 + ACX1xx_IE_DOT11_STATION_ID_LEN
];
6400 acx_s_interrogate(adev
, &stationID
, ACX1xx_IE_DOT11_STATION_ID
);
6401 paddr
= &stationID
[4];
6402 for (i
= 0; i
< ETH_ALEN
; i
++) {
6403 /* we copy the MAC address (reversed in
6404 * the card) to the netdevice's MAC
6405 * address, and on ifup it will be
6406 * copied into iwadev->dev_addr */
6407 adev
->ndev
->dev_addr
[ETH_ALEN
- 1 - i
] = paddr
[i
];
6409 CLEAR_BIT(adev
->get_mask
, GETSET_STATION_ID
);
6412 if (adev
->get_mask
& GETSET_SENSITIVITY
) {
6413 if ((RADIO_RFMD_11
== adev
->radio_type
)
6414 || (RADIO_MAXIM_0D
== adev
->radio_type
)
6415 || (RADIO_RALINK_15
== adev
->radio_type
)) {
6416 acx_s_read_phy_reg(adev
, 0x30, &adev
->sensitivity
);
6418 log(L_INIT
, "don't know how to get sensitivity "
6419 "for radio type 0x%02X\n", adev
->radio_type
);
6420 adev
->sensitivity
= 0;
6422 log(L_INIT
, "got sensitivity value %u\n", adev
->sensitivity
);
6424 CLEAR_BIT(adev
->get_mask
, GETSET_SENSITIVITY
);
6427 if (adev
->get_mask
& GETSET_ANTENNA
) {
6428 u8 antenna
[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN
];
6430 memset(antenna
, 0, sizeof(antenna
));
6431 acx_s_interrogate(adev
, antenna
, ACX1xx_IE_DOT11_CURRENT_ANTENNA
);
6432 adev
->antenna
= antenna
[4];
6433 log(L_INIT
, "got antenna value 0x%02X\n", adev
->antenna
);
6434 CLEAR_BIT(adev
->get_mask
, GETSET_ANTENNA
);
6437 if (adev
->get_mask
& GETSET_ED_THRESH
) {
6438 if (IS_ACX100(adev
)) {
6439 u8 ed_threshold
[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN
];
6441 memset(ed_threshold
, 0, sizeof(ed_threshold
));
6442 acx_s_interrogate(adev
, ed_threshold
, ACX100_IE_DOT11_ED_THRESHOLD
);
6443 adev
->ed_threshold
= ed_threshold
[4];
6445 log(L_INIT
, "acx111 doesn't support ED\n");
6446 adev
->ed_threshold
= 0;
6448 log(L_INIT
, "got Energy Detect (ED) threshold %u\n", adev
->ed_threshold
);
6449 CLEAR_BIT(adev
->get_mask
, GETSET_ED_THRESH
);
6452 if (adev
->get_mask
& GETSET_CCA
) {
6453 if (IS_ACX100(adev
)) {
6454 u8 cca
[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN
];
6456 memset(cca
, 0, sizeof(adev
->cca
));
6457 acx_s_interrogate(adev
, cca
, ACX1xx_IE_DOT11_CURRENT_CCA_MODE
);
6460 log(L_INIT
, "acx111 doesn't support CCA\n");
6463 log(L_INIT
, "got Channel Clear Assessment (CCA) value %u\n", adev
->cca
);
6464 CLEAR_BIT(adev
->get_mask
, GETSET_CCA
);
6467 if (adev
->get_mask
& GETSET_REG_DOMAIN
) {
6468 acx_ie_generic_t dom
;
6470 acx_s_interrogate(adev
, &dom
, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN
);
6471 adev
->reg_dom_id
= dom
.m
.bytes
[0];
6472 acx_s_set_sane_reg_domain(adev
, 0);
6473 log(L_INIT
, "got regulatory domain 0x%02X\n", adev
->reg_dom_id
);
6474 CLEAR_BIT(adev
->get_mask
, GETSET_REG_DOMAIN
);
6477 if (adev
->set_mask
& GETSET_STATION_ID
) {
6478 u8 stationID
[4 + ACX1xx_IE_DOT11_STATION_ID_LEN
];
6481 paddr
= &stationID
[4];
6482 for (i
= 0; i
< ETH_ALEN
; i
++) {
6483 /* copy the MAC address we obtained when we noticed
6484 * that the ethernet iface's MAC changed
6485 * to the card (reversed in
6487 paddr
[i
] = adev
->dev_addr
[ETH_ALEN
- 1 - i
];
6489 acx_s_configure(adev
, &stationID
, ACX1xx_IE_DOT11_STATION_ID
);
6490 CLEAR_BIT(adev
->set_mask
, GETSET_STATION_ID
);
6493 if (adev
->set_mask
& SET_TEMPLATES
) {
6494 log(L_INIT
, "updating packet templates\n");
6495 switch (adev
->mode
) {
6496 case ACX_MODE_2_STA
:
6497 acx_s_set_probe_request_template(adev
);
6498 #if POWER_SAVE_80211
6499 acx_s_set_null_data_template(adev
);
6502 case ACX_MODE_0_ADHOC
:
6503 acx_s_set_probe_request_template(adev
);
6504 #if POWER_SAVE_80211
6505 /* maybe power save functionality is somehow possible
6506 * for Ad-Hoc mode, too... FIXME: verify it somehow? firmware debug fields? */
6507 acx_s_set_null_data_template(adev
);
6511 acx_s_set_beacon_template(adev
);
6512 acx_s_set_tim_template(adev
);
6513 /* BTW acx111 firmware would not send probe responses
6514 ** if probe request does not have all basic rates flagged
6515 ** by 0x80! Thus firmware does not conform to 802.11,
6516 ** it should ignore 0x80 bit in ratevector from STA.
6517 ** We can 'fix' it by not using this template and
6518 ** sending probe responses by hand. TODO --vda */
6519 acx_s_set_probe_response_template(adev
);
6521 /* Needed if generated frames are to be emitted at different tx rate now */
6522 log(L_IRQ
, "redoing cmd_join_bssid() after template cfg\n");
6523 acx_s_cmd_join_bssid(adev
, adev
->bssid
);
6524 CLEAR_BIT(adev
->set_mask
, SET_TEMPLATES
);
6526 if (adev
->set_mask
& SET_STA_LIST
) {
6527 acx_lock(adev
, flags
);
6528 acx_l_sta_list_init(adev
);
6529 CLEAR_BIT(adev
->set_mask
, SET_STA_LIST
);
6530 acx_unlock(adev
, flags
);
6532 if (adev
->set_mask
& SET_RATE_FALLBACK
) {
6533 u8 rate
[4 + ACX1xx_IE_RATE_FALLBACK_LEN
];
6535 /* configure to not do fallbacks when not in auto rate mode */
6536 rate
[4] = (adev
->rate_auto
) ? /* adev->txrate_fallback_retries */ 1 : 0;
6537 log(L_INIT
, "updating Tx fallback to %u retries\n", rate
[4]);
6538 acx_s_configure(adev
, &rate
, ACX1xx_IE_RATE_FALLBACK
);
6539 CLEAR_BIT(adev
->set_mask
, SET_RATE_FALLBACK
);
6541 if (adev
->set_mask
& GETSET_TXPOWER
) {
6542 log(L_INIT
, "updating transmit power: %u dBm\n",
6543 adev
->tx_level_dbm
);
6544 acx_s_set_tx_level(adev
, adev
->tx_level_dbm
);
6545 CLEAR_BIT(adev
->set_mask
, GETSET_TXPOWER
);
6548 if (adev
->set_mask
& GETSET_SENSITIVITY
) {
6549 log(L_INIT
, "updating sensitivity value: %u\n",
6551 switch (adev
->radio_type
) {
6553 case RADIO_MAXIM_0D
:
6554 case RADIO_RALINK_15
:
6555 acx_s_write_phy_reg(adev
, 0x30, adev
->sensitivity
);
6557 case RADIO_RADIA_16
:
6558 case RADIO_UNKNOWN_17
:
6559 acx111_s_sens_radio_16_17(adev
);
6562 log(L_INIT
, "don't know how to modify sensitivity "
6563 "for radio type 0x%02X\n", adev
->radio_type
);
6565 CLEAR_BIT(adev
->set_mask
, GETSET_SENSITIVITY
);
6568 if (adev
->set_mask
& GETSET_ANTENNA
) {
6570 u8 antenna
[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN
];
6572 memset(antenna
, 0, sizeof(antenna
));
6573 antenna
[4] = adev
->antenna
;
6574 log(L_INIT
, "updating antenna value: 0x%02X\n",
6576 acx_s_configure(adev
, &antenna
, ACX1xx_IE_DOT11_CURRENT_ANTENNA
);
6577 CLEAR_BIT(adev
->set_mask
, GETSET_ANTENNA
);
6580 if (adev
->set_mask
& GETSET_ED_THRESH
) {
6582 log(L_INIT
, "updating Energy Detect (ED) threshold: %u\n",
6583 adev
->ed_threshold
);
6584 if (IS_ACX100(adev
)) {
6585 u8 ed_threshold
[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN
];
6587 memset(ed_threshold
, 0, sizeof(ed_threshold
));
6588 ed_threshold
[4] = adev
->ed_threshold
;
6589 acx_s_configure(adev
, &ed_threshold
, ACX100_IE_DOT11_ED_THRESHOLD
);
6592 log(L_INIT
, "acx111 doesn't support ED!\n");
6593 CLEAR_BIT(adev
->set_mask
, GETSET_ED_THRESH
);
6596 if (adev
->set_mask
& GETSET_CCA
) {
6598 log(L_INIT
, "updating Channel Clear Assessment "
6599 "(CCA) value: 0x%02X\n", adev
->cca
);
6600 if (IS_ACX100(adev
)) {
6601 u8 cca
[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN
];
6603 memset(cca
, 0, sizeof(cca
));
6605 acx_s_configure(adev
, &cca
, ACX1xx_IE_DOT11_CURRENT_CCA_MODE
);
6608 log(L_INIT
, "acx111 doesn't support CCA!\n");
6609 CLEAR_BIT(adev
->set_mask
, GETSET_CCA
);
6612 if (adev
->set_mask
& GETSET_LED_POWER
) {
6614 log(L_INIT
, "updating power LED status: %u\n", adev
->led_power
);
6616 acx_lock(adev
, flags
);
6617 #if defined (ACX_MEM)
6618 acxmem_l_power_led(adev
, adev
->led_power
);
6621 acxpci_l_power_led(adev
, adev
->led_power
);
6623 CLEAR_BIT(adev
->set_mask
, GETSET_LED_POWER
);
6624 acx_unlock(adev
, flags
);
6627 if (adev
->set_mask
& GETSET_POWER_80211
) {
6628 #if POWER_SAVE_80211
6629 acx_s_update_80211_powersave_mode(adev
);
6631 CLEAR_BIT(adev
->set_mask
, GETSET_POWER_80211
);
6634 if (adev
->set_mask
& GETSET_CHANNEL
) {
6636 log(L_INIT
, "updating channel to: %u\n", adev
->channel
);
6637 CLEAR_BIT(adev
->set_mask
, GETSET_CHANNEL
);
6640 if (adev
->set_mask
& GETSET_RETRY
) {
6641 u8 short_retry
[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN
];
6642 u8 long_retry
[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN
];
6644 log(L_INIT
, "updating short retry limit: %u, long retry limit: %u\n",
6645 adev
->short_retry
, adev
->long_retry
);
6646 short_retry
[0x4] = adev
->short_retry
;
6647 long_retry
[0x4] = adev
->long_retry
;
6648 acx_s_configure(adev
, &short_retry
, ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT
);
6649 acx_s_configure(adev
, &long_retry
, ACX1xx_IE_DOT11_LONG_RETRY_LIMIT
);
6650 CLEAR_BIT(adev
->set_mask
, GETSET_RETRY
);
6653 if (adev
->set_mask
& SET_MSDU_LIFETIME
) {
6654 u8 xmt_msdu_lifetime
[4 + ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN
];
6656 log(L_INIT
, "updating tx MSDU lifetime: %u\n",
6657 adev
->msdu_lifetime
);
6658 *(u32
*)&xmt_msdu_lifetime
[4] = cpu_to_le32((u32
)adev
->msdu_lifetime
);
6659 acx_s_configure(adev
, &xmt_msdu_lifetime
, ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME
);
6660 CLEAR_BIT(adev
->set_mask
, SET_MSDU_LIFETIME
);
6663 if (adev
->set_mask
& GETSET_REG_DOMAIN
) {
6664 log(L_INIT
, "updating regulatory domain: 0x%02X\n",
6666 acx_s_set_sane_reg_domain(adev
, 1);
6667 CLEAR_BIT(adev
->set_mask
, GETSET_REG_DOMAIN
);
6670 if (adev
->set_mask
& GETSET_MODE
) {
6671 adev
->ndev
->type
= (adev
->mode
== ACX_MODE_MONITOR
) ?
6672 adev
->monitor_type
: ARPHRD_ETHER
;
6674 switch (adev
->mode
) {
6677 acx_lock(adev
, flags
);
6678 acx_l_sta_list_init(adev
);
6680 adev
->ap_client
= NULL
;
6681 MAC_COPY(adev
->bssid
, adev
->dev_addr
);
6682 /* this basically says "we're connected" */
6683 acx_set_status(adev
, ACX_STATUS_4_ASSOCIATED
);
6684 acx_unlock(adev
, flags
);
6686 acx111_s_feature_off(adev
, 0, FEATURE2_NO_TXCRYPT
|FEATURE2_SNIFFER
);
6687 /* start sending beacons */
6688 acx_s_cmd_join_bssid(adev
, adev
->bssid
);
6690 case ACX_MODE_MONITOR
:
6691 acx111_s_feature_on(adev
, 0, FEATURE2_NO_TXCRYPT
|FEATURE2_SNIFFER
);
6692 /* this stops beacons */
6693 acx_s_cmd_join_bssid(adev
, adev
->bssid
);
6694 /* this basically says "we're connected" */
6695 acx_set_status(adev
, ACX_STATUS_4_ASSOCIATED
);
6696 SET_BIT(adev
->set_mask
, SET_RXCONFIG
|SET_WEP_OPTIONS
);
6698 case ACX_MODE_0_ADHOC
:
6699 case ACX_MODE_2_STA
:
6700 acx111_s_feature_off(adev
, 0, FEATURE2_NO_TXCRYPT
|FEATURE2_SNIFFER
);
6702 acx_lock(adev
, flags
);
6704 adev
->ap_client
= NULL
;
6705 acx_unlock(adev
, flags
);
6707 /* we want to start looking for peer or AP */
6711 /* TODO: disable RX/TX, stop any scanning activity etc: */
6712 /* adev->tx_disabled = 1; */
6713 /* SET_BIT(adev->set_mask, GETSET_RX|GETSET_TX); */
6715 /* This stops beacons (invalid macmode...) */
6716 acx_s_cmd_join_bssid(adev
, adev
->bssid
);
6717 acx_set_status(adev
, ACX_STATUS_0_STOPPED
);
6720 CLEAR_BIT(adev
->set_mask
, GETSET_MODE
);
6723 if (adev
->set_mask
& SET_RXCONFIG
) {
6724 acx_s_initialize_rx_config(adev
);
6725 CLEAR_BIT(adev
->set_mask
, SET_RXCONFIG
);
6728 if (adev
->set_mask
& GETSET_RESCAN
) {
6729 switch (adev
->mode
) {
6730 case ACX_MODE_0_ADHOC
:
6731 case ACX_MODE_2_STA
:
6735 CLEAR_BIT(adev
->set_mask
, GETSET_RESCAN
);
6739 * SET_WEP_OPTIONS must be before GETSET_WEP. The driver sets all options on
6740 * resume from suspend, and setting WEP options clears the keys.
6742 if (adev
->set_mask
& SET_WEP_OPTIONS
) {
6743 acx100_ie_wep_options_t options
;
6745 if (IS_ACX111(adev
)) {
6746 log(L_DEBUG
, "setting WEP Options for acx111 is not supported\n");
6748 log(L_INIT
, "setting WEP Options\n");
6750 /* let's choose maximum setting: 4 default keys,
6751 * plus 10 other keys: */
6752 options
.NumKeys
= cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS
+ 10);
6753 /* don't decrypt default key only,
6754 * don't override decryption: */
6755 options
.WEPOption
= 0;
6756 if (adev
->mode
== ACX_MODE_MONITOR
) {
6757 /* don't decrypt default key only,
6758 * override decryption mechanism: */
6759 options
.WEPOption
= 2;
6762 acx_s_configure(adev
, &options
, ACX100_IE_WEP_OPTIONS
);
6764 CLEAR_BIT(adev
->set_mask
, SET_WEP_OPTIONS
);
6767 if (adev
->set_mask
& GETSET_WEP
) {
6770 ie_dot11WEPDefaultKeyID_t dkey
;
6776 } ACX_PACKED keyindic
;
6778 log(L_INIT
, "updating WEP key settings\n");
6780 acx_s_set_wepkey(adev
);
6782 dkey
.KeyID
= adev
->wep_current_index
;
6783 log(L_INIT
, "setting WEP key %u as default\n", dkey
.KeyID
);
6784 acx_s_configure(adev
, &dkey
, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET
);
6787 acx_s_configure(adev
, &keyindic
, ACX111_IE_KEY_CHOOSE
);
6790 CLEAR_BIT(adev
->set_mask
, GETSET_WEP
);
6794 if (adev
->set_mask
& GETSET_TX
) {
6796 log(L_INIT
, "updating: %s Tx\n",
6797 adev
->tx_disabled
? "disable" : "enable");
6798 if (adev
->tx_disabled
)
6799 acx_s_issue_cmd(adev
, ACX1xx_CMD_DISABLE_TX
, NULL
, 0);
6801 acx_s_issue_cmd(adev
, ACX1xx_CMD_ENABLE_TX
, &adev
->channel
, 1);
6802 CLEAR_BIT(adev
->set_mask
, GETSET_TX
);
6806 * Really want to start RX last. In a busy RF environment it causes problems to
6807 * enable receive before the rest of the configuration parameters are finished.
6809 if (adev
->set_mask
& GETSET_RX
) {
6811 log(L_INIT
, "updating: enable Rx on channel: %u\n",
6813 acx_s_issue_cmd(adev
, ACX1xx_CMD_ENABLE_RX
, &adev
->channel
, 1);
6814 CLEAR_BIT(adev
->set_mask
, GETSET_RX
);
6817 /* Rescan was requested */
6819 switch (adev
->mode
) {
6820 case ACX_MODE_0_ADHOC
:
6821 case ACX_MODE_2_STA
:
6822 /* We can avoid clearing list if join code
6823 ** will be a bit more clever about not picking
6824 ** 'bad' AP over and over again */
6825 acx_lock(adev
, flags
);
6826 adev
->ap_client
= NULL
;
6827 acx_l_sta_list_init(adev
);
6828 acx_set_status(adev
, ACX_STATUS_1_SCANNING
);
6829 acx_unlock(adev
, flags
);
6831 acx_s_cmd_start_scan(adev
);
6835 /* debug, rate, and nick don't need any handling */
6836 /* what about sniffing mode?? */
6838 log(L_INIT
, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
6839 adev
->get_mask
, adev
->set_mask
);
6846 /***********************************************************************
6847 ** acx_e_after_interrupt_task
6850 acx_s_recalib_radio(acx_device_t
*adev
)
6852 if (IS_ACX111(adev
)) {
6853 acx111_cmd_radiocalib_t cal
;
6855 printk("%s: recalibrating radio\n", adev
->ndev
->name
);
6856 /* automatic recalibration, choose all methods: */
6857 cal
.methods
= cpu_to_le32(0x8000000f);
6858 /* automatic recalibration every 60 seconds (value in TUs)
6859 * I wonder what the firmware default here is? */
6860 cal
.interval
= cpu_to_le32(58594);
6861 return acx_s_issue_cmd_timeo(adev
, ACX111_CMD_RADIOCALIB
,
6862 &cal
, sizeof(cal
), CMD_TIMEOUT_MS(100));
6864 /* On ACX100, we need to recalibrate the radio
6865 * by issuing a GETSET_TX|GETSET_RX */
6866 if (/* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
6867 (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
6868 (OK
== acx_s_issue_cmd(adev
, ACX1xx_CMD_ENABLE_TX
, &adev
->channel
, 1)) &&
6869 (OK
== acx_s_issue_cmd(adev
, ACX1xx_CMD_ENABLE_RX
, &adev
->channel
, 1)) )
6876 acx_s_after_interrupt_recalib(acx_device_t
*adev
)
6880 /* this helps with ACX100 at least;
6881 * hopefully ACX111 also does a
6882 * recalibration here */
6884 /* clear flag beforehand, since we want to make sure
6885 * it's cleared; then only set it again on specific circumstances */
6886 CLEAR_BIT(adev
->after_interrupt_jobs
, ACX_AFTER_IRQ_CMD_RADIO_RECALIB
);
6888 /* better wait a bit between recalibrations to
6889 * prevent overheating due to torturing the card
6890 * into working too long despite high temperature
6891 * (just a safety measure) */
6892 if (adev
->recalib_time_last_success
6893 && time_before(jiffies
, adev
->recalib_time_last_success
6894 + RECALIB_PAUSE
* 60 * HZ
)) {
6895 if (adev
->recalib_msg_ratelimit
<= 4) {
6896 printk("%s: less than " STRING(RECALIB_PAUSE
)
6897 " minutes since last radio recalibration, "
6898 "not recalibrating (maybe card is too hot?)\n",
6900 adev
->recalib_msg_ratelimit
++;
6901 if (adev
->recalib_msg_ratelimit
== 5)
6902 printk("disabling above message\n");
6907 adev
->recalib_msg_ratelimit
= 0;
6909 /* note that commands sometimes fail (card busy),
6910 * so only clear flag if we were fully successful */
6911 res
= acx_s_recalib_radio(adev
);
6913 printk("%s: successfully recalibrated radio\n",
6915 adev
->recalib_time_last_success
= jiffies
;
6916 adev
->recalib_failure_count
= 0;
6918 /* failed: resubmit, but only limited
6919 * amount of times within some time range
6920 * to prevent endless loop */
6922 adev
->recalib_time_last_success
= 0; /* we failed */
6924 /* if some time passed between last
6925 * attempts, then reset failure retry counter
6926 * to be able to do next recalib attempt */
6927 if (time_after(jiffies
, adev
->recalib_time_last_attempt
+ 5*HZ
))
6928 adev
->recalib_failure_count
= 0;
6930 if (adev
->recalib_failure_count
< 5) {
6931 /* increment inside only, for speedup of outside path */
6932 adev
->recalib_failure_count
++;
6933 adev
->recalib_time_last_attempt
= jiffies
;
6934 acx_schedule_task(adev
, ACX_AFTER_IRQ_CMD_RADIO_RECALIB
);
6940 acx_e_after_interrupt_task(void *data
)
6942 struct net_device
*ndev
= (struct net_device
*)data
;
6943 acx_device_t
*adev
= ndev2adev(ndev
);
6949 if (!adev
->after_interrupt_jobs
)
6950 goto end
; /* no jobs to do */
6952 #if TX_CLEANUP_IN_SOFTIRQ
6953 /* can happen only on PCI */
6954 if (adev
->after_interrupt_jobs
& ACX_AFTER_IRQ_TX_CLEANUP
) {
6955 acx_lock(adev
, flags
);
6956 acxpci_l_clean_txdesc(adev
);
6957 CLEAR_BIT(adev
->after_interrupt_jobs
, ACX_AFTER_IRQ_TX_CLEANUP
);
6958 acx_unlock(adev
, flags
);
6961 /* we see lotsa tx errors */
6962 if (adev
->after_interrupt_jobs
& ACX_AFTER_IRQ_CMD_RADIO_RECALIB
) {
6963 acx_s_after_interrupt_recalib(adev
);
6966 /* a poor interrupt code wanted to do update_card_settings() */
6967 if (adev
->after_interrupt_jobs
& ACX_AFTER_IRQ_UPDATE_CARD_CFG
) {
6968 if (ACX_STATE_IFACE_UP
& adev
->dev_state_mask
)
6969 acx_s_update_card_settings(adev
);
6970 CLEAR_BIT(adev
->after_interrupt_jobs
, ACX_AFTER_IRQ_UPDATE_CARD_CFG
);
6973 /* 1) we detected that no Scan_Complete IRQ came from fw, or
6974 ** 2) we found too many STAs */
6975 if (adev
->after_interrupt_jobs
& ACX_AFTER_IRQ_CMD_STOP_SCAN
) {
6976 log(L_IRQ
, "sending a stop scan cmd...\n");
6977 acx_s_issue_cmd(adev
, ACX1xx_CMD_STOP_SCAN
, NULL
, 0);
6978 /* HACK: set the IRQ bit, since we won't get a
6979 * scan complete IRQ any more on ACX111 (works on ACX100!),
6980 * since _we_, not a fw, have stopped the scan */
6981 SET_BIT(adev
->irq_status
, HOST_INT_SCAN_COMPLETE
);
6982 CLEAR_BIT(adev
->after_interrupt_jobs
, ACX_AFTER_IRQ_CMD_STOP_SCAN
);
6985 /* either fw sent Scan_Complete or we detected that
6986 ** no Scan_Complete IRQ came from fw. Finish scanning,
6987 ** pick join partner if any */
6988 if (adev
->after_interrupt_jobs
& ACX_AFTER_IRQ_COMPLETE_SCAN
) {
6989 if (adev
->status
== ACX_STATUS_1_SCANNING
) {
6990 if (OK
!= acx_s_complete_scan(adev
)) {
6991 SET_BIT(adev
->after_interrupt_jobs
,
6992 ACX_AFTER_IRQ_RESTART_SCAN
);
6995 /* + scan kills current join status - restore it
6996 ** (do we need it for STA?) */
6997 /* + does it happen only with active scans?
6998 ** active and passive scans? ALL scans including
6999 ** background one? */
7000 /* + was not verified that everything is restored
7001 ** (but at least we start to emit beacons again) */
7002 switch (adev
->mode
) {
7003 case ACX_MODE_0_ADHOC
:
7005 log(L_IRQ
, "redoing cmd_join_bssid() after scan\n");
7006 acx_s_cmd_join_bssid(adev
, adev
->bssid
);
7009 CLEAR_BIT(adev
->after_interrupt_jobs
, ACX_AFTER_IRQ_COMPLETE_SCAN
);
7012 /* STA auth or assoc timed out, start over again */
7013 if (adev
->after_interrupt_jobs
& ACX_AFTER_IRQ_RESTART_SCAN
) {
7014 log(L_IRQ
, "sending a start_scan cmd...\n");
7015 acx_s_cmd_start_scan(adev
);
7016 CLEAR_BIT(adev
->after_interrupt_jobs
, ACX_AFTER_IRQ_RESTART_SCAN
);
7019 /* whee, we got positive assoc response! 8) */
7020 if (adev
->after_interrupt_jobs
& ACX_AFTER_IRQ_CMD_ASSOCIATE
) {
7021 acx_ie_generic_t pdr
;
7022 /* tiny race window exists, checking that we still a STA */
7023 switch (adev
->mode
) {
7024 case ACX_MODE_2_STA
:
7025 pdr
.m
.aid
= cpu_to_le16(adev
->aid
);
7026 acx_s_configure(adev
, &pdr
, ACX1xx_IE_ASSOC_ID
);
7027 acx_set_status(adev
, ACX_STATUS_4_ASSOCIATED
);
7028 log(L_ASSOC
|L_DEBUG
, "ASSOCIATED!\n");
7029 CLEAR_BIT(adev
->after_interrupt_jobs
, ACX_AFTER_IRQ_CMD_ASSOCIATE
);
7033 acx_sem_unlock(adev
);
7038 /***********************************************************************
7039 ** acx_schedule_task
7041 ** Schedule the call of the after_interrupt method after leaving
7042 ** the interrupt context.
7045 acx_schedule_task(acx_device_t
*adev
, unsigned int set_flag
)
7047 SET_BIT(adev
->after_interrupt_jobs
, set_flag
);
7048 SCHEDULE_WORK(&adev
->after_interrupt_task
);
7052 /***********************************************************************
7055 acx_init_task_scheduler(acx_device_t
*adev
)
7057 /* configure task scheduler */
7058 INIT_WORK(&adev
->after_interrupt_task
, acx_e_after_interrupt_task
,
7063 /***********************************************************************
7067 acx_s_start(acx_device_t
*adev
)
7072 * Ok, now we do everything that can possibly be done with ioctl
7073 * calls to make sure that when it was called before the card
7074 * was up we get the changes asked for
7077 SET_BIT(adev
->set_mask
, SET_TEMPLATES
|SET_STA_LIST
|GETSET_WEP
7078 |GETSET_TXPOWER
|GETSET_ANTENNA
|GETSET_ED_THRESH
|GETSET_CCA
7079 |GETSET_REG_DOMAIN
|GETSET_MODE
|GETSET_CHANNEL
7080 |GETSET_TX
|GETSET_RX
);
7082 log(L_INIT
, "updating initial settings on iface activation\n");
7083 acx_s_update_card_settings(adev
);
7089 /***********************************************************************
7090 ** acx_update_capabilities
7093 acx_update_capabilities(acx_device_t
*adev
)
7097 switch (adev
->mode
) {
7099 SET_BIT(cap
, WF_MGMT_CAP_ESS
); break;
7100 case ACX_MODE_0_ADHOC
:
7101 SET_BIT(cap
, WF_MGMT_CAP_IBSS
); break;
7102 /* other types of stations do not emit beacons */
7105 if (adev
->wep_restricted
) {
7106 SET_BIT(cap
, WF_MGMT_CAP_PRIVACY
);
7108 if (adev
->cfgopt_dot11ShortPreambleOption
) {
7109 SET_BIT(cap
, WF_MGMT_CAP_SHORT
);
7111 if (adev
->cfgopt_dot11PBCCOption
) {
7112 SET_BIT(cap
, WF_MGMT_CAP_PBCC
);
7114 if (adev
->cfgopt_dot11ChannelAgility
) {
7115 SET_BIT(cap
, WF_MGMT_CAP_AGILITY
);
7117 log(L_DEBUG
, "caps updated from 0x%04X to 0x%04X\n",
7118 adev
->capabilities
, cap
);
7119 adev
->capabilities
= cap
;
7122 /***********************************************************************
7123 ** Common function to parse ALL configoption struct formats
7124 ** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
7125 ** FIXME: logging should be removed here and added to a /proc file instead
7128 acx_s_parse_configoption(acx_device_t
*adev
, const acx111_ie_configoption_t
*pcfg
)
7132 int is_acx111
= IS_ACX111(adev
);
7134 if (acx_debug
& L_DEBUG
) {
7135 printk("configoption struct content:\n");
7136 acx_dump_bytes(pcfg
, sizeof(*pcfg
));
7139 if (( is_acx111
&& (adev
->eeprom_version
== 5))
7140 || (!is_acx111
&& (adev
->eeprom_version
== 4))
7141 || (!is_acx111
&& (adev
->eeprom_version
== 5))) {
7142 /* these versions are known to be supported */
7144 printk("unknown chip and EEPROM version combination (%s, v%d), "
7145 "don't know how to parse config options yet. "
7146 "Please report\n", is_acx111
? "ACX111" : "ACX100",
7147 adev
->eeprom_version
);
7151 /* first custom-parse the first part which has chip-specific layout */
7153 pEle
= (const u8
*) pcfg
;
7155 pEle
+= 4; /* skip (type,len) header */
7157 memcpy(adev
->cfgopt_NVSv
, pEle
, sizeof(adev
->cfgopt_NVSv
));
7158 pEle
+= sizeof(adev
->cfgopt_NVSv
);
7161 adev
->cfgopt_NVS_vendor_offs
= le16_to_cpu(*(u16
*)pEle
);
7162 pEle
+= sizeof(adev
->cfgopt_NVS_vendor_offs
);
7164 adev
->cfgopt_probe_delay
= 200; /* good default value? */
7165 pEle
+= 2; /* FIXME: unknown, value 0x0001 */
7167 memcpy(adev
->cfgopt_MAC
, pEle
, sizeof(adev
->cfgopt_MAC
));
7168 pEle
+= sizeof(adev
->cfgopt_MAC
);
7170 adev
->cfgopt_probe_delay
= le16_to_cpu(*(u16
*)pEle
);
7171 pEle
+= sizeof(adev
->cfgopt_probe_delay
);
7172 if ((adev
->cfgopt_probe_delay
< 100) || (adev
->cfgopt_probe_delay
> 500)) {
7173 printk("strange probe_delay value %d, "
7174 "tweaking to 200\n", adev
->cfgopt_probe_delay
);
7175 adev
->cfgopt_probe_delay
= 200;
7179 adev
->cfgopt_eof_memory
= le32_to_cpu(*(u32
*)pEle
);
7180 pEle
+= sizeof(adev
->cfgopt_eof_memory
);
7182 printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n",
7183 adev
->cfgopt_NVS_vendor_offs
,
7184 adev
->cfgopt_probe_delay
,
7185 adev
->cfgopt_eof_memory
);
7187 adev
->cfgopt_dot11CCAModes
= *pEle
++;
7188 adev
->cfgopt_dot11Diversity
= *pEle
++;
7189 adev
->cfgopt_dot11ShortPreambleOption
= *pEle
++;
7190 adev
->cfgopt_dot11PBCCOption
= *pEle
++;
7191 adev
->cfgopt_dot11ChannelAgility
= *pEle
++;
7192 adev
->cfgopt_dot11PhyType
= *pEle
++;
7193 adev
->cfgopt_dot11TempType
= *pEle
++;
7194 printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
7195 "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
7196 adev
->cfgopt_dot11CCAModes
,
7197 adev
->cfgopt_dot11Diversity
,
7198 adev
->cfgopt_dot11ShortPreambleOption
,
7199 adev
->cfgopt_dot11PBCCOption
,
7200 adev
->cfgopt_dot11ChannelAgility
,
7201 adev
->cfgopt_dot11PhyType
,
7202 adev
->cfgopt_dot11TempType
);
7204 /* then use common parsing for next part which has common layout */
7206 pEle
++; /* skip table_count (6) */
7208 if (IS_MEM(adev
) && IS_ACX100(adev
))
7211 * For iPaq hx4700 Generic Slave F/W 1.10.7.K. I'm not sure if these
7212 * 4 extra bytes are before the dot11 things above or after, so I'm just
7213 * going to guess after. If someone sees these aren't reasonable numbers,
7215 * The area from which the dot11 values above are read contains:
7216 * 04 01 01 01 00 05 01 06 00 02 01 02
7217 * the 8 dot11 reads above take care of 8 of them, but which 8...
7222 adev
->cfgopt_antennas
.type
= pEle
[0];
7223 adev
->cfgopt_antennas
.len
= pEle
[1];
7224 printk("AntennaID:%02X Len:%02X Data:",
7225 adev
->cfgopt_antennas
.type
, adev
->cfgopt_antennas
.len
);
7226 for (i
= 0; i
< pEle
[1]; i
++) {
7227 adev
->cfgopt_antennas
.list
[i
] = pEle
[i
+2];
7228 printk("%02X ", pEle
[i
+2]);
7232 pEle
+= pEle
[1] + 2;
7233 adev
->cfgopt_power_levels
.type
= pEle
[0];
7234 adev
->cfgopt_power_levels
.len
= pEle
[1];
7235 printk("PowerLevelID:%02X Len:%02X Data:",
7236 adev
->cfgopt_power_levels
.type
, adev
->cfgopt_power_levels
.len
);
7237 for (i
= 0; i
< pEle
[1]; i
++) {
7238 adev
->cfgopt_power_levels
.list
[i
] = le16_to_cpu(*(u16
*)&pEle
[i
*2+2]);
7239 printk("%04X ", adev
->cfgopt_power_levels
.list
[i
]);
7243 pEle
+= pEle
[1]*2 + 2;
7244 adev
->cfgopt_data_rates
.type
= pEle
[0];
7245 adev
->cfgopt_data_rates
.len
= pEle
[1];
7246 printk("DataRatesID:%02X Len:%02X Data:",
7247 adev
->cfgopt_data_rates
.type
, adev
->cfgopt_data_rates
.len
);
7248 for (i
= 0; i
< pEle
[1]; i
++) {
7249 adev
->cfgopt_data_rates
.list
[i
] = pEle
[i
+2];
7250 printk("%02X ", pEle
[i
+2]);
7254 pEle
+= pEle
[1] + 2;
7255 adev
->cfgopt_domains
.type
= pEle
[0];
7256 adev
->cfgopt_domains
.len
= pEle
[1];
7257 if (IS_MEM(adev
) && IS_ACX100(adev
))
7260 * For iPaq hx4700 Generic Slave F/W 1.10.7.K.
7261 * There's an extra byte between this structure and the next
7262 * that is not accounted for with this structure's length. It's
7263 * most likely a bug in the firmware, but we can fix it here
7264 * by bumping the length of this field by 1.
7266 adev
->cfgopt_domains
.len
++;
7268 printk("DomainID:%02X Len:%02X Data:",
7269 adev
->cfgopt_domains
.type
, adev
->cfgopt_domains
.len
);
7270 for (i
= 0; i
< adev
->cfgopt_domains
.len
; i
++) {
7271 adev
->cfgopt_domains
.list
[i
] = pEle
[i
+2];
7272 printk("%02X ", pEle
[i
+2]);
7276 pEle
+= adev
->cfgopt_domains
.len
+ 2;
7278 adev
->cfgopt_product_id
.type
= pEle
[0];
7279 adev
->cfgopt_product_id
.len
= pEle
[1];
7280 for (i
= 0; i
< pEle
[1]; i
++) {
7281 adev
->cfgopt_product_id
.list
[i
] = pEle
[i
+2];
7283 printk("ProductID:%02X Len:%02X Data:%.*s\n",
7284 adev
->cfgopt_product_id
.type
, adev
->cfgopt_product_id
.len
,
7285 adev
->cfgopt_product_id
.len
, (char *)adev
->cfgopt_product_id
.list
);
7287 pEle
+= pEle
[1] + 2;
7288 adev
->cfgopt_manufacturer
.type
= pEle
[0];
7289 adev
->cfgopt_manufacturer
.len
= pEle
[1];
7290 for (i
= 0; i
< pEle
[1]; i
++) {
7291 adev
->cfgopt_manufacturer
.list
[i
] = pEle
[i
+2];
7293 printk("ManufacturerID:%02X Len:%02X Data:%.*s\n",
7294 adev
->cfgopt_manufacturer
.type
, adev
->cfgopt_manufacturer
.len
,
7295 adev
->cfgopt_manufacturer
.len
, (char *)adev
->cfgopt_manufacturer
.list
);
7297 printk("EEPROM part:\n");
7298 for (i=0; i<58; i++) {
7299 printk("%02X =======> 0x%02X\n",
7300 i, (u8 *)adev->cfgopt_NVSv[i-2]);
7306 /***********************************************************************
7309 acx_e_init_module(void)
7313 acx_struct_size_check();
7315 printk("acx: this driver is still EXPERIMENTAL\n"
7316 "acx: reading README file and/or Craig's HOWTO is "
7317 "recommended, visit http://acx100.sf.net in case "
7318 "of further questions/discussion\n");
7320 #if defined(CONFIG_ACX_PCI)
7321 r1
= acxpci_e_init_module();
7325 #if defined(CONFIG_ACX_MEM)
7326 r2
= acxmem_e_init_module();
7330 #if defined(CONFIG_ACX_USB)
7331 r3
= acxusb_e_init_module();
7335 if (r2
&& r1
&& r3
) { /* all failed! */
7337 return r3
? r3
: r1
;
7341 /* return success if at least one succeeded */
7346 acx_e_cleanup_module(void)
7348 #if defined(CONFIG_ACX_PCI)
7349 acxpci_e_cleanup_module();
7351 #if defined(CONFIG_ACX_MEM)
7352 acxmem_e_cleanup_module();
7354 #if defined(CONFIG_ACX_USB)
7355 acxusb_e_cleanup_module();
7359 module_init(acx_e_init_module
)
7360 module_exit(acx_e_cleanup_module
)