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/config.h>
34 #include <linux/version.h>
35 #include <linux/module.h>
36 #include <linux/kernel.h>
37 #include <linux/sched.h>
38 #include <linux/types.h>
39 #include <linux/slab.h>
40 #include <linux/delay.h>
41 #include <linux/proc_fs.h>
42 #include <linux/if_arp.h>
43 #include <linux/rtnetlink.h>
44 #include <linux/netdevice.h>
45 #include <linux/etherdevice.h>
46 #include <linux/wireless.h>
48 #if WIRELESS_EXT >= 13
49 #include <net/iw_handler.h>
55 /***********************************************************************
57 static client_t
*acx_l_sta_list_alloc(wlandevice_t
*priv
);
58 static client_t
*acx_l_sta_list_get_from_hash(wlandevice_t
*priv
, const u8
*address
);
60 static int acx_l_process_data_frame_master(wlandevice_t
*priv
, rxbuffer_t
*rxbuf
);
61 static int acx_l_process_data_frame_client(wlandevice_t
*priv
, rxbuffer_t
*rxbuf
);
62 /* static int acx_l_process_NULL_frame(wlandevice_t *priv, rxbuffer_t *rxbuf, int vala); */
63 static int acx_l_process_mgmt_frame(wlandevice_t
*priv
, rxbuffer_t
*rxbuf
);
64 static void acx_l_process_disassoc_from_sta(wlandevice_t
*priv
, const wlan_fr_disassoc_t
*req
);
65 static void acx_l_process_disassoc_from_ap(wlandevice_t
*priv
, const wlan_fr_disassoc_t
*req
);
66 static void acx_l_process_deauth_from_sta(wlandevice_t
*priv
, const wlan_fr_deauthen_t
*req
);
67 static void acx_l_process_deauth_from_ap(wlandevice_t
*priv
, const wlan_fr_deauthen_t
*req
);
68 static int acx_l_process_probe_response(wlandevice_t
*priv
, wlan_fr_proberesp_t
*req
, const rxbuffer_t
*rxbuf
);
69 static int acx_l_process_assocresp(wlandevice_t
*priv
, const wlan_fr_assocresp_t
*req
);
70 static int acx_l_process_reassocresp(wlandevice_t
*priv
, const wlan_fr_reassocresp_t
*req
);
71 static int acx_l_process_authen(wlandevice_t
*priv
, const wlan_fr_authen_t
*req
);
72 static int acx_l_transmit_assocresp(wlandevice_t
*priv
, const wlan_fr_assocreq_t
*req
);
73 static int acx_l_transmit_reassocresp(wlandevice_t
*priv
, const wlan_fr_reassocreq_t
*req
);
74 static int acx_l_transmit_deauthen(wlandevice_t
*priv
, const u8
*addr
, u16 reason
);
75 static int acx_l_transmit_authen1(wlandevice_t
*priv
);
76 static int acx_l_transmit_authen2(wlandevice_t
*priv
, const wlan_fr_authen_t
*req
, client_t
*clt
);
77 static int acx_l_transmit_authen3(wlandevice_t
*priv
, const wlan_fr_authen_t
*req
);
78 static int acx_l_transmit_authen4(wlandevice_t
*priv
, const wlan_fr_authen_t
*req
);
79 static int acx_l_transmit_assoc_req(wlandevice_t
*priv
);
82 /***********************************************************************
85 unsigned int acx_debug
= L_ASSOC
|L_INIT
;
87 #if USE_FW_LOADER_LEGACY
88 static char *firmware_dir
;
90 #if SEPARATE_DRIVER_INSTANCES
94 /* introduced earlier than 2.6.10, but takes more memory, so don't use it
95 * if there's no compile warning by kernel */
96 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
99 /* parameter is 'debug', corresponding var is acx_debug */
100 module_param_named(debug
, acx_debug
, uint
, 0);
102 #if USE_FW_LOADER_LEGACY
103 module_param(firmware_dir
, charp
, 0);
109 /* doh, 2.6.x screwed up big time: here the define has its own ";"
110 * ("double ; detected"), yet in 2.4.x it DOESN'T (the sane thing to do),
112 MODULE_PARM(acx_debug
, "i");
114 #if USE_FW_LOADER_LEGACY
115 MODULE_PARM(firmware_dir
, "s");
121 MODULE_PARM_DESC(debug
, "Debug level mask (see L_xxx constants)");
123 #if USE_FW_LOADER_LEGACY
124 MODULE_PARM_DESC(firmware_dir
, "Directory to load acx100 firmware files from");
126 #if SEPARATE_DRIVER_INSTANCES
127 MODULE_PARM(card
, "i");
128 MODULE_PARM_DESC(card
, "Associate only with card-th acx100 card from this driver instance");
131 /* Shoundn't be needed now, acx.firmware_dir= should work */
132 #if 0 /* USE_FW_LOADER_LEGACY */
134 acx_get_firmware_dir(const char *str
)
136 /* I've seen other drivers just pass the string pointer,
137 * so hopefully that's safe */
141 __setup("acx_firmware_dir=", acx_get_firmware_dir
);
144 #ifdef MODULE_LICENSE
145 MODULE_LICENSE("Dual MPL/GPL");
147 /* USB had this: MODULE_AUTHOR("Martin Wawro <martin.wawro AT uni-dortmund.de>"); */
148 MODULE_AUTHOR("ACX100 Open Source Driver development team");
149 MODULE_DESCRIPTION("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)");
152 /***********************************************************************
154 /* Probably a number of acx's itermediate buffers for USB transfers,
155 ** not to be confused with number of descriptors in tx/rx rings
156 ** (which are not directly accessible to host in USB devices) */
157 #define USB_RX_CNT 10
158 #define USB_TX_CNT 10
161 /***********************************************************************
164 /* minutes to wait until next radio recalibration: */
165 #define RECALIB_PAUSE 5
167 const u8 reg_domain_ids
[] =
168 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 };
169 /* stupid workaround for the fact that in C the size of an external array
170 * cannot be determined from within a second file */
171 const u8 reg_domain_ids_len
= sizeof(reg_domain_ids
);
172 static const u16 reg_domain_channel_masks
[] =
173 { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc };
176 /***********************************************************************
179 #ifdef PARANOID_LOCKING
180 static unsigned max_lock_time
;
181 static unsigned max_sem_time
;
184 acx_lock_unhold() { max_lock_time
= 0; }
186 acx_sem_unhold() { max_sem_time
= 0; }
188 static inline const char*
189 sanitize_str(const char *s
)
191 const char* t
= strrchr(s
, '/');
197 acx_lock_debug(wlandevice_t
*priv
, const char* where
)
199 int count
= 100*1000*1000;
200 where
= sanitize_str(where
);
202 if (!spin_is_locked(&priv
->lock
)) break;
206 printk(KERN_EMERG
"LOCKUP: already taken at %s!\n", priv
->last_lock
);
209 priv
->last_lock
= where
;
210 rdtscl(priv
->lock_time
);
213 acx_unlock_debug(wlandevice_t
*priv
, const char* where
)
216 if (!spin_is_locked(&priv
->lock
)) {
217 where
= sanitize_str(where
);
218 printk(KERN_EMERG
"STRAY UNLOCK at %s!\n", where
);
222 if (acx_debug
& L_LOCK
) {
225 diff
-= priv
->lock_time
;
226 if (diff
> max_lock_time
) {
227 where
= sanitize_str(where
);
228 printk("max lock hold time %d CPU ticks from %s "
229 "to %s\n", diff
, priv
->last_lock
, where
);
230 max_lock_time
= diff
;
235 acx_down_debug(wlandevice_t
*priv
, const char* where
)
239 where
= sanitize_str(where
);
242 sem_count
= atomic_read(&priv
->sem
.count
);
243 if (sem_count
) break;
247 printk(KERN_EMERG
"D STATE at %s! last sem at %s\n",
248 where
, priv
->last_sem
);
251 priv
->last_sem
= where
;
252 priv
->sem_time
= jiffies
;
254 if (acx_debug
& L_LOCK
) {
255 printk("%s: sem_down %d -> %d\n",
256 where
, sem_count
, atomic_read(&priv
->sem
.count
));
260 acx_up_debug(wlandevice_t
*priv
, const char* where
)
262 int sem_count
= atomic_read(&priv
->sem
.count
);
264 where
= sanitize_str(where
);
265 printk(KERN_EMERG
"STRAY UP at %s! sem.count=%d\n", where
, sem_count
);
268 if (acx_debug
& L_LOCK
) {
269 unsigned diff
= jiffies
- priv
->sem_time
;
270 if (diff
> max_sem_time
) {
271 where
= sanitize_str(where
);
272 printk("max sem hold time %d jiffies from %s "
273 "to %s\n", diff
, priv
->last_sem
, where
);
278 if (acx_debug
& L_LOCK
) {
279 where
= sanitize_str(where
);
280 printk("%s: sem_up %d -> %d\n",
281 where
, sem_count
, atomic_read(&priv
->sem
.count
));
284 #endif /* PARANOID_LOCKING */
287 /***********************************************************************
291 static int acx_debug_func_indent
;
293 #define FUNC_INDENT_INCREMENT 2
296 #define TIMESTAMP(d) unsigned long d; rdtscl(d)
298 #define TIMESTAMP(d) unsigned long d = jiffies
302 spaces
[] = " " " "; /* Nx10 spaces */
305 log_fn_enter(const char *funcname
)
310 indent
= acx_debug_func_indent
;
311 if (indent
>= sizeof(spaces
))
312 indent
= sizeof(spaces
)-1;
314 printk("%08ld %s==> %s\n",
316 spaces
+ (sizeof(spaces
)-1) - indent
,
320 acx_debug_func_indent
+= FUNC_INDENT_INCREMENT
;
323 log_fn_exit(const char *funcname
)
328 acx_debug_func_indent
-= FUNC_INDENT_INCREMENT
;
330 indent
= acx_debug_func_indent
;
331 if (indent
>= sizeof(spaces
))
332 indent
= sizeof(spaces
)-1;
334 printk("%08ld %s<== %s\n",
336 spaces
+ (sizeof(spaces
)-1) - indent
,
341 log_fn_exit_v(const char *funcname
, int v
)
346 acx_debug_func_indent
-= FUNC_INDENT_INCREMENT
;
348 indent
= acx_debug_func_indent
;
349 if (indent
>= sizeof(spaces
))
350 indent
= sizeof(spaces
)-1;
352 printk("%08ld %s<== %s: %08X\n",
354 spaces
+ (sizeof(spaces
)-1) - indent
,
359 #endif /* ACX_DEBUG > 1 */
362 /***********************************************************************
363 ** Basically a msleep with logging
374 /***********************************************************************
375 ** Not inlined: it's larger than it seems
378 acx_print_mac(const char *head
, const u8
*mac
, const char *tail
)
380 printk("%s"MACSTR
"%s", head
, MAC(mac
), tail
);
384 /***********************************************************************
385 ** acx_get_status_name
388 acx_get_status_name(u16 status
)
390 static const char * const str
[] = {
391 "STOPPED", "SCANNING", "WAIT_AUTH",
392 "AUTHENTICATED", "ASSOCIATED", "INVALID??"
394 return str
[(status
< VEC_SIZE(str
)) ? status
: VEC_SIZE(str
)-1];
398 /***********************************************************************
399 ** acx_get_packet_type_string
403 acx_get_packet_type_string(u16 fc
)
405 static const char * const mgmt_arr
[] = {
406 "MGMT/AssocReq", "MGMT/AssocResp", "MGMT/ReassocReq",
407 "MGMT/ReassocResp", "MGMT/ProbeReq", "MGMT/ProbeResp",
408 "MGMT/UNKNOWN", "MGMT/UNKNOWN", "MGMT/Beacon", "MGMT/ATIM",
409 "MGMT/Disassoc", "MGMT/Authen", "MGMT/Deauthen"
411 static const char * const ctl_arr
[] = {
412 "CTL/PSPoll", "CTL/RTS", "CTL/CTS", "CTL/Ack", "CTL/CFEnd",
415 static const char * const data_arr
[] = {
416 "DATA/DataOnly", "DATA/Data CFAck", "DATA/Data CFPoll",
417 "DATA/Data CFAck/CFPoll", "DATA/Null", "DATA/CFAck",
418 "DATA/CFPoll", "DATA/CFAck/CFPoll"
420 const char *str
= "UNKNOWN";
421 u8 fstype
= (WF_FC_FSTYPE
& fc
) >> 4;
424 switch (WF_FC_FTYPE
& fc
) {
426 str
= "MGMT/UNKNOWN";
427 if (fstype
< VEC_SIZE(mgmt_arr
))
428 str
= mgmt_arr
[fstype
];
433 if (ctl
< VEC_SIZE(ctl_arr
))
437 str
= "DATA/UNKNOWN";
438 if (fstype
< VEC_SIZE(data_arr
))
439 str
= data_arr
[fstype
];
447 /***********************************************************************
448 ** acx_cmd_status_str
451 acx_cmd_status_str(unsigned int state
)
453 static const char * const cmd_error_strings
[] = {
457 "Invalid Information Element",
459 "Channel invalid in current regulatory domain",
461 "Command rejected (read-only information element)",
472 return state
< VEC_SIZE(cmd_error_strings
) ?
473 cmd_error_strings
[state
] : "UNKNOWN REASON";
477 /***********************************************************************
481 get_status_string(unsigned int status
)
483 /* A bit shortened, but hopefully still understandable */
484 static const char * const status_str
[] = {
485 /* 0 */ "Successful",
486 /* 1 */ "Unspecified failure",
495 /*10 */ "Cannot support all requested capabilities in Capability Information field",
496 /*11 */ "Reassoc denied (reason outside of 802.11b scope)",
497 /*12 */ "Assoc denied (reason outside of 802.11b scope), maybe MAC filtering by peer?",
498 /*13 */ "Responding station doesnt support specified auth algorithm",
499 /*14 */ "Auth rejected: wrong transaction sequence number",
500 /*15 */ "Auth rejected: challenge failure",
501 /*16 */ "Auth rejected: timeout for next frame in sequence",
502 /*17 */ "Assoc denied: too many STAs on this AP",
503 /*18 */ "Assoc denied: requesting STA doesnt support all data rates in basic set",
504 /*19 */ "Assoc denied: requesting STA doesnt support Short Preamble",
505 /*20 */ "Assoc denied: requesting STA doesnt support PBCC Modulation",
506 /*21 */ "Assoc denied: requesting STA doesnt support Channel Agility"
510 /*25 */ "Assoc denied: requesting STA doesnt support Short Slot Time",
511 /*26 */ "Assoc denied: requesting STA doesnt support DSSS-OFDM"
514 return status_str
[status
< VEC_SIZE(status_str
) ? status
: 2];
518 /***********************************************************************
521 acx_log_bad_eid(wlan_hdr_t
* hdr
, int len
, wlan_ie_t
* ie_ptr
)
523 if (acx_debug
& L_ASSOC
) {
524 int offset
= (u8
*)ie_ptr
- (u8
*)hdr
;
525 printk("acx: unknown EID %d in mgmt frame at offset %d. IE: ",
526 ie_ptr
->eid
, offset
);
527 /* IE len can be bogus, IE can extend past packet end. Oh well... */
528 acx_dump_bytes(ie_ptr
, ie_ptr
->len
+ 2);
529 if (acx_debug
& L_DATA
) {
530 printk("frame (%s): ",
531 acx_get_packet_type_string(le16_to_cpu(hdr
->fc
)));
532 acx_dump_bytes(hdr
, len
);
538 /***********************************************************************
542 acx_dump_bytes(const void *data
, int num
)
544 const u8
* ptr
= (const u8
*)data
;
552 printk( "%02X %02X %02X %02X %02X %02X %02X %02X "
553 "%02X %02X %02X %02X %02X %02X %02X %02X\n",
554 ptr
[0], ptr
[1], ptr
[2], ptr
[3],
555 ptr
[4], ptr
[5], ptr
[6], ptr
[7],
556 ptr
[8], ptr
[9], ptr
[10], ptr
[11],
557 ptr
[12], ptr
[13], ptr
[14], ptr
[15]);
563 printk("%02X ", *ptr
++);
564 printk("%02X\n", *ptr
);
570 /***********************************************************************
573 acx_e_change_mtu(struct net_device
*dev
, int mtu
)
577 MAX_MTU
= WLAN_DATA_MAXLEN
- (ETH_HLEN
)
580 if (mtu
< MIN_MTU
|| mtu
> MAX_MTU
)
588 /***********************************************************************
589 ** acx_e_get_stats, acx_e_get_wireless_stats
591 struct net_device_stats
*
592 acx_e_get_stats(netdevice_t
*dev
)
594 wlandevice_t
*priv
= netdev_priv(dev
);
598 struct iw_statistics
*
599 acx_e_get_wireless_stats(netdevice_t
*dev
)
601 wlandevice_t
*priv
= netdev_priv(dev
);
602 return &priv
->wstats
;
606 /***********************************************************************
607 ** maps acx111 tx descr rate field to acx100 one
614 RATE100_2
,/* 3, should not happen */
615 RATE100_2
,/* 4, should not happen */
617 RATE100_2
,/* 6, should not happen */
618 RATE100_2
,/* 7, should not happen */
620 RATE100_2
,/* 9, should not happen */
621 RATE100_2
,/* 10, should not happen */
622 RATE100_2
,/* 11, should not happen */
623 RATE100_2
,/* 12, should not happen */
624 RATE100_2
,/* 13, should not happen */
625 RATE100_2
,/* 14, should not happen */
626 RATE100_2
,/* 15, should not happen */
630 acx_rate111to100(u16 r
) {
631 return bitpos2rate100
[highest_bit(r
)];
635 /***********************************************************************
636 ** Calculate level like the feb 2003 windows driver seems to do
639 acx_signal_to_winlevel(u8 rawlevel
)
641 /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
642 u8 winlevel
= ((4 + (rawlevel
* 5)) / 8);
650 acx_signal_determine_quality(u8 signal
, u8 noise
)
654 qual
= (((signal
- 30) * 100 / 70) + (100 - noise
* 4)) / 2;
664 /***********************************************************************
665 ** Interrogate/configure commands
670 ACX100_IE_ACX_TIMER_LEN
,
671 ACX1xx_IE_POWER_MGMT_LEN
,
672 ACX1xx_IE_QUEUE_CONFIG_LEN
,
673 ACX100_IE_BLOCK_SIZE_LEN
,
674 ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN
,
675 ACX1xx_IE_RATE_FALLBACK_LEN
,
676 ACX100_IE_WEP_OPTIONS_LEN
,
677 ACX1xx_IE_MEMORY_MAP_LEN
, /* ACX1xx_IE_SSID_LEN, */
679 ACX1xx_IE_ASSOC_ID_LEN
,
681 ACX111_IE_CONFIG_OPTIONS_LEN
,
683 ACX1xx_IE_FCS_ERROR_COUNT_LEN
,
684 ACX1xx_IE_MEDIUM_USAGE_LEN
,
685 ACX1xx_IE_RXCONFIG_LEN
,
688 ACX1xx_IE_FIRMWARE_STATISTICS_LEN
,
690 ACX1xx_IE_FEATURE_CONFIG_LEN
,
691 ACX111_IE_KEY_CHOOSE_LEN
,
697 ACX1xx_IE_DOT11_STATION_ID_LEN
,
699 ACX100_IE_DOT11_BEACON_PERIOD_LEN
,
700 ACX1xx_IE_DOT11_DTIM_PERIOD_LEN
,
701 ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN
,
702 ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN
,
703 ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN
,
704 ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN
,
706 ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN
,
707 ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN
,
709 ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN
,
710 ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN
,
711 ACX100_IE_DOT11_ED_THRESHOLD_LEN
,
712 ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN
,
719 #define FUNC "configure"
722 acx_s_configure(wlandevice_t
*priv
, void *pdr
, int type
)
726 acx_s_configure_debug(wlandevice_t
*priv
, void *pdr
, int type
, const char* typestr
)
733 len
= CtlLength
[type
];
735 len
= CtlLengthDot11
[type
- 0x1000];
737 acxlog(L_CTL
, FUNC
"(type:%s,len:%u)\n", typestr
, len
);
738 if (unlikely(!len
)) {
739 acxlog(L_DEBUG
, "zero-length type %s?!\n", typestr
);
742 ((acx_ie_generic_t
*)pdr
)->type
= cpu_to_le16(type
);
743 ((acx_ie_generic_t
*)pdr
)->len
= cpu_to_le16(len
);
744 res
= acx_s_issue_cmd(priv
, ACX1xx_CMD_CONFIGURE
, pdr
, len
+ 4);
747 printk("%s: "FUNC
"(type:%s) FAILED\n", priv
->netdev
->name
, typestr
);
749 printk("%s: "FUNC
"(type:0x%X) FAILED\n", priv
->netdev
->name
, type
);
751 /* dump_stack() is already done in issue_cmd() */
757 #define FUNC "interrogate"
760 acx_s_interrogate(wlandevice_t
*priv
, void *pdr
, int type
)
764 acx_s_interrogate_debug(wlandevice_t
*priv
, void *pdr
, int type
,
772 len
= CtlLength
[type
];
774 len
= CtlLengthDot11
[type
-0x1000];
775 acxlog(L_CTL
, FUNC
"(type:%s,len:%u)\n", typestr
, len
);
777 ((acx_ie_generic_t
*)pdr
)->type
= cpu_to_le16(type
);
778 ((acx_ie_generic_t
*)pdr
)->len
= cpu_to_le16(len
);
779 res
= acx_s_issue_cmd(priv
, ACX1xx_CMD_INTERROGATE
, pdr
, len
+ 4);
782 printk("%s: "FUNC
"(type:%s) FAILED\n", priv
->netdev
->name
, typestr
);
784 printk("%s: "FUNC
"(type:0x%X) FAILED\n", priv
->netdev
->name
, type
);
786 /* dump_stack() is already done in issue_cmd() */
793 great_inquisitor(wlandevice_t
*priv
)
798 /* 0x200 was too large here: */
799 u8 data
[0x100 - 4] ACX_PACKED
;
805 /* 0..0x20, 0x1000..0x1020 */
806 for (type
= 0; type
<= 0x1020; type
++) {
809 ie
.type
= cpu_to_le16(type
);
810 ie
.len
= cpu_to_le16(sizeof(ie
) - 4);
811 acx_s_issue_cmd(priv
, ACX1xx_CMD_INTERROGATE
, &ie
, sizeof(ie
));
818 #ifdef CONFIG_PROC_FS
819 /***********************************************************************
822 /***********************************************************************
824 ** Generate content for our /proc entry
827 ** buf is a pointer to write output to
828 ** priv is the usual pointer to our private struct wlandevice
830 ** number of bytes actually written to buf
835 acx_l_proc_output(char *buf
, wlandevice_t
*priv
)
843 "acx driver version:\t\t" WLAN_RELEASE
"\n"
844 "Wireless extension version:\t" STRING(WIRELESS_EXT
) "\n"
845 "chip name:\t\t\t%s (0x%08X)\n"
846 "radio type:\t\t\t0x%02X\n"
847 "form factor:\t\t\t0x%02X\n"
848 "EEPROM version:\t\t\t0x%02X\n"
849 "firmware version:\t\t%s (0x%08X)\n",
850 priv
->chip_name
, priv
->firmware_id
,
853 priv
->eeprom_version
,
854 priv
->firmware_version
, priv
->firmware_numver
);
856 for (i
= 0; i
< VEC_SIZE(priv
->sta_list
); i
++) {
857 struct client
*bss
= &priv
->sta_list
[i
];
858 if (!bss
->used
) continue;
859 p
+= sprintf(p
, "BSS %u BSSID "MACSTR
" ESSID %s channel %u "
860 "Cap 0x%X SIR %u SNR %u\n",
861 i
, MAC(bss
->bssid
), (char*)bss
->essid
, bss
->channel
,
862 bss
->cap_info
, bss
->sir
, bss
->snr
);
864 p
+= sprintf(p
, "status:\t\t\t%u (%s)\n",
865 priv
->status
, acx_get_status_name(priv
->status
));
872 /***********************************************************************
875 acx_s_proc_diag_output(char *buf
, wlandevice_t
*priv
)
878 fw_stats_t
*fw_stats
;
883 fw_stats
= kmalloc(sizeof(fw_stats_t
), GFP_KERNEL
);
888 memset(fw_stats
, 0, sizeof(fw_stats_t
));
890 acx_lock(priv
, flags
);
893 p
= acxpci_s_proc_diag_output(p
, priv
);
897 "** network status **\n"
898 "dev_state_mask 0x%04X\n"
900 "mode %u, channel %u, "
901 "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
902 priv
->dev_state_mask
,
903 priv
->status
, acx_get_status_name(priv
->status
),
904 priv
->mode
, priv
->channel
,
905 priv
->reg_dom_id
, priv
->reg_dom_chanmask
908 "ESSID \"%s\", essid_active %d, essid_len %d, "
909 "essid_for_assoc \"%s\", nick \"%s\"\n"
910 "WEP ena %d, restricted %d, idx %d\n",
911 priv
->essid
, priv
->essid_active
, (int)priv
->essid_len
,
912 priv
->essid_for_assoc
, priv
->nick
,
913 priv
->wep_enabled
, priv
->wep_restricted
,
914 priv
->wep_current_index
);
915 p
+= sprintf(p
, "dev_addr "MACSTR
"\n", MAC(priv
->dev_addr
));
916 p
+= sprintf(p
, "bssid "MACSTR
"\n", MAC(priv
->bssid
));
917 p
+= sprintf(p
, "ap_filter "MACSTR
"\n", MAC(priv
->ap
));
922 "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
923 "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
924 "rts_threshold %d, short_retry %d, long_retry %d, msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
925 priv
->tx_disabled
, priv
->tx_level_dbm
, /* priv->tx_level_val, priv->tx_level_auto, */
926 priv
->sensitivity
, priv
->antenna
, priv
->ed_threshold
, priv
->cca
, priv
->preamble_mode
,
927 priv
->rts_threshold
, priv
->short_retry
, priv
->long_retry
, priv
->msdu_lifetime
, priv
->listen_interval
, priv
->beacon_interval
);
929 acx_unlock(priv
, flags
);
931 if (OK
!= acx_s_interrogate(priv
, fw_stats
, ACX1xx_IE_FIRMWARE_STATISTICS
))
941 "tx_desc_overfl %u, rx_OutOfMem %u, rx_hdr_overfl %u, rx_hdr_use_next %u\n"
942 "rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u, rx_dma_req %u\n"
943 "rx_dma_err %u, tx_dma_req %u, tx_dma_err %u, cmd_cplt %u, fiq %u\n"
944 "rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u, irqs %u\n"
945 "acx_trans_procs %u, decrypt_done %u, dma_0_done %u, dma_1_done %u\n",
946 priv
->firmware_version
,
947 le32_to_cpu(fw_stats
->tx_desc_of
),
948 le32_to_cpu(fw_stats
->rx_oom
),
949 le32_to_cpu(fw_stats
->rx_hdr_of
),
950 le32_to_cpu(fw_stats
->rx_hdr_use_next
),
951 le32_to_cpu(fw_stats
->rx_dropped_frame
),
952 le32_to_cpu(fw_stats
->rx_frame_ptr_err
),
953 le32_to_cpu(fw_stats
->rx_xfr_hint_trig
),
954 le32_to_cpu(fw_stats
->rx_dma_req
),
955 le32_to_cpu(fw_stats
->rx_dma_err
),
956 le32_to_cpu(fw_stats
->tx_dma_req
),
957 le32_to_cpu(fw_stats
->tx_dma_err
),
958 le32_to_cpu(fw_stats
->cmd_cplt
),
959 le32_to_cpu(fw_stats
->fiq
),
960 le32_to_cpu(fw_stats
->rx_hdrs
),
961 le32_to_cpu(fw_stats
->rx_cmplt
),
962 le32_to_cpu(fw_stats
->rx_mem_of
),
963 le32_to_cpu(fw_stats
->rx_rdys
),
964 le32_to_cpu(fw_stats
->irqs
),
965 le32_to_cpu(fw_stats
->acx_trans_procs
),
966 le32_to_cpu(fw_stats
->decrypt_done
),
967 le32_to_cpu(fw_stats
->dma_0_done
),
968 le32_to_cpu(fw_stats
->dma_1_done
));
970 "tx_exch_complet %u, commands %u, acx_rx_procs %u\n"
971 "hw_pm_mode_changes %u, host_acks %u, pci_pm %u, acm_wakeups %u\n"
972 "wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
973 "wep_key_not_found %u, wep_decrypt_fail %u\n",
974 le32_to_cpu(fw_stats
->tx_exch_complet
),
975 le32_to_cpu(fw_stats
->commands
),
976 le32_to_cpu(fw_stats
->acx_rx_procs
),
977 le32_to_cpu(fw_stats
->hw_pm_mode_changes
),
978 le32_to_cpu(fw_stats
->host_acks
),
979 le32_to_cpu(fw_stats
->pci_pm
),
980 le32_to_cpu(fw_stats
->acm_wakeups
),
981 le32_to_cpu(fw_stats
->wep_key_count
),
982 le32_to_cpu(fw_stats
->wep_default_key_count
),
983 le32_to_cpu(fw_stats
->dot11_def_key_mib
),
984 le32_to_cpu(fw_stats
->wep_key_not_found
),
985 le32_to_cpu(fw_stats
->wep_decrypt_fail
));
995 /***********************************************************************
998 acx_s_proc_phy_output(char *buf
, wlandevice_t
*priv
)
1006 if (RADIO_RFMD_11 != priv->radio_type) {
1007 printk("sorry, not yet adapted for radio types "
1008 "other than RFMD, please verify "
1009 "PHY size etc. first!\n");
1014 /* The PHY area is only 0x80 bytes long; further pages after that
1015 * only have some page number registers with altered value,
1016 * all other registers remain the same. */
1017 for (i
= 0; i
< 0x80; i
++) {
1018 acx_s_read_phy_reg(priv
, i
, p
++);
1026 /***********************************************************************
1027 ** acx_e_read_proc_XXXX
1028 ** Handle our /proc entry
1031 ** standard kernel read_proc interface
1033 ** number of bytes written to buf
1038 acx_e_read_proc(char *buf
, char **start
, off_t offset
, int count
,
1039 int *eof
, void *data
)
1041 wlandevice_t
*priv
= (wlandevice_t
*)data
;
1042 unsigned long flags
;
1048 acx_lock(priv
, flags
);
1050 length
= acx_l_proc_output(buf
, priv
);
1051 acx_unlock(priv
, flags
);
1052 acx_sem_unlock(priv
);
1055 if (length
<= offset
+ count
)
1057 *start
= buf
+ offset
;
1068 acx_e_read_proc_diag(char *buf
, char **start
, off_t offset
, int count
,
1069 int *eof
, void *data
)
1071 wlandevice_t
*priv
= (wlandevice_t
*)data
;
1078 length
= acx_s_proc_diag_output(buf
, priv
);
1079 acx_sem_unlock(priv
);
1082 if (length
<= offset
+ count
)
1084 *start
= buf
+ offset
;
1095 acx_e_read_proc_eeprom(char *buf
, char **start
, off_t offset
, int count
,
1096 int *eof
, void *data
)
1098 wlandevice_t
*priv
= (wlandevice_t
*)data
;
1107 length
= acxpci_proc_eeprom_output(buf
, priv
);
1108 acx_sem_unlock(priv
);
1112 if (length
<= offset
+ count
)
1114 *start
= buf
+ offset
;
1125 acx_e_read_proc_phy(char *buf
, char **start
, off_t offset
, int count
,
1126 int *eof
, void *data
)
1128 wlandevice_t
*priv
= (wlandevice_t
*)data
;
1135 length
= acx_s_proc_phy_output(buf
, priv
);
1136 acx_sem_unlock(priv
);
1139 if (length
<= offset
+ count
)
1141 *start
= buf
+ offset
;
1152 /***********************************************************************
1153 ** /proc files registration
1155 static const char * const
1156 proc_files
[] = { "", "_diag", "_eeprom", "_phy" };
1158 static read_proc_t
* const
1159 acx_proc_funcs
[] = {
1161 acx_e_read_proc_diag
,
1162 acx_e_read_proc_eeprom
,
1167 manage_proc_entries(const struct net_device
*dev
, int remove
)
1169 /* doh, netdev_priv() doesn't have const! */
1170 wlandevice_t
*priv
= netdev_priv((struct net_device
*)dev
);
1174 for (i
= 0; i
< 4; i
++) {
1175 sprintf(procbuf
, "driver/acx_%s", dev
->name
);
1176 strcat(procbuf
, proc_files
[i
]);
1178 acxlog(L_INIT
, "creating /proc entry %s\n", procbuf
);
1179 if (!create_proc_read_entry(procbuf
, 0, 0, acx_proc_funcs
[i
], priv
))
1182 acxlog(L_INIT
, "removing /proc entry %s\n", procbuf
);
1183 remove_proc_entry(procbuf
, NULL
);
1190 acx_proc_register_entries(const struct net_device
*dev
)
1192 return manage_proc_entries(dev
, 0);
1196 acx_proc_unregister_entries(const struct net_device
*dev
)
1198 return manage_proc_entries(dev
, 1);
1200 #endif /* CONFIG_PROC_FS */
1203 /***********************************************************************
1204 ** acx_cmd_join_bssid
1206 ** Common code for both acx100 and acx111.
1208 /* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
1210 bitpos2genframe_txrate
[] = {
1211 10, /* 0. 1 Mbit/s */
1212 20, /* 1. 2 Mbit/s */
1213 55, /* 2. 5.5 Mbit/s */
1214 0x0B, /* 3. 6 Mbit/s */
1215 0x0F, /* 4. 9 Mbit/s */
1216 110, /* 5. 11 Mbit/s */
1217 0x0A, /* 6. 12 Mbit/s */
1218 0x0E, /* 7. 18 Mbit/s */
1219 220, /* 8. 22 Mbit/s */
1220 0x09, /* 9. 24 Mbit/s */
1221 0x0D, /* 10. 36 Mbit/s */
1222 0x08, /* 11. 48 Mbit/s */
1223 0x0C, /* 12. 54 Mbit/s */
1224 10, /* 13. 1 Mbit/s, should never happen */
1225 10, /* 14. 1 Mbit/s, should never happen */
1226 10, /* 15. 1 Mbit/s, should never happen */
1230 ** Actually, each one compiled into one AND and one SHIFT,
1231 ** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
1233 rate111to5bits(unsigned int rate
)
1236 | ( (rate
& RATE111_11
) / (RATE111_11
/JOINBSS_RATES_11
) )
1237 | ( (rate
& RATE111_22
) / (RATE111_22
/JOINBSS_RATES_22
) )
1242 acx_s_cmd_join_bssid(wlandevice_t
*priv
, const u8
*bssid
)
1250 dtim_interval
= (ACX_MODE_0_ADHOC
== priv
->mode
) ?
1251 1 : priv
->dtim_interval
;
1253 memset(&tmp
, 0, sizeof(tmp
));
1255 for (i
= 0; i
< ETH_ALEN
; i
++) {
1256 tmp
.bssid
[i
] = bssid
[ETH_ALEN
-1 - i
];
1259 tmp
.beacon_interval
= cpu_to_le16(priv
->beacon_interval
);
1261 /* basic rate set. Control frame responses (such as ACK or CTS frames)
1262 ** are sent with one of these rates */
1263 if (IS_ACX111(priv
)) {
1264 /* It was experimentally determined that rates_basic
1265 ** can take 11g rates as well, not only rates
1266 ** defined with JOINBSS_RATES_BASIC111_nnn.
1267 ** Just use RATE111_nnn constants... */
1268 tmp
.u
.acx111
.dtim_interval
= dtim_interval
;
1269 tmp
.u
.acx111
.rates_basic
= cpu_to_le16(priv
->rate_basic
);
1270 acxlog(L_ASSOC
, "%s rates_basic %04X, rates_supported %04X\n",
1271 __func__
, priv
->rate_basic
, priv
->rate_oper
);
1273 tmp
.u
.acx100
.dtim_interval
= dtim_interval
;
1274 tmp
.u
.acx100
.rates_basic
= rate111to5bits(priv
->rate_basic
);
1275 tmp
.u
.acx100
.rates_supported
= rate111to5bits(priv
->rate_oper
);
1276 acxlog(L_ASSOC
, "%s rates_basic %04X->%02X, "
1277 "rates_supported %04X->%02X\n",
1279 priv
->rate_basic
, tmp
.u
.acx100
.rates_basic
,
1280 priv
->rate_oper
, tmp
.u
.acx100
.rates_supported
);
1283 /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
1284 ** will be sent (rate/modulation/preamble) */
1285 tmp
.genfrm_txrate
= bitpos2genframe_txrate
[lowest_bit(priv
->rate_basic
)];
1286 tmp
.genfrm_mod_pre
= 0; /* FIXME: was = priv->capab_short (which is always 0); */
1287 /* we can use short pre *if* all peers can understand it */
1288 /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
1290 /* we switch fw to STA mode in MONITOR mode, it seems to be
1291 ** the only mode where fw does not emit beacons by itself
1292 ** but allows us to send anything (we really want to retain
1293 ** ability to tx arbitrary frames in MONITOR mode)
1295 tmp
.macmode
= (priv
->mode
!= ACX_MODE_MONITOR
? priv
->mode
: ACX_MODE_2_STA
);
1296 tmp
.channel
= priv
->channel
;
1297 tmp
.essid_len
= priv
->essid_len
;
1298 /* NOTE: the code memcpy'd essid_len + 1 before, which is WRONG! */
1299 memcpy(tmp
.essid
, priv
->essid
, tmp
.essid_len
);
1300 acx_s_issue_cmd(priv
, ACX1xx_CMD_JOIN
, &tmp
, tmp
.essid_len
+ 0x11);
1302 acxlog(L_ASSOC
|L_DEBUG
, "BSS_Type = %u\n", tmp
.macmode
);
1303 acxlog_mac(L_ASSOC
|L_DEBUG
, "JoinBSSID MAC:", priv
->bssid
, "\n");
1305 acx_update_capabilities(priv
);
1310 /***********************************************************************
1311 ** acx_s_cmd_start_scan
1313 ** Issue scan command to the hardware
1316 acx100_s_scan_chan(wlandevice_t
*priv
)
1322 memset(&s
, 0, sizeof(s
));
1323 s
.count
= cpu_to_le16(priv
->scan_count
);
1324 s
.start_chan
= cpu_to_le16(1);
1325 s
.flags
= cpu_to_le16(0x8000);
1326 s
.max_rate
= priv
->scan_rate
;
1327 s
.options
= priv
->scan_mode
;
1328 s
.chan_duration
= cpu_to_le16(priv
->scan_duration
);
1329 s
.max_probe_delay
= cpu_to_le16(priv
->scan_probe_delay
);
1331 acx_s_issue_cmd(priv
, ACX1xx_CMD_SCAN
, &s
, sizeof(s
));
1336 acx111_s_scan_chan(wlandevice_t
*priv
)
1342 memset(&s
, 0, sizeof(s
));
1343 s
.count
= cpu_to_le16(priv
->scan_count
);
1344 s
.channel_list_select
= 0; /* scan every allowed channel */
1345 /*s.channel_list_select = 1;*/ /* scan given channels */
1346 s
.rate
= priv
->scan_rate
;
1347 s
.options
= priv
->scan_mode
;
1348 s
.chan_duration
= cpu_to_le16(priv
->scan_duration
);
1349 s
.max_probe_delay
= cpu_to_le16(priv
->scan_probe_delay
);
1350 /*s.modulation = 0x40;*/ /* long preamble? OFDM? -> only for active scan */
1352 /*s.channel_list[0] = 6;
1353 s.channel_list[1] = 4;*/
1355 acx_s_issue_cmd(priv
, ACX1xx_CMD_SCAN
, &s
, sizeof(s
));
1360 acx_s_cmd_start_scan(wlandevice_t
*priv
)
1362 /* time_before check is 'just in case' thing */
1363 if (!(priv
->irq_status
& HOST_INT_SCAN_COMPLETE
)
1364 && time_before(jiffies
, priv
->scan_start
+ 10*HZ
)
1366 acxlog(L_INIT
, "start_scan: seems like previous scan "
1367 "is still running. Not starting anew. Please report\n");
1371 acxlog(L_INIT
, "starting radio scan\n");
1372 /* remember that fw is commanded to do scan */
1373 priv
->scan_start
= jiffies
;
1374 CLEAR_BIT(priv
->irq_status
, HOST_INT_SCAN_COMPLETE
);
1376 if (IS_ACX100(priv
)) {
1377 acx100_s_scan_chan(priv
);
1379 acx111_s_scan_chan(priv
);
1384 /***********************************************************************
1385 ** acx111 feature config
1388 acx111_s_get_feature_config(wlandevice_t
*priv
,
1389 u32
*feature_options
, u32
*data_flow_options
)
1391 struct acx111_ie_feature_config fc
;
1393 if (!IS_ACX111(priv
)) {
1397 memset(&fc
, 0, sizeof(fc
));
1399 if (OK
!= acx_s_interrogate(priv
, &fc
, ACX1xx_IE_FEATURE_CONFIG
)) {
1403 "got Feature option:0x%X, DataFlow option: 0x%X\n",
1405 fc
.data_flow_options
);
1407 if (feature_options
)
1408 *feature_options
= le32_to_cpu(fc
.feature_options
);
1409 if (data_flow_options
)
1410 *data_flow_options
= le32_to_cpu(fc
.data_flow_options
);
1416 acx111_s_set_feature_config(wlandevice_t
*priv
,
1417 u32 feature_options
, u32 data_flow_options
,
1418 unsigned int mode
/* 0 == remove, 1 == add, 2 == set */)
1420 struct acx111_ie_feature_config fc
;
1422 if (!IS_ACX111(priv
)) {
1426 if ((mode
< 0) || (mode
> 2))
1430 /* need to modify old data */
1431 acx111_s_get_feature_config(priv
, &fc
.feature_options
, &fc
.data_flow_options
);
1433 /* need to set a completely new value */
1434 fc
.feature_options
= 0;
1435 fc
.data_flow_options
= 0;
1438 if (mode
== 0) { /* remove */
1439 CLEAR_BIT(fc
.feature_options
, cpu_to_le32(feature_options
));
1440 CLEAR_BIT(fc
.data_flow_options
, cpu_to_le32(data_flow_options
));
1441 } else { /* add or set */
1442 SET_BIT(fc
.feature_options
, cpu_to_le32(feature_options
));
1443 SET_BIT(fc
.data_flow_options
, cpu_to_le32(data_flow_options
));
1447 "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
1448 "new: feature 0x%08X dataflow 0x%08X\n",
1449 feature_options
, data_flow_options
, mode
,
1450 le32_to_cpu(fc
.feature_options
),
1451 le32_to_cpu(fc
.data_flow_options
));
1453 if (OK
!= acx_s_configure(priv
, &fc
, ACX1xx_IE_FEATURE_CONFIG
)) {
1461 acx111_s_feature_off(wlandevice_t
*priv
, u32 f
, u32 d
)
1463 return acx111_s_set_feature_config(priv
, f
, d
, 0);
1466 acx111_s_feature_on(wlandevice_t
*priv
, u32 f
, u32 d
)
1468 return acx111_s_set_feature_config(priv
, f
, d
, 1);
1471 acx111_s_feature_set(wlandevice_t
*priv
, u32 f
, u32 d
)
1473 return acx111_s_set_feature_config(priv
, f
, d
, 2);
1477 /***********************************************************************
1478 ** acx100_s_init_memory_pools
1481 acx100_s_init_memory_pools(wlandevice_t
*priv
, const acx_ie_memmap_t
*mmt
)
1483 acx100_ie_memblocksize_t MemoryBlockSize
;
1484 acx100_ie_memconfigoption_t MemoryConfigOption
;
1485 int TotalMemoryBlocks
;
1487 int TotalRxBlockSize
;
1489 int TotalTxBlockSize
;
1493 /* Let's see if we can follow this:
1494 first we select our memory block size (which I think is
1495 completely arbitrary) */
1496 MemoryBlockSize
.size
= cpu_to_le16(priv
->memblocksize
);
1498 /* Then we alert the card to our decision of block size */
1499 if (OK
!= acx_s_configure(priv
, &MemoryBlockSize
, ACX100_IE_BLOCK_SIZE
)) {
1503 /* We figure out how many total blocks we can create, using
1504 the block size we chose, and the beginning and ending
1505 memory pointers, i.e.: end-start/size */
1506 TotalMemoryBlocks
= (le32_to_cpu(mmt
->PoolEnd
) - le32_to_cpu(mmt
->PoolStart
)) / priv
->memblocksize
;
1508 acxlog(L_DEBUG
, "TotalMemoryBlocks=%u (%u bytes)\n",
1509 TotalMemoryBlocks
, TotalMemoryBlocks
*priv
->memblocksize
);
1511 /* MemoryConfigOption.DMA_config bitmask:
1512 // access to ACX memory is to be done:
1513 0x00080000 // using PCI conf space?!
1514 0x00040000 // using IO instructions?
1515 0x00000000 // using memory access instructions
1516 0x00020000 // use local memory block linked list (else what?)
1517 0x00010000 // use host indirect descriptors (else host must access ACX memory?)
1520 MemoryConfigOption
.DMA_config
= cpu_to_le32(0x30000);
1521 /* Declare start of the Rx host pool */
1522 MemoryConfigOption
.pRxHostDesc
= cpu2acx(priv
->rxhostdesc_startphy
);
1523 acxlog(L_DEBUG
, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
1524 acx2cpu(MemoryConfigOption
.pRxHostDesc
),
1525 (long)priv
->rxhostdesc_startphy
);
1527 MemoryConfigOption
.DMA_config
= cpu_to_le32(0x20000);
1530 /* 50% of the allotment of memory blocks go to tx descriptors */
1531 TxBlockNum
= TotalMemoryBlocks
/ 2;
1532 MemoryConfigOption
.TxBlockNum
= cpu_to_le16(TxBlockNum
);
1534 /* and 50% go to the rx descriptors */
1535 RxBlockNum
= TotalMemoryBlocks
- TxBlockNum
;
1536 MemoryConfigOption
.RxBlockNum
= cpu_to_le16(RxBlockNum
);
1538 /* size of the tx and rx descriptor queues */
1539 TotalTxBlockSize
= TxBlockNum
* priv
->memblocksize
;
1540 TotalRxBlockSize
= RxBlockNum
* priv
->memblocksize
;
1541 acxlog(L_DEBUG
, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u "
1542 "TotalTxBlockSize %u\n", TxBlockNum
, RxBlockNum
,
1543 TotalTxBlockSize
, TotalRxBlockSize
);
1546 /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
1547 MemoryConfigOption
.rx_mem
=
1548 cpu_to_le32((le32_to_cpu(mmt
->PoolStart
) + 0x1f) & ~0x1f);
1550 /* align the rx descriptor queue to units of 0x20
1551 * and offset it by the tx descriptor queue */
1552 MemoryConfigOption
.tx_mem
=
1553 cpu_to_le32((le32_to_cpu(mmt
->PoolStart
) + TotalRxBlockSize
+ 0x1f) & ~0x1f);
1554 acxlog(L_DEBUG
, "rx_mem %08X rx_mem %08X\n",
1555 MemoryConfigOption
.tx_mem
, MemoryConfigOption
.rx_mem
);
1557 /* alert the device to our decision */
1558 if (OK
!= acx_s_configure(priv
, &MemoryConfigOption
, ACX1xx_IE_MEMORY_CONFIG_OPTIONS
)) {
1562 /* and tell the device to kick it into gear */
1563 if (OK
!= acx_s_issue_cmd(priv
, ACX100_CMD_INIT_MEMORY
, NULL
, 0)) {
1574 /***********************************************************************
1575 ** acx100_s_create_dma_regions
1577 ** Note that this fn messes up heavily with hardware, but we cannot
1578 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1581 acx100_s_create_dma_regions(wlandevice_t
*priv
)
1583 acx100_ie_queueconfig_t queueconf
;
1584 acx_ie_memmap_t memmap
;
1586 u32 tx_queue_start
, rx_queue_start
;
1590 /* read out the acx100 physical start address for the queues */
1591 if (OK
!= acx_s_interrogate(priv
, &memmap
, ACX1xx_IE_MEMORY_MAP
)) {
1595 tx_queue_start
= le32_to_cpu(memmap
.QueueStart
);
1596 rx_queue_start
= tx_queue_start
+ TX_CNT
* sizeof(txdesc_t
);
1598 acxlog(L_DEBUG
, "initializing Queue Indicator\n");
1600 memset(&queueconf
, 0, sizeof(queueconf
));
1602 /* Not needed for PCI, so we can avoid setting them altogether */
1604 queueconf
.NumTxDesc
= USB_TX_CNT
;
1605 queueconf
.NumRxDesc
= USB_RX_CNT
;
1608 /* calculate size of queues */
1609 queueconf
.AreaSize
= cpu_to_le32(
1610 TX_CNT
* sizeof(txdesc_t
) +
1611 RX_CNT
* sizeof(rxdesc_t
) + 8
1613 queueconf
.NumTxQueues
= 1; /* number of tx queues */
1614 /* sets the beginning of the tx descriptor queue */
1615 queueconf
.TxQueueStart
= memmap
.QueueStart
;
1616 /* done by memset: queueconf.TxQueuePri = 0; */
1617 queueconf
.RxQueueStart
= cpu_to_le32(rx_queue_start
);
1618 queueconf
.QueueOptions
= 1; /* auto reset descriptor */
1619 /* sets the end of the rx descriptor queue */
1620 queueconf
.QueueEnd
= cpu_to_le32(
1621 rx_queue_start
+ RX_CNT
* sizeof(rxdesc_t
)
1623 /* sets the beginning of the next queue */
1624 queueconf
.HostQueueEnd
= cpu_to_le32(le32_to_cpu(queueconf
.QueueEnd
) + 8);
1625 if (OK
!= acx_s_configure(priv
, &queueconf
, ACX1xx_IE_QUEUE_CONFIG
)) {
1630 /* sets the beginning of the rx descriptor queue, after the tx descrs */
1631 if (OK
!= acxpci_s_create_hostdesc_queues(priv
))
1633 acxpci_create_desc_queues(priv
, tx_queue_start
, rx_queue_start
);
1636 if (OK
!= acx_s_interrogate(priv
, &memmap
, ACX1xx_IE_MEMORY_MAP
)) {
1640 /* [20050901] seems to be bogus. remove if no one complains */
1641 #if 0 /* #ifdef ACX_USB */
1642 if (OK
!= acx_s_configure(priv
, &memmap
, ACX1xx_IE_MEMORY_MAP
)) {
1647 memmap
.PoolStart
= cpu_to_le32(
1648 (le32_to_cpu(memmap
.QueueEnd
) + 4 + 0x1f) & ~0x1f
1651 if (OK
!= acx_s_configure(priv
, &memmap
, ACX1xx_IE_MEMORY_MAP
)) {
1655 if (OK
!= acx100_s_init_memory_pools(priv
, &memmap
)) {
1663 acx_s_msleep(1000); /* ? */
1665 acxpci_free_desc_queues(priv
);
1672 /***********************************************************************
1673 ** acx111_s_create_dma_regions
1675 ** Note that this fn messes up heavily with hardware, but we cannot
1676 ** lock it (we need to sleep). Not a problem since IRQs can't happen
1678 #define ACX111_PERCENT(percent) ((percent)/5)
1681 acx111_s_create_dma_regions(wlandevice_t
*priv
)
1683 struct acx111_ie_memoryconfig memconf
;
1684 struct acx111_ie_queueconfig queueconf
;
1685 u32 tx_queue_start
, rx_queue_start
;
1689 /* Calculate memory positions and queue sizes */
1691 /* Set up our host descriptor pool + data pool */
1693 if (OK
!= acxpci_s_create_hostdesc_queues(priv
))
1697 memset(&memconf
, 0, sizeof(memconf
));
1698 /* the number of STAs (STA contexts) to support
1699 ** NB: was set to 1 and everything seemed to work nevertheless... */
1700 memconf
.no_of_stations
= cpu_to_le16(VEC_SIZE(priv
->sta_list
));
1701 /* specify the memory block size. Default is 256 */
1702 memconf
.memory_block_size
= cpu_to_le16(priv
->memblocksize
);
1703 /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
1704 memconf
.tx_rx_memory_block_allocation
= ACX111_PERCENT(50);
1705 /* set the count of our queues
1706 ** NB: struct acx111_ie_memoryconfig shall be modified
1707 ** if we ever will switch to more than one rx and/or tx queue */
1708 memconf
.count_rx_queues
= 1;
1709 memconf
.count_tx_queues
= 1;
1710 /* 0 == Busmaster Indirect Memory Organization, which is what we want
1711 * (using linked host descs with their allocated mem).
1712 * 2 == Generic Bus Slave */
1713 /* done by memset: memconf.options = 0; */
1714 /* let's use 25% for fragmentations and 75% for frame transfers
1715 * (specified in units of 5%) */
1716 memconf
.fragmentation
= ACX111_PERCENT(75);
1717 /* Rx descriptor queue config */
1718 memconf
.rx_queue1_count_descs
= RX_CNT
;
1719 memconf
.rx_queue1_type
= 7; /* must be set to 7 */
1720 /* done by memset: memconf.rx_queue1_prio = 0; low prio */
1722 memconf
.rx_queue1_host_rx_start
= cpu2acx(priv
->rxhostdesc_startphy
);
1724 /* Tx descriptor queue config */
1725 memconf
.tx_queue1_count_descs
= TX_CNT
;
1726 /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
1728 /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
1729 ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
1730 ** But it is actually correct wrt IE numbers.
1731 ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
1732 ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
1733 ** which is 4 bytes larger. what a mess. TODO: clean it up) */
1734 if (OK
!= acx_s_configure(priv
, &memconf
, ACX1xx_IE_QUEUE_CONFIG
)) {
1738 acx_s_interrogate(priv
, &queueconf
, ACX1xx_IE_MEMORY_CONFIG_OPTIONS
);
1740 tx_queue_start
= le32_to_cpu(queueconf
.tx1_queue_address
);
1741 rx_queue_start
= le32_to_cpu(queueconf
.rx1_queue_address
);
1743 acxlog(L_INIT
, "dump queue head (from card):\n"
1745 "tx_memory_block_address: %X\n"
1746 "rx_memory_block_address: %X\n"
1747 "tx1_queue address: %X\n"
1748 "rx1_queue address: %X\n",
1749 le16_to_cpu(queueconf
.len
),
1750 le32_to_cpu(queueconf
.tx_memory_block_address
),
1751 le32_to_cpu(queueconf
.rx_memory_block_address
),
1756 acxpci_create_desc_queues(priv
, tx_queue_start
, rx_queue_start
);
1762 acxpci_free_desc_queues(priv
);
1769 /***********************************************************************
1770 ** acx_s_set_defaults
1771 ** Called from acx_s_init_mac
1774 acx_s_set_defaults(wlandevice_t
*priv
)
1776 unsigned long flags
;
1780 /* query some settings from the card.
1781 * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
1782 * query is REQUIRED, otherwise the card won't work correctly!! */
1783 priv
->get_mask
= GETSET_ANTENNA
|GETSET_SENSITIVITY
|GETSET_STATION_ID
|GETSET_REG_DOMAIN
;
1784 /* Only ACX100 supports ED and CCA */
1785 if (IS_ACX100(priv
))
1786 priv
->get_mask
|= GETSET_CCA
|GETSET_ED_THRESH
;
1788 acx_s_update_card_settings(priv
, 0, 0);
1790 acx_lock(priv
, flags
);
1792 /* set our global interrupt mask */
1794 acxpci_set_interrupt_mask(priv
);
1796 priv
->led_power
= 1; /* LED is active on startup */
1797 priv
->brange_max_quality
= 60; /* LED blink max quality is 60 */
1798 priv
->brange_time_last_state_change
= jiffies
;
1800 /* copy the MAC address we just got from the card
1801 * into our MAC address used during current 802.11 session */
1802 MAC_COPY(priv
->dev_addr
, priv
->netdev
->dev_addr
);
1803 sprintf(priv
->essid
, "STA%02X%02X%02X",
1804 priv
->dev_addr
[3], priv
->dev_addr
[4], priv
->dev_addr
[5]);
1805 priv
->essid_len
= sizeof("STAxxxxxx") - 1; /* make sure to adapt if changed above! */
1806 priv
->essid_active
= 1;
1808 /* we have a nick field to waste, so why not abuse it
1809 * to announce the driver version? ;-) */
1810 strncpy(priv
->nick
, "acx " WLAN_RELEASE
, IW_ESSID_MAX_SIZE
);
1813 if (IS_ACX111(priv
)) {
1814 /* Hope this is correct, only tested with domain 0x30 */
1815 acxpci_read_eeprom_byte(priv
, 0x16F, &priv
->reg_dom_id
);
1816 } else if (priv
->eeprom_version
< 5) {
1817 acxpci_read_eeprom_byte(priv
, 0x16F, &priv
->reg_dom_id
);
1819 acxpci_read_eeprom_byte(priv
, 0x171, &priv
->reg_dom_id
);
1824 /* 0xffff would be better, but then we won't get a "scan complete"
1825 * interrupt, so our current infrastructure will fail: */
1826 priv
->scan_count
= 1;
1827 priv
->scan_mode
= ACX_SCAN_OPT_PASSIVE
;
1828 /* Doesn't work for acx100, do it only for acx111 for now */
1829 if (IS_ACX111(priv
)) {
1830 priv
->scan_mode
= ACX_SCAN_OPT_ACTIVE
;
1832 priv
->scan_duration
= 100;
1833 priv
->scan_probe_delay
= 200;
1834 priv
->scan_rate
= ACX_SCAN_RATE_1
;
1836 priv
->auth_alg
= WLAN_AUTH_ALG_OPENSYSTEM
;
1837 priv
->preamble_mode
= 2; /* auto */
1838 priv
->listen_interval
= 100;
1839 priv
->beacon_interval
= DEFAULT_BEACON_INTERVAL
;
1840 priv
->mode
= ACX_MODE_2_STA
;
1841 priv
->dtim_interval
= DEFAULT_DTIM_INTERVAL
;
1843 priv
->msdu_lifetime
= DEFAULT_MSDU_LIFETIME
;
1844 SET_BIT(priv
->set_mask
, SET_MSDU_LIFETIME
);
1846 priv
->rts_threshold
= DEFAULT_RTS_THRESHOLD
;
1848 /* use standard default values for retry limits */
1849 priv
->short_retry
= 7; /* max. retries for (short) non-RTS packets */
1850 priv
->long_retry
= 4; /* max. retries for long (RTS) packets */
1851 SET_BIT(priv
->set_mask
, GETSET_RETRY
);
1853 priv
->fallback_threshold
= 3;
1854 priv
->stepup_threshold
= 10;
1855 priv
->rate_bcast
= RATE111_1
;
1856 priv
->rate_bcast100
= RATE100_1
;
1857 priv
->rate_basic
= RATE111_1
| RATE111_2
;
1858 priv
->rate_auto
= 1;
1859 if (IS_ACX111(priv
)) {
1860 priv
->rate_oper
= RATE111_ALL
;
1862 priv
->rate_oper
= RATE111_ACX100_COMPAT
;
1865 /* configure card to do rate fallback when in auto rate mode. */
1866 SET_BIT(priv
->set_mask
, SET_RATE_FALLBACK
);
1868 /* Supported Rates element - the rates here are given in units of
1869 * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
1870 acx_l_update_ratevector(priv
);
1872 priv
->capab_short
= 0;
1873 priv
->capab_pbcc
= 1;
1874 priv
->capab_agility
= 0;
1876 SET_BIT(priv
->set_mask
, SET_RXCONFIG
);
1878 /* set some more defaults */
1879 if (IS_ACX111(priv
)) {
1880 /* 30mW (15dBm) is default, at least in my acx111 card: */
1881 priv
->tx_level_dbm
= 15;
1883 /* don't use max. level, since it might be dangerous
1884 * (e.g. WRT54G people experience
1885 * excessive Tx power damage!) */
1886 priv
->tx_level_dbm
= 18;
1888 /* priv->tx_level_auto = 1; */
1889 SET_BIT(priv
->set_mask
, GETSET_TXPOWER
);
1891 if (IS_ACX111(priv
)) {
1892 /* start with sensitivity level 1 out of 3: */
1893 priv
->sensitivity
= 1;
1896 /* better re-init the antenna value we got above */
1897 SET_BIT(priv
->set_mask
, GETSET_ANTENNA
);
1899 priv
->ps_wakeup_cfg
= 0;
1900 priv
->ps_listen_interval
= 0;
1901 priv
->ps_options
= 0;
1902 priv
->ps_hangover_period
= 0;
1903 priv
->ps_enhanced_transition_time
= 0;
1904 #ifdef POWER_SAVE_80211
1905 SET_BIT(priv
->set_mask
, GETSET_POWER_80211
);
1908 MAC_BCAST(priv
->ap
);
1910 acx_unlock(priv
, flags
);
1911 acx_lock_unhold(); // hold time 844814 CPU ticks @2GHz
1913 acx_s_initialize_rx_config(priv
);
1920 /***********************************************************************
1921 ** FIXME: this should be solved in a general way for all radio types
1922 ** by decoding the radio firmware module,
1923 ** since it probably has some standard structure describing how to
1924 ** set the power level of the radio module which it controls.
1925 ** Or maybe not, since the radio module probably has a function interface
1926 ** instead which then manages Tx level programming :-\
1929 acx111_s_set_tx_level(wlandevice_t
*priv
, u8 level_dbm
)
1931 struct acx111_ie_tx_level tx_level
;
1933 /* my acx111 card has two power levels in its configoptions (== EEPROM):
1936 * For now, just assume all other acx111 cards have the same.
1937 * Ideally we would query it here, but we first need a
1938 * standard way to query individual configoptions easily. */
1939 if (level_dbm
<= 12) {
1940 tx_level
.level
= 2; /* 10 dBm */
1941 priv
->tx_level_dbm
= 10;
1943 tx_level
.level
= 1; /* 15 dBm */
1944 priv
->tx_level_dbm
= 15;
1946 if (level_dbm
!= priv
->tx_level_dbm
)
1947 acxlog(L_INIT
, "acx111 firmware has specific "
1948 "power levels only: adjusted %d dBm to %d dBm!\n",
1949 level_dbm
, priv
->tx_level_dbm
);
1951 return acx_s_configure(priv
, &tx_level
, ACX1xx_IE_DOT11_TX_POWER_LEVEL
);
1955 acx_s_set_tx_level(wlandevice_t
*priv
, u8 level_dbm
)
1957 if (IS_ACX111(priv
)) {
1958 return acx111_s_set_tx_level(priv
, level_dbm
);
1961 return acx100pci_s_set_tx_level(priv
, level_dbm
);
1967 /***********************************************************************
1970 /* Returns the current tx level (ACX111) */
1972 acx111_s_get_tx_level(wlandevice_t
*priv
)
1974 struct acx111_ie_tx_level tx_level
;
1977 acx_s_interrogate(priv
, &tx_level
, ACX1xx_IE_DOT11_TX_POWER_LEVEL
);
1978 return tx_level
.level
;
1983 /***********************************************************************
1987 acx_s_init_mac(netdevice_t
*dev
)
1989 wlandevice_t
*priv
= netdev_priv(dev
);
1990 int result
= NOT_OK
;
1995 priv
->memblocksize
= 256; /* 256 is default */
1996 acxpci_init_mboxes(priv
);
1997 /* try to load radio for both ACX100 and ACX111, since both
1998 * chips have at least some firmware versions making use of an
1999 * external radio module */
2000 acxpci_s_upload_radio(priv
);
2002 priv
->memblocksize
= 128;
2005 if (IS_ACX111(priv
)) {
2006 /* for ACX111, the order is different from ACX100
2007 1. init packet templates
2008 2. create station context and create dma regions
2009 3. init wep default keys
2011 if (OK
!= acx111_s_init_packet_templates(priv
))
2014 if (OK
!= acx111_s_create_dma_regions(priv
)) {
2015 printk("%s: acx111_create_dma_regions FAILED\n",
2020 /* don't decrypt WEP in firmware */
2021 if (OK
!= acx111_s_feature_on(priv
, 0, FEATURE2_SNIFFER
))
2025 if (OK
!= acx100_s_init_wep(priv
))
2027 acxlog(L_DEBUG
, "between init_wep and init_packet_templates\n");
2028 if (OK
!= acx100_s_init_packet_templates(priv
))
2031 if (OK
!= acx100_s_create_dma_regions(priv
)) {
2032 printk("%s: acx100_create_dma_regions FAILED\n",
2038 MAC_COPY(dev
->dev_addr
, priv
->dev_addr
);
2047 /*----------------------------------------------------------------
2049 * Called from IRQ context only
2050 *----------------------------------------------------------------*/
2052 acx_l_rxmonitor(wlandevice_t
*priv
, const rxbuffer_t
*rxbuf
)
2055 struct sk_buff
*skb
;
2057 unsigned int skb_len
;
2062 /* we are in big luck: the acx100 doesn't modify any of the fields */
2063 /* in the 802.11 frame. just pass this packet into the PF_PACKET */
2064 /* subsystem. yeah. */
2065 payload_offset
= ((u8
*)acx_get_wlan_hdr(priv
, rxbuf
) - (u8
*)rxbuf
);
2066 skb_len
= RXBUF_BYTES_USED(rxbuf
) - payload_offset
;
2069 if (skb_len
> WLAN_A4FR_MAXLEN_WEP
) {
2070 printk("%s: monitor mode panic: oversized frame!\n",
2071 priv
->netdev
->name
);
2075 if (priv
->netdev
->type
== ARPHRD_IEEE80211_PRISM
)
2076 skb_len
+= sizeof(*msg
);
2079 skb
= dev_alloc_skb(skb_len
);
2081 printk("%s: no memory for skb (%u bytes)\n",
2082 priv
->netdev
->name
, skb_len
);
2086 skb_put(skb
, skb_len
);
2088 /* when in raw 802.11 mode, just copy frame as-is */
2089 if (priv
->netdev
->type
== ARPHRD_IEEE80211
)
2091 else { /* otherwise, emulate prism header */
2092 msg
= (wlansniffrm_t
*)skb
->data
;
2095 msg
->msgcode
= WLANSNIFFFRM
;
2096 msg
->msglen
= sizeof(*msg
);
2097 strncpy(msg
->devname
, priv
->netdev
->name
, sizeof(msg
->devname
)-1);
2098 msg
->devname
[sizeof(msg
->devname
)-1] = '\0';
2100 msg
->hosttime
.did
= WLANSNIFFFRM_hosttime
;
2101 msg
->hosttime
.status
= WLANITEM_STATUS_data_ok
;
2102 msg
->hosttime
.len
= 4;
2103 msg
->hosttime
.data
= jiffies
;
2105 msg
->mactime
.did
= WLANSNIFFFRM_mactime
;
2106 msg
->mactime
.status
= WLANITEM_STATUS_data_ok
;
2107 msg
->mactime
.len
= 4;
2108 msg
->mactime
.data
= rxbuf
->time
;
2110 msg
->channel
.did
= WLANSNIFFFRM_channel
;
2111 msg
->channel
.status
= WLANITEM_STATUS_data_ok
;
2112 msg
->channel
.len
= 4;
2113 msg
->channel
.data
= priv
->channel
;
2115 msg
->rssi
.did
= WLANSNIFFFRM_rssi
;
2116 msg
->rssi
.status
= WLANITEM_STATUS_no_value
;
2120 msg
->sq
.did
= WLANSNIFFFRM_sq
;
2121 msg
->sq
.status
= WLANITEM_STATUS_no_value
;
2125 msg
->signal
.did
= WLANSNIFFFRM_signal
;
2126 msg
->signal
.status
= WLANITEM_STATUS_data_ok
;
2127 msg
->signal
.len
= 4;
2128 msg
->signal
.data
= rxbuf
->phy_snr
;
2130 msg
->noise
.did
= WLANSNIFFFRM_noise
;
2131 msg
->noise
.status
= WLANITEM_STATUS_data_ok
;
2133 msg
->noise
.data
= rxbuf
->phy_level
;
2135 msg
->rate
.did
= WLANSNIFFFRM_rate
;
2136 msg
->rate
.status
= WLANITEM_STATUS_data_ok
;
2138 msg
->rate
.data
= rxbuf
->phy_plcp_signal
/ 5;
2140 msg
->istx
.did
= WLANSNIFFFRM_istx
;
2141 msg
->istx
.status
= WLANITEM_STATUS_data_ok
;
2143 msg
->istx
.data
= 0; /* tx=0: it's not a tx packet */
2145 skb_len
-= sizeof(*msg
);
2147 msg
->frmlen
.did
= WLANSNIFFFRM_signal
;
2148 msg
->frmlen
.status
= WLANITEM_STATUS_data_ok
;
2149 msg
->frmlen
.len
= 4;
2150 msg
->frmlen
.data
= skb_len
;
2153 memcpy(datap
, ((unsigned char*)rxbuf
)+payload_offset
, skb_len
);
2155 skb
->dev
= priv
->netdev
;
2156 skb
->dev
->last_rx
= jiffies
;
2158 skb
->mac
.raw
= skb
->data
;
2159 skb
->ip_summed
= CHECKSUM_NONE
;
2160 skb
->pkt_type
= PACKET_OTHERHOST
;
2161 skb
->protocol
= htons(ETH_P_80211_RAW
);
2164 priv
->stats
.rx_packets
++;
2165 priv
->stats
.rx_bytes
+= skb
->len
;
2171 /***********************************************************************
2172 ** acx_l_rx_ieee802_11_frame
2174 ** Called from IRQ context only
2177 /* All these contortions are for saner dup logging
2179 ** We want: (a) to know about excessive dups
2180 ** (b) to not spam kernel log about occasional dups
2182 ** 1/64 threshold was chosen by running "ping -A"
2183 ** It gave "rx: 59 DUPs in 2878 packets" only with 4 parallel
2184 ** "ping -A" streams running. */
2185 /* 2005-10-11: bumped up to 1/8
2186 ** subtract a $smallint from dup_count in order to
2187 ** avoid "2 DUPs in 19 packets" messages */
2189 acx_l_handle_dup(wlandevice_t
*priv
, u16 seq
)
2191 if (priv
->dup_count
) {
2192 priv
->nondup_count
++;
2193 if (time_after(jiffies
, priv
->dup_msg_expiry
)) {
2194 /* Log only if more than 1 dup in 64 packets */
2195 if (priv
->nondup_count
/8 < priv
->dup_count
-5) {
2196 printk(KERN_INFO
"%s: rx: %d DUPs in "
2197 "%d packets received in 10 secs\n",
2200 priv
->nondup_count
);
2202 priv
->dup_count
= 0;
2203 priv
->nondup_count
= 0;
2206 if (unlikely(seq
== priv
->last_seq_ctrl
)) {
2207 if (!priv
->dup_count
++)
2208 priv
->dup_msg_expiry
= jiffies
+ 10*HZ
;
2209 priv
->stats
.rx_errors
++;
2210 return 1; /* a dup */
2212 priv
->last_seq_ctrl
= seq
;
2217 acx_l_rx_ieee802_11_frame(wlandevice_t
*priv
, rxbuffer_t
*rxbuf
)
2219 unsigned int ftype
, fstype
;
2220 const wlan_hdr_t
*hdr
;
2221 int result
= NOT_OK
;
2225 hdr
= acx_get_wlan_hdr(priv
, rxbuf
);
2227 /* see IEEE 802.11-1999.pdf chapter 7 "MAC frame formats" */
2228 if ((hdr
->fc
& WF_FC_PVERi
) != 0) {
2229 printk_ratelimited(KERN_INFO
"rx: unsupported 802.11 protocol\n");
2233 ftype
= hdr
->fc
& WF_FC_FTYPEi
;
2234 fstype
= hdr
->fc
& WF_FC_FSTYPEi
;
2237 /* check data frames first, for speed */
2238 case WF_FTYPE_DATAi
:
2240 case WF_FSTYPE_DATAONLYi
:
2241 if (acx_l_handle_dup(priv
, hdr
->seq
))
2242 break; /* a dup, simply discard it */
2245 if (WF_FC_FROMTODSi == (hdr->fc & WF_FC_FROMTODSi)) {
2246 result = acx_l_process_data_frame_wds(priv, rxbuf);
2251 switch (priv
->mode
) {
2253 result
= acx_l_process_data_frame_master(priv
, rxbuf
);
2255 case ACX_MODE_0_ADHOC
:
2256 case ACX_MODE_2_STA
:
2257 result
= acx_l_process_data_frame_client(priv
, rxbuf
);
2260 case WF_FSTYPE_DATA_CFACKi
:
2261 case WF_FSTYPE_DATA_CFPOLLi
:
2262 case WF_FSTYPE_DATA_CFACK_CFPOLLi
:
2263 case WF_FSTYPE_CFPOLLi
:
2264 case WF_FSTYPE_CFACK_CFPOLLi
:
2266 acx_process_class_frame(priv, rxbuf, 3); */
2268 case WF_FSTYPE_NULLi
:
2269 /* acx_l_process_NULL_frame(priv, rxbuf, 3); */
2271 /* FIXME: same here, see above */
2272 case WF_FSTYPE_CFACKi
:
2277 case WF_FTYPE_MGMTi
:
2278 result
= acx_l_process_mgmt_frame(priv
, rxbuf
);
2281 if (fstype
== WF_FSTYPE_PSPOLLi
)
2283 /* this call is irrelevant, since
2284 * acx_process_class_frame is a stub, so return
2285 * immediately instead.
2286 * return acx_process_class_frame(priv, rxbuf, 3); */
2297 /***********************************************************************
2298 ** acx_l_process_rxbuf
2300 ** NB: used by USB code also
2303 acx_l_process_rxbuf(wlandevice_t
*priv
, rxbuffer_t
*rxbuf
)
2305 struct wlan_hdr
*hdr
;
2306 unsigned int buf_len
;
2310 hdr
= acx_get_wlan_hdr(priv
, rxbuf
);
2311 /* length of frame from control field to last byte of FCS */
2312 buf_len
= RXBUF_BYTES_RCVD(rxbuf
);
2313 fc
= le16_to_cpu(hdr
->fc
);
2315 if ( ((WF_FC_FSTYPE
& fc
) != WF_FSTYPE_BEACON
)
2316 || (acx_debug
& L_XFER_BEACON
)
2318 acxlog(L_XFER
|L_DATA
, "rx: %s "
2319 "time %u len %u signal %u SNR %u macstat %02X "
2320 "phystat %02X phyrate %u status %u\n",
2321 acx_get_packet_type_string(fc
),
2322 le32_to_cpu(rxbuf
->time
),
2324 acx_signal_to_winlevel(rxbuf
->phy_level
),
2325 acx_signal_to_winlevel(rxbuf
->phy_snr
),
2327 rxbuf
->phy_stat_baseband
,
2328 rxbuf
->phy_plcp_signal
,
2332 if (unlikely(acx_debug
& L_DATA
)) {
2333 printk("rx: 802.11 buf[%u]: ", buf_len
);
2334 acx_dump_bytes(hdr
, buf_len
);
2337 /* FIXME: should check for Rx errors (rxbuf->mac_status?
2338 * discard broken packets - but NOT for monitor!)
2339 * and update Rx packet statistics here */
2341 if (unlikely(priv
->mode
== ACX_MODE_MONITOR
)) {
2342 acx_l_rxmonitor(priv
, rxbuf
);
2343 } else if (likely(buf_len
>= WLAN_HDR_A3_LEN
)) {
2344 acx_l_rx_ieee802_11_frame(priv
, rxbuf
);
2346 acxlog(L_DEBUG
|L_XFER
|L_DATA
,
2347 "rx: NOT receiving packet (%s): "
2348 "size too small (%u)\n",
2349 acx_get_packet_type_string(fc
),
2353 /* Now check Rx quality level, AFTER processing packet.
2354 * I tried to figure out how to map these levels to dBm
2355 * values, but for the life of me I really didn't
2356 * manage to get it. Either these values are not meant to
2357 * be expressed in dBm, or it's some pretty complicated
2360 #ifdef FROM_SCAN_SOURCE_ONLY
2361 /* only consider packets originating from the MAC
2362 * address of the device that's managing our BSSID.
2363 * Disable it for now, since it removes information (levels
2364 * from different peers) and slows the Rx path. */
2366 && mac_is_equal(hdr
->a2
, priv
->ap_client
->address
)) {
2368 priv
->wstats
.qual
.level
= acx_signal_to_winlevel(rxbuf
->phy_level
);
2369 priv
->wstats
.qual
.noise
= acx_signal_to_winlevel(rxbuf
->phy_snr
);
2371 qual
= acx_signal_determine_quality(priv
->wstats
.qual
.level
,
2372 priv
->wstats
.qual
.noise
);
2374 qual
= (priv
->wstats
.qual
.noise
<= 100) ?
2375 100 - priv
->wstats
.qual
.noise
: 0;
2377 priv
->wstats
.qual
.qual
= qual
;
2378 priv
->wstats
.qual
.updated
= 7; /* all 3 indicators updated */
2379 #ifdef FROM_SCAN_SOURCE_ONLY
2385 /***********************************************************************
2388 ** Called by network core. Can be called outside of process context.
2391 acx_i_start_xmit(struct sk_buff
*skb
, netdevice_t
*dev
)
2393 wlandevice_t
*priv
= netdev_priv(dev
);
2396 unsigned long flags
;
2397 int txresult
= NOT_OK
;
2402 if (unlikely(!skb
)) {
2403 /* indicate success */
2407 if (unlikely(!priv
)) {
2411 acx_lock(priv
, flags
);
2413 if (unlikely(!(priv
->dev_state_mask
& ACX_STATE_IFACE_UP
))) {
2416 if (unlikely(priv
->mode
== ACX_MODE_OFF
)) {
2419 if (unlikely(acx_queue_stopped(dev
))) {
2420 acxlog(L_DEBUG
, "%s: called when queue stopped\n", __func__
);
2423 if (unlikely(ACX_STATUS_4_ASSOCIATED
!= priv
->status
)) {
2424 acxlog(L_XFER
, "trying to xmit, but not associated yet: "
2426 /* silently drop the packet, since we're not connected yet */
2428 /* ...but indicate an error nevertheless */
2429 priv
->stats
.tx_errors
++;
2433 tx
= acx_l_alloc_tx(priv
);
2434 if (unlikely(!tx
)) {
2435 printk("%s: start_xmit: txdesc ring is full, dropping tx\n",
2441 txbuf
= acx_l_get_txbuf(priv
, tx
);
2443 /* Card was removed */
2447 len
= acx_ether_to_txbuf(priv
, txbuf
, skb
);
2449 /* Error in packet conversion */
2453 acx_l_tx_data(priv
, tx
, len
);
2454 dev
->trans_start
= jiffies
;
2457 priv
->stats
.tx_packets
++;
2458 priv
->stats
.tx_bytes
+= skb
->len
;
2461 acx_unlock(priv
, flags
);
2464 if ((txresult
== OK
) && skb
)
2465 dev_kfree_skb_any(skb
);
2472 /***********************************************************************
2473 ** acx_l_update_ratevector
2475 ** Updates priv->rate_supported[_len] according to rate_{basic,oper}
2478 bitpos2ratebyte
[] = {
2495 acx_l_update_ratevector(wlandevice_t
*priv
)
2497 u16 bcfg
= priv
->rate_basic
;
2498 u16 ocfg
= priv
->rate_oper
;
2499 u8
*supp
= priv
->rate_supported
;
2500 const u8
*dot11
= bitpos2ratebyte
;
2516 priv
->rate_supported_len
= supp
- priv
->rate_supported
;
2517 if (acx_debug
& L_ASSOC
) {
2518 printk("new ratevector: ");
2519 acx_dump_bytes(priv
->rate_supported
, priv
->rate_supported_len
);
2525 /*----------------------------------------------------------------
2526 * acx_l_sta_list_init
2527 *----------------------------------------------------------------*/
2529 acx_l_sta_list_init(wlandevice_t
*priv
)
2532 memset(priv
->sta_hash_tab
, 0, sizeof(priv
->sta_hash_tab
));
2533 memset(priv
->sta_list
, 0, sizeof(priv
->sta_list
));
2538 /*----------------------------------------------------------------
2539 * acx_l_sta_list_get_from_hash
2540 *----------------------------------------------------------------*/
2541 static inline client_t
*
2542 acx_l_sta_list_get_from_hash(wlandevice_t
*priv
, const u8
*address
)
2544 return priv
->sta_hash_tab
[address
[5] % VEC_SIZE(priv
->sta_hash_tab
)];
2548 /*----------------------------------------------------------------
2549 * acx_l_sta_list_get
2550 *----------------------------------------------------------------*/
2552 acx_l_sta_list_get(wlandevice_t
*priv
, const u8
*address
)
2556 client
= acx_l_sta_list_get_from_hash(priv
, address
);
2558 if (mac_is_equal(address
, client
->address
)) {
2559 client
->mtime
= jiffies
;
2562 client
= client
->next
;
2569 /*----------------------------------------------------------------
2570 * acx_l_sta_list_del
2571 *----------------------------------------------------------------*/
2573 acx_l_sta_list_del(wlandevice_t
*priv
, client_t
*victim
)
2575 client_t
*client
, *next
;
2577 client
= acx_l_sta_list_get_from_hash(priv
, victim
->address
);
2579 /* tricky. next = client on first iteration only,
2580 ** on all other iters next = client->next */
2582 if (next
== victim
) {
2583 client
->next
= victim
->next
;
2585 memset(victim
, 0, sizeof(*victim
));
2589 next
= client
->next
;
2594 /*----------------------------------------------------------------
2595 * acx_l_sta_list_alloc
2597 * Never fails - will evict oldest client if needed
2598 *----------------------------------------------------------------*/
2600 acx_l_sta_list_alloc(wlandevice_t
*priv
)
2603 unsigned long age
, oldest_age
;
2604 client_t
*client
, *oldest
;
2608 oldest
= &priv
->sta_list
[0];
2610 for (i
= 0; i
< VEC_SIZE(priv
->sta_list
); i
++) {
2611 client
= &priv
->sta_list
[i
];
2613 if (!client
->used
) {
2616 age
= jiffies
- client
->mtime
;
2617 if (oldest_age
< age
) {
2623 acx_l_sta_list_del(priv
, oldest
);
2626 memset(client
, 0, sizeof(*client
));
2632 /*----------------------------------------------------------------
2633 * acx_l_sta_list_add
2635 * Never fails - will evict oldest client if needed
2636 *----------------------------------------------------------------*/
2637 /* In case we will reimplement it differently... */
2638 #define STA_LIST_ADD_CAN_FAIL 0
2641 acx_l_sta_list_add(wlandevice_t
*priv
, const u8
*address
)
2648 client
= acx_l_sta_list_alloc(priv
);
2650 client
->mtime
= jiffies
;
2651 MAC_COPY(client
->address
, address
);
2652 client
->used
= CLIENT_EXIST_1
;
2653 client
->auth_alg
= WLAN_AUTH_ALG_SHAREDKEY
;
2654 client
->auth_step
= 1;
2655 /* give some tentative peer rate values
2656 ** (needed because peer may do auth without probing us first,
2657 ** thus we'll have no idea of peer's ratevector yet).
2658 ** Will be overwritten by scanning or assoc code */
2659 client
->rate_cap
= priv
->rate_basic
;
2660 client
->rate_cfg
= priv
->rate_basic
;
2661 client
->rate_cur
= 1 << lowest_bit(priv
->rate_basic
);
2663 index
= address
[5] % VEC_SIZE(priv
->sta_hash_tab
);
2664 client
->next
= priv
->sta_hash_tab
[index
];
2665 priv
->sta_hash_tab
[index
] = client
;
2667 acxlog_mac(L_ASSOC
, "sta_list_add: sta=", address
, "\n");
2674 /*----------------------------------------------------------------
2675 * acx_l_sta_list_get_or_add
2677 * Never fails - will evict oldest client if needed
2678 *----------------------------------------------------------------*/
2680 acx_l_sta_list_get_or_add(wlandevice_t
*priv
, const u8
*address
)
2682 client_t
*client
= acx_l_sta_list_get(priv
, address
);
2684 client
= acx_l_sta_list_add(priv
, address
);
2689 /***********************************************************************
2692 ** This function is called in many atomic regions, must not sleep
2694 ** This function does not need locking UNLESS you call it
2695 ** as acx_set_status(ACX_STATUS_4_ASSOCIATED), bacause this can
2696 ** wake queue. This can race with stop_queue elsewhere.
2697 ** See acx_stop_queue comment. */
2699 acx_set_status(wlandevice_t
*priv
, u16 new_status
)
2701 #define QUEUE_OPEN_AFTER_ASSOC 1 /* this really seems to be needed now */
2702 u16 old_status
= priv
->status
;
2706 acxlog(L_ASSOC
, "%s(%d):%s\n",
2707 __func__
, new_status
, acx_get_status_name(new_status
));
2709 #if WIRELESS_EXT > 13 /* wireless_send_event() and SIOCGIWSCAN */
2710 /* wireless_send_event never sleeps */
2711 if (ACX_STATUS_4_ASSOCIATED
== new_status
) {
2712 union iwreq_data wrqu
;
2714 wrqu
.data
.length
= 0;
2715 wrqu
.data
.flags
= 0;
2716 wireless_send_event(priv
->netdev
, SIOCGIWSCAN
, &wrqu
, NULL
);
2718 wrqu
.data
.length
= 0;
2719 wrqu
.data
.flags
= 0;
2720 MAC_COPY(wrqu
.ap_addr
.sa_data
, priv
->bssid
);
2721 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
2722 wireless_send_event(priv
->netdev
, SIOCGIWAP
, &wrqu
, NULL
);
2724 union iwreq_data wrqu
;
2726 /* send event with empty BSSID to indicate we're not associated */
2727 MAC_ZERO(wrqu
.ap_addr
.sa_data
);
2728 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
2729 wireless_send_event(priv
->netdev
, SIOCGIWAP
, &wrqu
, NULL
);
2733 priv
->status
= new_status
;
2735 switch (new_status
) {
2736 case ACX_STATUS_1_SCANNING
:
2737 priv
->scan_retries
= 0;
2738 /* 1.0 s initial scan time */
2739 acx_set_timer(priv
, 1000000);
2741 case ACX_STATUS_2_WAIT_AUTH
:
2742 case ACX_STATUS_3_AUTHENTICATED
:
2743 priv
->auth_or_assoc_retries
= 0;
2744 acx_set_timer(priv
, 1500000); /* 1.5 s */
2748 #if QUEUE_OPEN_AFTER_ASSOC
2749 if (new_status
== ACX_STATUS_4_ASSOCIATED
) {
2750 if (old_status
< ACX_STATUS_4_ASSOCIATED
) {
2751 /* ah, we're newly associated now,
2752 * so let's indicate carrier */
2753 acx_carrier_on(priv
->netdev
, "after association");
2754 acx_wake_queue(priv
->netdev
, "after association");
2757 /* not associated any more, so let's kill carrier */
2758 if (old_status
>= ACX_STATUS_4_ASSOCIATED
) {
2759 acx_carrier_off(priv
->netdev
, "after losing association");
2760 acx_stop_queue(priv
->netdev
, "after losing association");
2768 /*------------------------------------------------------------------------------
2771 * Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
2772 *----------------------------------------------------------------------------*/
2774 acx_i_timer(unsigned long address
)
2776 unsigned long flags
;
2777 wlandevice_t
*priv
= (wlandevice_t
*)address
;
2781 acx_lock(priv
, flags
);
2783 acxlog(L_DEBUG
|L_ASSOC
, "%s: priv->status=%d (%s)\n",
2784 __func__
, priv
->status
, acx_get_status_name(priv
->status
));
2786 switch (priv
->status
) {
2787 case ACX_STATUS_1_SCANNING
:
2788 /* was set to 0 by set_status() */
2789 if (++priv
->scan_retries
< 7) {
2790 acx_set_timer(priv
, 1000000);
2791 /* used to interrogate for scan status.
2792 ** We rely on SCAN_COMPLETE IRQ instead */
2793 acxlog(L_ASSOC
, "continuing scan (%d sec)\n",
2794 priv
->scan_retries
);
2796 acxlog(L_ASSOC
, "stopping scan\n");
2797 /* send stop_scan cmd when we leave the interrupt context,
2798 * and make a decision what to do next (COMPLETE_SCAN) */
2799 acx_schedule_task(priv
,
2800 ACX_AFTER_IRQ_CMD_STOP_SCAN
+ ACX_AFTER_IRQ_COMPLETE_SCAN
);
2803 case ACX_STATUS_2_WAIT_AUTH
:
2804 /* was set to 0 by set_status() */
2805 if (++priv
->auth_or_assoc_retries
< 10) {
2806 acxlog(L_ASSOC
, "resend authen1 request (attempt %d)\n",
2807 priv
->auth_or_assoc_retries
+ 1);
2808 acx_l_transmit_authen1(priv
);
2810 /* time exceeded: fall back to scanning mode */
2812 "authen1 request reply timeout, giving up\n");
2813 /* we are a STA, need to find AP anyhow */
2814 acx_set_status(priv
, ACX_STATUS_1_SCANNING
);
2815 acx_schedule_task(priv
, ACX_AFTER_IRQ_RESTART_SCAN
);
2817 /* used to be 1500000, but some other driver uses 2.5s */
2818 acx_set_timer(priv
, 2500000);
2820 case ACX_STATUS_3_AUTHENTICATED
:
2821 /* was set to 0 by set_status() */
2822 if (++priv
->auth_or_assoc_retries
< 10) {
2823 acxlog(L_ASSOC
, "resend assoc request (attempt %d)\n",
2824 priv
->auth_or_assoc_retries
+ 1);
2825 acx_l_transmit_assoc_req(priv
);
2827 /* time exceeded: give up */
2829 "association request reply timeout, giving up\n");
2830 /* we are a STA, need to find AP anyhow */
2831 acx_set_status(priv
, ACX_STATUS_1_SCANNING
);
2832 acx_schedule_task(priv
, ACX_AFTER_IRQ_RESTART_SCAN
);
2834 acx_set_timer(priv
, 2500000); /* see above */
2836 case ACX_STATUS_4_ASSOCIATED
:
2841 acx_unlock(priv
, flags
);
2847 /*------------------------------------------------------------------------------
2850 * Sets the 802.11 state management timer's timeout.
2851 *----------------------------------------------------------------------------*/
2853 acx_set_timer(wlandevice_t
*priv
, int timeout_us
)
2857 acxlog(L_DEBUG
|L_IRQ
, "%s(%u ms)\n", __func__
, timeout_us
/1000);
2858 if (!(priv
->dev_state_mask
& ACX_STATE_IFACE_UP
)) {
2859 printk("attempt to set the timer "
2860 "when the card interface is not up!\n");
2864 /* first check if the timer was already initialized, THEN modify it */
2865 if (priv
->mgmt_timer
.function
) {
2866 mod_timer(&priv
->mgmt_timer
,
2867 jiffies
+ (timeout_us
* HZ
/ 1000000));
2874 /*----------------------------------------------------------------
2875 * acx_l_transmit_assocresp
2878 *----------------------------------------------------------------*/
2897 find_pos(const u8
*p
, int size
, u8 v
)
2900 for (i
= 0; i
< size
; i
++)
2903 /* printk a message about strange byte? */
2908 add_bits_to_ratemasks(u8
* ratevec
, int len
, u16
* brate
, u16
* orate
)
2911 int n
= 1 << find_pos(dot11ratebyte
,
2912 sizeof(dot11ratebyte
), *ratevec
& 0x7f);
2913 if (*ratevec
& 0x80)
2921 acx_l_transmit_assocresp(wlandevice_t
*priv
, const wlan_fr_assocreq_t
*req
)
2924 struct wlan_hdr_mgmt
*head
;
2925 struct assocresp_frame_body
*body
;
2934 /* sa = req->hdr->a1; */
2936 bssid
= req
->hdr
->a3
;
2938 clt
= acx_l_sta_list_get(priv
, da
);
2942 /* Assoc without auth is a big no-no */
2943 /* Let's be liberal: if already assoc'ed STA sends assoc req again,
2944 ** we won't be rude */
2945 if (clt
->used
!= CLIENT_AUTHENTICATED_2
2946 && clt
->used
!= CLIENT_ASSOCIATED_3
) {
2947 acx_l_transmit_deauthen(priv
, da
, WLAN_MGMT_REASON_CLASS2_NONAUTH
);
2951 clt
->used
= CLIENT_ASSOCIATED_3
;
2953 if (clt
->aid
== 0) {
2954 clt
->aid
= ++priv
->aid
;
2956 clt
->cap_info
= ieee2host16(*(req
->cap_info
));
2957 /* We cheat here a bit. We don't really care which rates are flagged
2958 ** as basic by the client, so we stuff them in single ratemask */
2960 if (req
->supp_rates
)
2961 add_bits_to_ratemasks(req
->supp_rates
->rates
,
2962 req
->supp_rates
->len
, &clt
->rate_cap
, &clt
->rate_cap
);
2964 add_bits_to_ratemasks(req
->ext_rates
->rates
,
2965 req
->ext_rates
->len
, &clt
->rate_cap
, &clt
->rate_cap
);
2966 /* We can check that client supports all basic rates,
2967 ** and deny assoc if not. But let's be liberal, right? ;) */
2968 clt
->rate_cfg
= clt
->rate_cap
& priv
->rate_oper
;
2969 if (!clt
->rate_cfg
) clt
->rate_cfg
= 1 << lowest_bit(priv
->rate_oper
);
2970 clt
->rate_cur
= 1 << lowest_bit(clt
->rate_cfg
);
2971 clt
->fallback_count
= clt
->stepup_count
= 0;
2972 clt
->ignore_count
= 16;
2974 tx
= acx_l_alloc_tx(priv
);
2977 head
= acx_l_get_txbuf(priv
, tx
);
2980 body
= (void*)(head
+ 1);
2982 head
->fc
= WF_FSTYPE_ASSOCRESPi
;
2983 head
->dur
= req
->hdr
->dur
;
2984 MAC_COPY(head
->da
, da
);
2985 /* MAC_COPY(head->sa, sa); */
2986 MAC_COPY(head
->sa
, priv
->dev_addr
);
2987 MAC_COPY(head
->bssid
, bssid
);
2988 head
->seq
= req
->hdr
->seq
;
2990 body
->cap_info
= host2ieee16(priv
->capabilities
);
2991 body
->status
= host2ieee16(0);
2992 body
->aid
= host2ieee16(clt
->aid
);
2993 p
= wlan_fill_ie_rates((u8
*)&body
->rates
, priv
->rate_supported_len
,
2994 priv
->rate_supported
);
2995 p
= wlan_fill_ie_rates_ext(p
, priv
->rate_supported_len
,
2996 priv
->rate_supported
);
2998 acx_l_tx_data(priv
, tx
, p
- (u8
*)head
);
3008 /*----------------------------------------------------------------
3009 * acx_l_transmit_reassocresp
3011 You may be wondering, just like me, what a hell is ReAuth.
3012 In practice it was seen sent by STA when STA feels like losing connection.
3016 5.4.2.3 Reassociation
3018 Association is sufficient for no-transition message delivery between
3019 IEEE 802.11 stations. Additional functionality is needed to support
3020 BSS-transition mobility. The additional required functionality
3021 is provided by the reassociation service. Reassociation is a DSS.
3022 The reassociation service is invoked to 'move' a current association
3023 from one AP to another. This keeps the DS informed of the current
3024 mapping between AP and STA as the station moves from BSS to BSS within
3025 an ESS. Reassociation also enables changing association attributes
3026 of an established association while the STA remains associated with
3027 the same AP. Reassociation is always initiated by the mobile STA.
3029 5.4.3.1 Authentication
3031 A STA may be authenticated with many other STAs at any given instant.
3033 5.4.3.1.1 Preauthentication
3035 Because the authentication process could be time-consuming (depending
3036 on the authentication protocol in use), the authentication service can
3037 be invoked independently of the association service. Preauthentication
3038 is typically done by a STA while it is already associated with an AP
3039 (with which it previously authenticated). IEEE 802.11 does not require
3040 that STAs preauthenticate with APs. However, authentication is required
3041 before an association can be established. If the authentication is left
3042 until reassociation time, this may impact the speed with which a STA can
3043 reassociate between APs, limiting BSS-transition mobility performance.
3044 The use of preauthentication takes the authentication service overhead
3045 out of the time-critical reassociation process.
3049 For a STA to reassociate, the reassociation service causes the following
3052 Reassociation request
3054 * Message type: Management
3055 * Message subtype: Reassociation request
3056 * Information items:
3057 - IEEE address of the STA
3058 - IEEE address of the AP with which the STA will reassociate
3059 - IEEE address of the AP with which the STA is currently associated
3061 * Direction of message: From STA to 'new' AP
3063 The address of the current AP is included for efficiency. The inclusion
3064 of the current AP address facilitates MAC reassociation to be independent
3065 of the DS implementation.
3067 Reassociation response
3068 * Message type: Management
3069 * Message subtype: Reassociation response
3070 * Information items:
3071 - Result of the requested reassociation. (success/failure)
3072 - If the reassociation is successful, the response shall include the AID.
3073 * Direction of message: From AP to STA
3075 7.2.3.6 Reassociation Request frame format
3077 The frame body of a management frame of subtype Reassociation Request
3078 contains the information shown in Table 9.
3080 Table 9 Reassociation Request frame body
3082 1 Capability information
3084 3 Current AP address
3088 7.2.3.7 Reassociation Response frame format
3090 The frame body of a management frame of subtype Reassociation Response
3091 contains the information shown in Table 10.
3093 Table 10 Reassociation Response frame body
3095 1 Capability information
3097 3 Association ID (AID)
3100 *----------------------------------------------------------------*/
3102 acx_l_transmit_reassocresp(wlandevice_t
*priv
, const wlan_fr_reassocreq_t
*req
)
3105 struct wlan_hdr_mgmt
*head
;
3106 struct reassocresp_frame_body
*body
;
3115 /* sa = req->hdr->a1; */
3117 bssid
= req
->hdr
->a3
;
3119 /* Must be already authenticated, so it must be in the list */
3120 clt
= acx_l_sta_list_get(priv
, da
);
3124 /* Assoc without auth is a big no-no */
3125 /* Already assoc'ed STAs sending ReAssoc req are ok per 802.11 */
3126 if (clt
->used
!= CLIENT_AUTHENTICATED_2
3127 && clt
->used
!= CLIENT_ASSOCIATED_3
) {
3128 acx_l_transmit_deauthen(priv
, da
, WLAN_MGMT_REASON_CLASS2_NONAUTH
);
3132 clt
->used
= CLIENT_ASSOCIATED_3
;
3133 if (clt
->aid
== 0) {
3134 clt
->aid
= ++priv
->aid
;
3137 clt
->cap_info
= ieee2host16(*(req
->cap_info
));
3138 /* We cheat here a bit. We don't really care which rates are flagged
3139 ** as basic by the client, so we stuff them in single ratemask */
3141 if (req
->supp_rates
)
3142 add_bits_to_ratemasks(req
->supp_rates
->rates
,
3143 req
->supp_rates
->len
, &clt
->rate_cap
, &clt
->rate_cap
);
3145 add_bits_to_ratemasks(req
->ext_rates
->rates
,
3146 req
->ext_rates
->len
, &clt
->rate_cap
, &clt
->rate_cap
);
3147 /* We can check that client supports all basic rates,
3148 ** and deny assoc if not. But let's be liberal, right? ;) */
3149 clt
->rate_cfg
= clt
->rate_cap
& priv
->rate_oper
;
3150 if (!clt
->rate_cfg
) clt
->rate_cfg
= 1 << lowest_bit(priv
->rate_oper
);
3151 clt
->rate_cur
= 1 << lowest_bit(clt
->rate_cfg
);
3152 clt
->fallback_count
= clt
->stepup_count
= 0;
3153 clt
->ignore_count
= 16;
3155 tx
= acx_l_alloc_tx(priv
);
3158 head
= acx_l_get_txbuf(priv
, tx
);
3161 body
= (void*)(head
+ 1);
3163 head
->fc
= WF_FSTYPE_REASSOCRESPi
;
3164 head
->dur
= req
->hdr
->dur
;
3165 MAC_COPY(head
->da
, da
);
3166 /* MAC_COPY(head->sa, sa); */
3167 MAC_COPY(head
->sa
, priv
->dev_addr
);
3168 MAC_COPY(head
->bssid
, bssid
);
3169 head
->seq
= req
->hdr
->seq
;
3172 body
->cap_info
= host2ieee16(priv
->capabilities
);
3173 /* 2. status code */
3174 body
->status
= host2ieee16(0);
3176 body
->aid
= host2ieee16(clt
->aid
);
3178 p
= wlan_fill_ie_rates((u8
*)&body
->rates
, priv
->rate_supported_len
,
3179 priv
->rate_supported
);
3180 /* 5. ext supp rates */
3181 p
= wlan_fill_ie_rates_ext(p
, priv
->rate_supported_len
,
3182 priv
->rate_supported
);
3184 acx_l_tx_data(priv
, tx
, p
- (u8
*)head
);
3194 /*----------------------------------------------------------------
3195 * acx_l_process_disassoc_from_sta
3196 *----------------------------------------------------------------*/
3198 acx_l_process_disassoc_from_sta(wlandevice_t
*priv
, const wlan_fr_disassoc_t
*req
)
3206 clt
= acx_l_sta_list_get(priv
, ta
);
3210 if (clt
->used
!= CLIENT_ASSOCIATED_3
3211 && clt
->used
!= CLIENT_AUTHENTICATED_2
) {
3212 /* it's disassociating, but it's
3213 ** not even authenticated! Let it know that */
3214 acxlog_mac(L_ASSOC
|L_XFER
, "peer ", ta
, "has sent disassoc "
3215 "req but it is not even auth'ed! sending deauth\n");
3216 acx_l_transmit_deauthen(priv
, ta
,
3217 WLAN_MGMT_REASON_CLASS2_NONAUTH
);
3218 clt
->used
= CLIENT_EXIST_1
;
3220 /* mark it as auth'ed only */
3221 clt
->used
= CLIENT_AUTHENTICATED_2
;
3228 /*----------------------------------------------------------------
3229 * acx_l_process_deauthen_from_sta
3230 *----------------------------------------------------------------*/
3232 acx_l_process_deauth_from_sta(wlandevice_t
*priv
, const wlan_fr_deauthen_t
*req
)
3234 const wlan_hdr_t
*hdr
;
3241 if (acx_debug
& L_ASSOC
) {
3242 acx_print_mac("DEAUTHEN priv->addr=", priv
->dev_addr
, " ");
3243 acx_print_mac("a1", hdr
->a1
, " ");
3244 acx_print_mac("a2", hdr
->a2
, " ");
3245 acx_print_mac("a3", hdr
->a3
, " ");
3246 acx_print_mac("priv->bssid", priv
->bssid
, "\n");
3249 if (!mac_is_equal(priv
->dev_addr
, hdr
->a1
)) {
3253 acxlog_mac(L_DEBUG
, "STA ", hdr
->a2
, " sent us deauthen packet\n");
3255 client
= acx_l_sta_list_get(priv
, hdr
->a2
);
3259 client
->used
= CLIENT_EXIST_1
;
3265 /*----------------------------------------------------------------
3266 * acx_l_process_disassoc_from_ap
3267 *----------------------------------------------------------------*/
3269 acx_l_process_disassoc_from_ap(wlandevice_t
*priv
, const wlan_fr_disassoc_t
*req
)
3273 if (!priv
->ap_client
) {
3274 /* Hrm, we aren't assoc'ed yet anyhow... */
3277 if (mac_is_equal(priv
->dev_addr
, req
->hdr
->a1
)) {
3278 acx_l_transmit_deauthen(priv
, priv
->bssid
,
3279 WLAN_MGMT_REASON_DEAUTH_LEAVING
);
3280 /* Start scan anew */
3281 SET_BIT(priv
->set_mask
, GETSET_RESCAN
);
3282 acx_schedule_task(priv
, ACX_AFTER_IRQ_UPDATE_CARD_CFG
);
3289 /*----------------------------------------------------------------
3290 * acx_l_process_deauth_from_ap
3291 *----------------------------------------------------------------*/
3293 acx_l_process_deauth_from_ap(wlandevice_t
*priv
, const wlan_fr_deauthen_t
*req
)
3297 if (!priv
->ap_client
) {
3298 /* Hrm, we aren't assoc'ed yet anyhow... */
3301 /* Chk: is ta is verified to be from our AP? */
3302 if (mac_is_equal(priv
->dev_addr
, req
->hdr
->a1
)) {
3303 acxlog(L_DEBUG
, "AP sent us deauth packet\n");
3304 /* not needed: acx_set_status(priv, ACX_STATUS_1_SCANNING) */
3305 SET_BIT(priv
->set_mask
, GETSET_RESCAN
);
3306 acx_schedule_task(priv
, ACX_AFTER_IRQ_UPDATE_CARD_CFG
);
3313 /*------------------------------------------------------------------------------
3316 * The end of the Rx path. Pulls data from a rxhostdesc into a socket
3317 * buffer and feeds it to the network stack via netif_rx().
3320 * rxdesc: the rxhostdesc to pull the data from
3321 * priv: the acx100 private struct of the interface
3322 *----------------------------------------------------------------------------*/
3324 acx_l_rx(wlandevice_t
*priv
, rxbuffer_t
*rxbuf
)
3327 if (likely(priv
->dev_state_mask
& ACX_STATE_IFACE_UP
)) {
3328 struct sk_buff
*skb
;
3329 skb
= acx_rxbuf_to_ether(priv
, rxbuf
);
3332 priv
->netdev
->last_rx
= jiffies
;
3333 priv
->stats
.rx_packets
++;
3334 priv
->stats
.rx_bytes
+= skb
->len
;
3341 /*----------------------------------------------------------------
3342 * acx_l_process_data_frame_master
3343 *----------------------------------------------------------------*/
3345 acx_l_process_data_frame_master(wlandevice_t
*priv
, rxbuffer_t
*rxbuf
)
3347 struct wlan_hdr
*hdr
;
3351 int result
= NOT_OK
;
3355 hdr
= acx_get_wlan_hdr(priv
, rxbuf
);
3357 switch (WF_FC_FROMTODSi
& hdr
->fc
) {
3360 acxlog(L_DEBUG
, "ap->sta or adhoc->adhoc data frame ignored\n");
3364 default: /* WF_FC_FROMTODSi */
3365 acxlog(L_DEBUG
, "wds data frame ignored (todo)\n");
3369 /* check if it is our BSSID, if not, leave */
3370 if (!mac_is_equal(priv
->bssid
, hdr
->a1
)) {
3374 if (mac_is_equal(priv
->dev_addr
, hdr
->a3
)) {
3375 /* this one is for us */
3376 acx_l_rx(priv
, rxbuf
);
3378 if (mac_is_bcast(hdr
->a3
)) {
3379 /* this one is bcast, rx it too */
3380 acx_l_rx(priv
, rxbuf
);
3382 tx
= acx_l_alloc_tx(priv
);
3386 /* repackage, tx, and hope it someday reaches its destination */
3387 /* order is important, we do it in-place */
3388 MAC_COPY(hdr
->a1
, hdr
->a3
);
3389 MAC_COPY(hdr
->a3
, hdr
->a2
);
3390 MAC_COPY(hdr
->a2
, priv
->bssid
);
3391 /* To_DS = 0, From_DS = 1 */
3392 hdr
->fc
= WF_FC_FROMDSi
+ WF_FTYPE_DATAi
;
3394 len
= RXBUF_BYTES_RCVD(rxbuf
);
3395 txbuf
= acx_l_get_txbuf(priv
, tx
);
3397 memcpy(txbuf
, &rxbuf
->hdr_a3
, len
);
3398 acx_l_tx_data(priv
, tx
, len
);
3409 /*----------------------------------------------------------------
3410 * acx_l_process_data_frame_client
3411 *----------------------------------------------------------------*/
3413 acx_l_process_data_frame_client(wlandevice_t
*priv
, rxbuffer_t
*rxbuf
)
3415 const u8
*da
, *bssid
;
3416 const wlan_hdr_t
*hdr
;
3417 netdevice_t
*dev
= priv
->netdev
;
3418 int result
= NOT_OK
;
3422 if (ACX_STATUS_4_ASSOCIATED
!= priv
->status
)
3425 hdr
= acx_get_wlan_hdr(priv
, rxbuf
);
3427 switch (WF_FC_FROMTODSi
& hdr
->fc
) {
3429 if (priv
->mode
!= ACX_MODE_0_ADHOC
) {
3430 acxlog(L_DEBUG
, "adhoc->adhoc data frame ignored\n");
3436 if (priv
->mode
!= ACX_MODE_2_STA
) {
3437 acxlog(L_DEBUG
, "ap->sta data frame ignored\n");
3443 acxlog(L_DEBUG
, "sta->ap data frame ignored\n");
3445 default: /* WF_FC_FROMTODSi: wds->wds */
3446 acxlog(L_DEBUG
, "wds data frame ignored (todo)\n");
3452 if (unlikely(acx_debug
& L_DEBUG
)) {
3453 acx_print_mac("rx: da=", da
, "");
3454 acx_print_mac(" bssid=", bssid
, "");
3455 acx_print_mac(" priv->bssid=", priv
->bssid
, "");
3456 acx_print_mac(" priv->addr=", priv
->dev_addr
, "\n");
3459 /* promiscuous mode --> receive all packets */
3460 if (unlikely(dev
->flags
& IFF_PROMISC
))
3463 /* FIRST, check if it is our BSSID */
3464 if (!mac_is_equal(priv
->bssid
, bssid
)) {
3465 /* is not our BSSID, so bail out */
3469 /* then, check if it is our address */
3470 if (mac_is_equal(priv
->dev_addr
, da
)) {
3474 /* then, check if it is broadcast */
3475 if (mac_is_bcast(da
)) {
3479 if (mac_is_mcast(da
)) {
3480 /* unconditionally receive all multicasts */
3481 if (dev
->flags
& IFF_ALLMULTI
)
3484 /* FIXME: check against the list of
3485 * multicast addresses that are configured
3486 * for the interface (ifconfig) */
3487 acxlog(L_XFER
, "FIXME: multicast packet, need to check "
3488 "against a list of multicast addresses "
3489 "(to be created!); accepting packet for now\n");
3490 /* for now, just accept it here */
3494 acxlog(L_DEBUG
, "rx: foreign packet, dropping\n");
3497 /* receive packet */
3498 acx_l_rx(priv
, rxbuf
);
3507 /*----------------------------------------------------------------
3508 * acx_l_process_mgmt_frame
3510 * Theory of operation: mgmt packet gets parsed (to make it easy
3511 * to access variable-sized IEs), results stored in 'parsed'.
3512 * Then we react to the packet.
3513 * NB: wlan_mgmt_decode_XXX are dev-independent (shoudnt have been named acx_XXX)
3514 *----------------------------------------------------------------*/
3515 typedef union parsed_mgmt_req
{
3516 wlan_fr_mgmt_t mgmt
;
3517 wlan_fr_assocreq_t assocreq
;
3518 wlan_fr_reassocreq_t reassocreq
;
3519 wlan_fr_assocresp_t assocresp
;
3520 wlan_fr_reassocresp_t reassocresp
;
3521 wlan_fr_beacon_t beacon
;
3522 wlan_fr_disassoc_t disassoc
;
3523 wlan_fr_authen_t authen
;
3524 wlan_fr_deauthen_t deauthen
;
3525 wlan_fr_proberesp_t proberesp
;
3526 } parsed_mgmt_req_t
;
3528 void BUG_excessive_stack_usage(void);
3531 acx_l_process_mgmt_frame(wlandevice_t
*priv
, rxbuffer_t
*rxbuf
)
3533 parsed_mgmt_req_t parsed
; /* takes ~100 bytes of stack */
3535 int adhoc
, sta_scan
, sta
, ap
;
3538 if (sizeof(parsed
) > 256)
3539 BUG_excessive_stack_usage();
3543 hdr
= acx_get_wlan_hdr(priv
, rxbuf
);
3545 /* Management frames never have these set */
3546 if (WF_FC_FROMTODSi
& hdr
->fc
) {
3551 len
= RXBUF_BYTES_RCVD(rxbuf
);
3552 if (WF_FC_ISWEPi
& hdr
->fc
)
3555 adhoc
= (priv
->mode
== ACX_MODE_0_ADHOC
);
3556 sta_scan
= ((priv
->mode
== ACX_MODE_2_STA
)
3557 && (priv
->status
!= ACX_STATUS_4_ASSOCIATED
));
3558 sta
= ((priv
->mode
== ACX_MODE_2_STA
)
3559 && (priv
->status
== ACX_STATUS_4_ASSOCIATED
));
3560 ap
= (priv
->mode
== ACX_MODE_3_AP
);
3562 switch (WF_FC_FSTYPEi
& hdr
->fc
) {
3563 /* beacons first, for speed */
3564 case WF_FSTYPE_BEACONi
:
3565 memset(&parsed
.beacon
, 0, sizeof(parsed
.beacon
));
3566 parsed
.beacon
.hdr
= hdr
;
3567 parsed
.beacon
.len
= len
;
3568 if (acx_debug
& L_DATA
) {
3569 printk("beacon len:%d fc:%04X dur:%04X seq:%04X",
3570 len
, hdr
->fc
, hdr
->dur
, hdr
->seq
);
3571 acx_print_mac(" a1:", hdr
->a1
, "");
3572 acx_print_mac(" a2:", hdr
->a2
, "");
3573 acx_print_mac(" a3:", hdr
->a3
, "\n");
3575 wlan_mgmt_decode_beacon(&parsed
.beacon
);
3576 /* beacon and probe response are very similar, so... */
3577 acx_l_process_probe_response(priv
, &parsed
.beacon
, rxbuf
);
3579 case WF_FSTYPE_ASSOCREQi
:
3582 memset(&parsed
.assocreq
, 0, sizeof(parsed
.assocreq
));
3583 parsed
.assocreq
.hdr
= hdr
;
3584 parsed
.assocreq
.len
= len
;
3585 wlan_mgmt_decode_assocreq(&parsed
.assocreq
);
3586 if (mac_is_equal(hdr
->a1
, priv
->bssid
)
3587 && mac_is_equal(hdr
->a3
, priv
->bssid
)) {
3588 acx_l_transmit_assocresp(priv
, &parsed
.assocreq
);
3591 case WF_FSTYPE_REASSOCREQi
:
3594 memset(&parsed
.assocreq
, 0, sizeof(parsed
.assocreq
));
3595 parsed
.assocreq
.hdr
= hdr
;
3596 parsed
.assocreq
.len
= len
;
3597 wlan_mgmt_decode_assocreq(&parsed
.assocreq
);
3598 /* reassocreq and assocreq are equivalent */
3599 acx_l_transmit_reassocresp(priv
, &parsed
.reassocreq
);
3601 case WF_FSTYPE_ASSOCRESPi
:
3604 memset(&parsed
.assocresp
, 0, sizeof(parsed
.assocresp
));
3605 parsed
.assocresp
.hdr
= hdr
;
3606 parsed
.assocresp
.len
= len
;
3607 wlan_mgmt_decode_assocresp(&parsed
.assocresp
);
3608 acx_l_process_assocresp(priv
, &parsed
.assocresp
);
3610 case WF_FSTYPE_REASSOCRESPi
:
3613 memset(&parsed
.assocresp
, 0, sizeof(parsed
.assocresp
));
3614 parsed
.assocresp
.hdr
= hdr
;
3615 parsed
.assocresp
.len
= len
;
3616 wlan_mgmt_decode_assocresp(&parsed
.assocresp
);
3617 acx_l_process_reassocresp(priv
, &parsed
.reassocresp
);
3619 case WF_FSTYPE_PROBEREQi
:
3621 /* FIXME: since we're supposed to be an AP,
3622 ** we need to return a Probe Response packet.
3623 ** Currently firmware is doing it for us,
3624 ** but firmware is buggy! See comment elsewhere --vda */
3627 case WF_FSTYPE_PROBERESPi
:
3628 memset(&parsed
.proberesp
, 0, sizeof(parsed
.proberesp
));
3629 parsed
.proberesp
.hdr
= hdr
;
3630 parsed
.proberesp
.len
= len
;
3631 wlan_mgmt_decode_proberesp(&parsed
.proberesp
);
3632 acx_l_process_probe_response(priv
, &parsed
.proberesp
, rxbuf
);
3638 case WF_FSTYPE_ATIMi
:
3641 case WF_FSTYPE_DISASSOCi
:
3644 memset(&parsed
.disassoc
, 0, sizeof(parsed
.disassoc
));
3645 parsed
.disassoc
.hdr
= hdr
;
3646 parsed
.disassoc
.len
= len
;
3647 wlan_mgmt_decode_disassoc(&parsed
.disassoc
);
3649 acx_l_process_disassoc_from_ap(priv
, &parsed
.disassoc
);
3651 acx_l_process_disassoc_from_sta(priv
, &parsed
.disassoc
);
3653 case WF_FSTYPE_AUTHENi
:
3654 if (!sta_scan
&& !ap
)
3656 memset(&parsed
.authen
, 0, sizeof(parsed
.authen
));
3657 parsed
.authen
.hdr
= hdr
;
3658 parsed
.authen
.len
= len
;
3659 wlan_mgmt_decode_authen(&parsed
.authen
);
3660 acx_l_process_authen(priv
, &parsed
.authen
);
3662 case WF_FSTYPE_DEAUTHENi
:
3665 memset(&parsed
.deauthen
, 0, sizeof(parsed
.deauthen
));
3666 parsed
.deauthen
.hdr
= hdr
;
3667 parsed
.deauthen
.len
= len
;
3668 wlan_mgmt_decode_deauthen(&parsed
.deauthen
);
3670 acx_l_process_deauth_from_ap(priv
, &parsed
.deauthen
);
3672 acx_l_process_deauth_from_sta(priv
, &parsed
.deauthen
);
3682 /*----------------------------------------------------------------
3683 * acx_process_class_frame
3685 * Called from IRQ context only
3686 *----------------------------------------------------------------*/
3688 acx_process_class_frame(wlandevice_t
*priv
, rxbuffer_t
*rxbuf
, int vala
)
3695 /*----------------------------------------------------------------
3696 * acx_l_process_NULL_frame
3697 *----------------------------------------------------------------*/
3698 #ifdef BOGUS_ITS_NOT_A_NULL_FRAME_HANDLER_AT_ALL
3700 acx_l_process_NULL_frame(wlandevice_t
*priv
, rxbuffer_t
*rxbuf
, int vala
)
3702 const signed char *esi
;
3704 const wlan_hdr_t
*hdr
;
3705 const client_t
*client
;
3706 int result
= NOT_OK
;
3708 hdr
= acx_get_wlan_hdr(priv
, rxbuf
);
3710 switch (WF_FC_FROMTODSi
& hdr
->fc
) {
3723 default: /* WF_FC_FROMTODSi */
3724 esi
= hdr
->a1
; /* added by me! --vda */
3733 client
= acx_l_sta_list_get(priv
, ebx
);
3738 acxlog(L_DEBUG
|L_XFER
, "<transmit_deauth 7>\n");
3739 acx_l_transmit_deauthen(priv
, ebx
,
3740 WLAN_MGMT_REASON_CLASS2_NONAUTH
);
3742 acxlog(L_DEBUG
, "received NULL frame from unknown client! "
3743 "We really shouldn't send deauthen here, right?\n");
3753 /*----------------------------------------------------------------
3754 * acx_l_process_probe_response
3755 *----------------------------------------------------------------*/
3757 acx_l_process_probe_response(wlandevice_t
*priv
, wlan_fr_proberesp_t
*req
,
3758 const rxbuffer_t
*rxbuf
)
3767 if (mac_is_equal(hdr
->a3
, priv
->dev_addr
)) {
3768 acxlog(L_ASSOC
, "huh, scan found our own MAC!?\n");
3769 goto ok
; /* just skip this one silently */
3772 bss
= acx_l_sta_list_get_or_add(priv
, hdr
->a2
);
3774 /* NB: be careful modifying bss data! It may be one
3775 ** of already known clients (like our AP is we are a STA)
3776 ** Thus do not blindly modify e.g. current ratemask! */
3778 if (STA_LIST_ADD_CAN_FAIL
&& !bss
) {
3779 /* uh oh, we found more sites/stations than we can handle with
3780 * our current setup: pull the emergency brake and stop scanning! */
3781 acx_schedule_task(priv
, ACX_AFTER_IRQ_CMD_STOP_SCAN
);
3782 /* TODO: a nice comment what below call achieves --vda */
3783 acx_set_status(priv
, ACX_STATUS_2_WAIT_AUTH
);
3786 /* NB: get_or_add already filled bss->address = hdr->a2 */
3787 MAC_COPY(bss
->bssid
, hdr
->a3
);
3789 /* copy the ESSID element */
3790 if (req
->ssid
&& req
->ssid
->len
<= IW_ESSID_MAX_SIZE
) {
3791 bss
->essid_len
= req
->ssid
->len
;
3792 memcpy(bss
->essid
, req
->ssid
->ssid
, req
->ssid
->len
);
3793 bss
->essid
[req
->ssid
->len
] = '\0';
3795 /* Either no ESSID IE or oversized one */
3796 printk("%s: received packet has bogus ESSID\n",
3797 priv
->netdev
->name
);
3801 bss
->channel
= req
->ds_parms
->curr_ch
;
3803 bss
->cap_info
= ieee2host16(*req
->cap_info
);
3805 bss
->sir
= acx_signal_to_winlevel(rxbuf
->phy_level
);
3806 bss
->snr
= acx_signal_to_winlevel(rxbuf
->phy_snr
);
3808 bss
->rate_cap
= 0; /* operational mask */
3809 bss
->rate_bas
= 0; /* basic mask */
3810 if (req
->supp_rates
)
3811 add_bits_to_ratemasks(req
->supp_rates
->rates
,
3812 req
->supp_rates
->len
, &bss
->rate_bas
, &bss
->rate_cap
);
3814 add_bits_to_ratemasks(req
->ext_rates
->rates
,
3815 req
->ext_rates
->len
, &bss
->rate_bas
, &bss
->rate_cap
);
3816 /* Fix up any possible bogosity - code elsewhere
3817 * is not expecting empty masks */
3819 bss
->rate_cap
= priv
->rate_basic
;
3821 bss
->rate_bas
= 1 << lowest_bit(bss
->rate_cap
);
3823 bss
->rate_cur
= 1 << lowest_bit(bss
->rate_bas
);
3825 /* People moan about this being too noisy at L_ASSOC */
3827 "found %s: ESSID='%s' ch=%d "
3828 "BSSID="MACSTR
" caps=0x%04X SIR=%d SNR=%d\n",
3829 (bss
->cap_info
& WF_MGMT_CAP_IBSS
) ? "Ad-Hoc peer" : "AP",
3830 bss
->essid
, bss
->channel
, MAC(bss
->bssid
), bss
->cap_info
,
3831 bss
->sir
, bss
->snr
);
3838 /*----------------------------------------------------------------
3839 * acx_l_process_assocresp
3840 *----------------------------------------------------------------*/
3842 acx_l_process_assocresp(wlandevice_t
*priv
, const wlan_fr_assocresp_t
*req
)
3844 const wlan_hdr_t
*hdr
;
3850 if ((ACX_MODE_2_STA
== priv
->mode
)
3851 && mac_is_equal(priv
->dev_addr
, hdr
->a1
)) {
3852 u16 st
= ieee2host16(*(req
->status
));
3853 if (WLAN_MGMT_STATUS_SUCCESS
== st
) {
3854 priv
->aid
= ieee2host16(*(req
->aid
));
3855 /* tell the card we are associated when we are out of interrupt context */
3856 acx_schedule_task(priv
, ACX_AFTER_IRQ_CMD_ASSOCIATE
);
3859 /* TODO: we shall delete peer from sta_list, and try other candidates... */
3861 printk("%s: association FAILED: peer sent "
3862 "response code %d (%s)\n",
3863 priv
->netdev
->name
, st
, get_status_string(st
));
3873 /*----------------------------------------------------------------
3874 * acx_l_process_reassocresp
3875 *----------------------------------------------------------------*/
3877 acx_l_process_reassocresp(wlandevice_t
*priv
, const wlan_fr_reassocresp_t
*req
)
3879 const wlan_hdr_t
*hdr
;
3880 int result
= NOT_OK
;
3886 if (!mac_is_equal(priv
->dev_addr
, hdr
->a1
)) {
3889 st
= ieee2host16(*(req
->status
));
3890 if (st
== WLAN_MGMT_STATUS_SUCCESS
) {
3891 acx_set_status(priv
, ACX_STATUS_4_ASSOCIATED
);
3894 printk("%s: reassociation FAILED: peer sent "
3895 "response code %d (%s)\n",
3896 priv
->netdev
->name
, st
, get_status_string(st
));
3904 /*----------------------------------------------------------------
3905 * acx_l_process_authen
3907 * Called only in STA_SCAN or AP mode
3908 *----------------------------------------------------------------*/
3910 acx_l_process_authen(wlandevice_t
*priv
, const wlan_fr_authen_t
*req
)
3912 const wlan_hdr_t
*hdr
;
3914 wlan_ie_challenge_t
*chal
;
3915 u16 alg
, seq
, status
;
3922 if (acx_debug
& L_ASSOC
) {
3923 acx_print_mac("AUTHEN priv->addr=", priv
->dev_addr
, " ");
3924 acx_print_mac("a1=", hdr
->a1
, " ");
3925 acx_print_mac("a2=", hdr
->a2
, " ");
3926 acx_print_mac("a3=", hdr
->a3
, " ");
3927 acx_print_mac("priv->bssid=", priv
->bssid
, "\n");
3930 if (!mac_is_equal(priv
->dev_addr
, hdr
->a1
)
3931 || !mac_is_equal(priv
->bssid
, hdr
->a3
)) {
3936 alg
= ieee2host16(*(req
->auth_alg
));
3937 seq
= ieee2host16(*(req
->auth_seq
));
3938 status
= ieee2host16(*(req
->status
));
3940 ap
= (priv
->mode
== ACX_MODE_3_AP
);
3942 if (priv
->auth_alg
<= 1) {
3943 if (priv
->auth_alg
!= alg
) {
3944 acxlog(L_ASSOC
, "authentication algorithm mismatch: "
3945 "want: %d, req: %d\n", priv
->auth_alg
, alg
);
3950 acxlog(L_ASSOC
, "algorithm is ok\n");
3953 clt
= acx_l_sta_list_get_or_add(priv
, hdr
->a2
);
3954 if (STA_LIST_ADD_CAN_FAIL
&& !clt
) {
3955 acxlog(L_ASSOC
, "could not allocate room for client\n");
3960 clt
= priv
->ap_client
;
3961 if (!mac_is_equal(clt
->address
, hdr
->a2
)) {
3962 printk("%s: malformed auth frame from AP?!\n",
3963 priv
->netdev
->name
);
3969 /* now check which step in the authentication sequence we are
3970 * currently in, and act accordingly */
3971 acxlog(L_ASSOC
, "acx_process_authen auth seq step %d\n", seq
);
3976 acx_l_transmit_authen2(priv
, req
, clt
);
3981 if (status
== WLAN_MGMT_STATUS_SUCCESS
) {
3982 if (alg
== WLAN_AUTH_ALG_OPENSYSTEM
) {
3983 acx_set_status(priv
, ACX_STATUS_3_AUTHENTICATED
);
3984 acx_l_transmit_assoc_req(priv
);
3986 if (alg
== WLAN_AUTH_ALG_SHAREDKEY
) {
3987 acx_l_transmit_authen3(priv
, req
);
3990 printk("%s: auth FAILED: peer sent "
3991 "response code %d (%s), "
3992 "still waiting for authentication\n",
3994 status
, get_status_string(status
));
3995 acx_set_status(priv
, ACX_STATUS_2_WAIT_AUTH
);
4001 if ((clt
->auth_alg
!= WLAN_AUTH_ALG_SHAREDKEY
)
4002 || (alg
!= WLAN_AUTH_ALG_SHAREDKEY
)
4003 || (clt
->auth_step
!= 2))
4005 chal
= req
->challenge
;
4007 || memcmp(chal
->challenge
, clt
->challenge_text
, WLAN_CHALLENGE_LEN
)
4008 || (chal
->eid
!= WLAN_EID_CHALLENGE
)
4009 || (chal
->len
!= WLAN_CHALLENGE_LEN
)
4012 acx_l_transmit_authen4(priv
, req
);
4013 MAC_COPY(clt
->address
, hdr
->a2
);
4014 clt
->used
= CLIENT_AUTHENTICATED_2
;
4016 clt
->seq
= ieee2host16(hdr
->seq
);
4021 /* ok, we're through: we're authenticated. Woohoo!! */
4022 acx_set_status(priv
, ACX_STATUS_3_AUTHENTICATED
);
4023 acxlog(L_ASSOC
, "Authenticated!\n");
4024 /* now that we're authenticated, request association */
4025 acx_l_transmit_assoc_req(priv
);
4035 /*----------------------------------------------------------------
4037 *----------------------------------------------------------------*/
4039 acx_gen_challenge(wlan_ie_challenge_t
* d
)
4042 d
->eid
= WLAN_EID_CHALLENGE
;
4043 d
->len
= WLAN_CHALLENGE_LEN
;
4044 get_random_bytes(d
->challenge
, WLAN_CHALLENGE_LEN
);
4049 /*----------------------------------------------------------------
4050 * acx_l_transmit_deauthen
4051 *----------------------------------------------------------------*/
4053 acx_l_transmit_deauthen(wlandevice_t
*priv
, const u8
*addr
, u16 reason
)
4056 struct wlan_hdr_mgmt
*head
;
4057 struct deauthen_frame_body
*body
;
4061 tx
= acx_l_alloc_tx(priv
);
4064 head
= acx_l_get_txbuf(priv
, tx
);
4067 body
= (void*)(head
+ 1);
4069 head
->fc
= (WF_FTYPE_MGMTi
| WF_FSTYPE_DEAUTHENi
);
4071 MAC_COPY(head
->da
, addr
);
4072 MAC_COPY(head
->sa
, priv
->dev_addr
);
4073 MAC_COPY(head
->bssid
, priv
->bssid
);
4076 acxlog(L_DEBUG
|L_ASSOC
|L_XFER
,
4077 "sending deauthen to "MACSTR
" for %d\n",
4080 body
->reason
= host2ieee16(reason
);
4082 /* body is fixed size here, but beware of cutting-and-pasting this -
4083 ** do not use sizeof(*body) for variable sized mgmt packets! */
4084 acx_l_tx_data(priv
, tx
, WLAN_HDR_A3_LEN
+ sizeof(*body
));
4094 /*----------------------------------------------------------------
4095 * acx_l_transmit_authen1
4096 *----------------------------------------------------------------*/
4098 acx_l_transmit_authen1(wlandevice_t
*priv
)
4101 struct wlan_hdr_mgmt
*head
;
4102 struct auth_frame_body
*body
;
4106 acxlog(L_ASSOC
, "Sending authentication1 request, "
4107 "awaiting response!\n");
4109 tx
= acx_l_alloc_tx(priv
);
4112 head
= acx_l_get_txbuf(priv
, tx
);
4115 body
= (void*)(head
+ 1);
4117 head
->fc
= WF_FSTYPE_AUTHENi
;
4118 head
->dur
= host2ieee16(0x8000);
4119 MAC_COPY(head
->da
, priv
->bssid
);
4120 MAC_COPY(head
->sa
, priv
->dev_addr
);
4121 MAC_COPY(head
->bssid
, priv
->bssid
);
4124 body
->auth_alg
= host2ieee16(priv
->auth_alg
);
4125 body
->auth_seq
= host2ieee16(1);
4126 body
->status
= host2ieee16(0);
4128 acx_l_tx_data(priv
, tx
, WLAN_HDR_A3_LEN
+ 2 + 2 + 2);
4138 /*----------------------------------------------------------------
4139 * acx_l_transmit_authen2
4140 *----------------------------------------------------------------*/
4142 acx_l_transmit_authen2(wlandevice_t
*priv
, const wlan_fr_authen_t
*req
,
4146 struct wlan_hdr_mgmt
*head
;
4147 struct auth_frame_body
*body
;
4148 unsigned int packet_len
;
4155 MAC_COPY(clt
->address
, req
->hdr
->a2
);
4157 clt
->ps
= ((WF_FC_PWRMGTi
& req
->hdr
->fc
) != 0);
4159 clt
->auth_alg
= ieee2host16(*(req
->auth_alg
));
4161 clt
->seq
= ieee2host16(req
->hdr
->seq
);
4163 tx
= acx_l_alloc_tx(priv
);
4166 head
= acx_l_get_txbuf(priv
, tx
);
4169 body
= (void*)(head
+ 1);
4171 head
->fc
= WF_FSTYPE_AUTHENi
; /* 0xb0 */
4172 head
->dur
= req
->hdr
->dur
;
4173 MAC_COPY(head
->da
, req
->hdr
->a2
);
4174 /* MAC_COPY(head->sa, req->hdr->a1); */
4175 MAC_COPY(head
->sa
, priv
->dev_addr
);
4176 MAC_COPY(head
->bssid
, req
->hdr
->a3
);
4177 head
->seq
= req
->hdr
->seq
;
4179 /* already in IEEE format, no endianness conversion */
4180 body
->auth_alg
= *(req
->auth_alg
);
4181 body
->auth_seq
= host2ieee16(2);
4182 body
->status
= host2ieee16(0);
4184 packet_len
= WLAN_HDR_A3_LEN
+ 2 + 2 + 2;
4185 if (ieee2host16(*(req
->auth_alg
)) == WLAN_AUTH_ALG_OPENSYSTEM
) {
4186 clt
->used
= CLIENT_AUTHENTICATED_2
;
4187 } else { /* shared key */
4188 acx_gen_challenge(&body
->challenge
);
4189 memcpy(&clt
->challenge_text
, body
->challenge
.challenge
, WLAN_CHALLENGE_LEN
);
4190 packet_len
+= 2 + 2 + 2 + 1+1+WLAN_CHALLENGE_LEN
;
4193 acxlog_mac(L_ASSOC
|L_XFER
,
4194 "transmit_auth2: BSSID=", head
->bssid
, "\n");
4196 acx_l_tx_data(priv
, tx
, packet_len
);
4206 /*----------------------------------------------------------------
4207 * acx_l_transmit_authen3
4208 *----------------------------------------------------------------*/
4210 acx_l_transmit_authen3(wlandevice_t
*priv
, const wlan_fr_authen_t
*req
)
4213 struct wlan_hdr_mgmt
*head
;
4214 struct auth_frame_body
*body
;
4215 unsigned int packet_len
;
4219 tx
= acx_l_alloc_tx(priv
);
4222 head
= acx_l_get_txbuf(priv
, tx
);
4225 body
= (void*)(head
+ 1);
4227 head
->fc
= WF_FC_ISWEPi
+ WF_FSTYPE_AUTHENi
;
4228 /* FIXME: is this needed?? authen4 does it...
4229 head->dur = req->hdr->dur;
4230 head->seq = req->hdr->seq;
4232 MAC_COPY(head
->da
, priv
->bssid
);
4233 MAC_COPY(head
->sa
, priv
->dev_addr
);
4234 MAC_COPY(head
->bssid
, priv
->bssid
);
4236 /* already in IEEE format, no endianness conversion */
4237 body
->auth_alg
= *(req
->auth_alg
);
4238 body
->auth_seq
= host2ieee16(3);
4239 body
->status
= host2ieee16(0);
4240 memcpy(&body
->challenge
, req
->challenge
, req
->challenge
->len
+ 2);
4241 packet_len
= WLAN_HDR_A3_LEN
+ 8 + req
->challenge
->len
;
4243 acxlog(L_ASSOC
|L_XFER
, "transmit_authen3!\n");
4245 acx_l_tx_data(priv
, tx
, packet_len
);
4252 /*----------------------------------------------------------------
4253 * acx_l_transmit_authen4
4254 *----------------------------------------------------------------*/
4256 acx_l_transmit_authen4(wlandevice_t
*priv
, const wlan_fr_authen_t
*req
)
4259 struct wlan_hdr_mgmt
*head
;
4260 struct auth_frame_body
*body
;
4264 tx
= acx_l_alloc_tx(priv
);
4267 head
= acx_l_get_txbuf(priv
, tx
);
4270 body
= (void*)(head
+ 1);
4272 head
->fc
= WF_FSTYPE_AUTHENi
; /* 0xb0 */
4273 head
->dur
= req
->hdr
->dur
;
4274 MAC_COPY(head
->da
, req
->hdr
->a2
);
4275 /* MAC_COPY(head->sa, req->hdr->a1); */
4276 MAC_COPY(head
->sa
, priv
->dev_addr
);
4277 MAC_COPY(head
->bssid
, req
->hdr
->a3
);
4278 head
->seq
= req
->hdr
->seq
;
4280 /* already in IEEE format, no endianness conversion */
4281 body
->auth_alg
= *(req
->auth_alg
);
4282 body
->auth_seq
= host2ieee16(4);
4283 body
->status
= host2ieee16(0);
4285 acx_l_tx_data(priv
, tx
, WLAN_HDR_A3_LEN
+ 2 + 2 + 2);
4292 /*----------------------------------------------------------------
4293 * acx_l_transmit_assoc_req
4295 * priv->ap_client is a current candidate AP here
4296 *----------------------------------------------------------------*/
4298 acx_l_transmit_assoc_req(wlandevice_t
*priv
)
4301 struct wlan_hdr_mgmt
*head
;
4302 u8
*body
, *p
, *prate
;
4303 unsigned int packet_len
;
4308 acxlog(L_ASSOC
, "sending association request, "
4309 "awaiting response. NOT ASSOCIATED YET\n");
4310 tx
= acx_l_alloc_tx(priv
);
4313 head
= acx_l_get_txbuf(priv
, tx
);
4316 body
= (void*)(head
+ 1);
4318 head
->fc
= WF_FSTYPE_ASSOCREQi
;
4319 head
->dur
= host2ieee16(0x8000);
4320 MAC_COPY(head
->da
, priv
->bssid
);
4321 MAC_COPY(head
->sa
, priv
->dev_addr
);
4322 MAC_COPY(head
->bssid
, priv
->bssid
);
4326 /* now start filling the AssocReq frame body */
4328 /* since this assoc request will most likely only get
4329 * sent in the STA to AP case (and not when Ad-Hoc IBSS),
4330 * the cap combination indicated here will thus be
4331 * WF_MGMT_CAP_ESSi *always* (no IBSS ever)
4332 * The specs are more than non-obvious on all that:
4334 * 802.11 7.3.1.4 Capability Information field
4335 ** APs set the ESS subfield to 1 and the IBSS subfield to 0 within
4336 ** Beacon or Probe Response management frames. STAs within an IBSS
4337 ** set the ESS subfield to 0 and the IBSS subfield to 1 in transmitted
4338 ** Beacon or Probe Response management frames
4340 ** APs set the Privacy subfield to 1 within transmitted Beacon,
4341 ** Probe Response, Association Response, and Reassociation Response
4342 ** if WEP is required for all data type frames within the BSS.
4343 ** STAs within an IBSS set the Privacy subfield to 1 in Beacon
4344 ** or Probe Response management frames if WEP is required
4345 ** for all data type frames within the IBSS */
4347 /* note that returning 0 will be refused by several APs...
4348 * (so this indicates that you're probably supposed to
4349 * "confirm" the ESS mode) */
4350 cap
= WF_MGMT_CAP_ESSi
;
4352 /* this one used to be a check on wep_restricted,
4353 * but more likely it's wep_enabled instead */
4354 if (priv
->wep_enabled
)
4355 SET_BIT(cap
, WF_MGMT_CAP_PRIVACYi
);
4357 /* Probably we can just set these always, because our hw is
4358 ** capable of shortpre and PBCC --vda */
4359 /* only ask for short preamble if the peer station supports it */
4360 if (priv
->ap_client
->cap_info
& WF_MGMT_CAP_SHORT
)
4361 SET_BIT(cap
, WF_MGMT_CAP_SHORTi
);
4362 /* only ask for PBCC support if the peer station supports it */
4363 if (priv
->ap_client
->cap_info
& WF_MGMT_CAP_PBCC
)
4364 SET_BIT(cap
, WF_MGMT_CAP_PBCCi
);
4367 *(u16
*)p
= cap
; p
+= 2;
4368 /* 2. listen interval */
4369 *(u16
*)p
= host2ieee16(priv
->listen_interval
); p
+= 2;
4371 p
= wlan_fill_ie_ssid(p
,
4372 strlen(priv
->essid_for_assoc
), priv
->essid_for_assoc
);
4375 p
= wlan_fill_ie_rates(p
,
4376 priv
->rate_supported_len
, priv
->rate_supported
);
4377 /* 5. ext supp rates */
4378 p
= wlan_fill_ie_rates_ext(p
,
4379 priv
->rate_supported_len
, priv
->rate_supported
);
4381 if (acx_debug
& L_DEBUG
) {
4382 printk("association: rates element\n");
4383 acx_dump_bytes(prate
, p
- prate
);
4386 /* calculate lengths */
4387 packet_len
= WLAN_HDR_A3_LEN
+ (p
- body
);
4389 acxlog(L_ASSOC
, "association: requesting caps 0x%04X, ESSID '%s'\n",
4390 cap
, priv
->essid_for_assoc
);
4392 acx_l_tx_data(priv
, tx
, packet_len
);
4401 /*----------------------------------------------------------------
4402 * acx_l_transmit_disassoc
4404 * FIXME: looks like incomplete implementation of a helper:
4405 * acx_l_transmit_disassoc(priv, clt) - kick this client (we're an AP)
4406 * acx_l_transmit_disassoc(priv, NULL) - leave BSSID (we're a STA)
4407 *----------------------------------------------------------------*/
4410 acx_l_transmit_disassoc(wlandevice_t
*priv
, client_t
*clt
)
4413 struct wlan_hdr_mgmt
*head
;
4414 struct disassoc_frame_body
*body
;
4417 /* if (clt != NULL) { */
4418 tx
= acx_l_alloc_tx(priv
);
4421 head
= acx_l_get_txbuf(priv
, tx
);
4424 body
= (void*)(head
+ 1);
4426 /* clt->used = CLIENT_AUTHENTICATED_2; - not (yet?) associated */
4428 head
->fc
= WF_FSTYPE_DISASSOCi
;
4430 /* huh? It muchly depends on whether we're STA or AP...
4431 ** sta->ap: da=bssid, sa=own, bssid=bssid
4432 ** ap->sta: da=sta, sa=bssid, bssid=bssid. FIXME! */
4433 MAC_COPY(head
->da
, priv
->bssid
);
4434 MAC_COPY(head
->sa
, priv
->dev_addr
);
4435 MAC_COPY(head
->bssid
, priv
->dev_addr
);
4438 /* "Class 3 frame received from nonassociated station." */
4439 body
->reason
= host2ieee16(7);
4441 /* fixed size struct, ok to sizeof */
4442 acx_l_tx_data(priv
, tx
, WLAN_HDR_A3_LEN
+ sizeof(*body
));
4453 /*----------------------------------------------------------------
4454 * acx_s_complete_scan
4456 * Called either from after_interrupt_task() if:
4457 * 1) there was Scan_Complete IRQ, or
4458 * 2) scanning expired in timer()
4459 * We need to decide which ESS or IBSS to join.
4460 * Iterates thru priv->sta_list:
4461 * if priv->ap is not bcast, will join only specified
4462 * ESS or IBSS with this bssid
4463 * checks peers' caps for ESS/IBSS bit
4464 * checks peers' SSID, allows exact match or hidden SSID
4465 * If station to join is chosen:
4466 * points priv->ap_client to the chosen struct client
4467 * sets priv->essid_for_assoc for future assoc attempt
4468 * Auth/assoc is not yet performed
4469 * Returns OK if there is no need to restart scan
4470 *----------------------------------------------------------------*/
4472 acx_s_complete_scan(wlandevice_t
*priv
)
4475 unsigned long flags
;
4483 switch (priv
->mode
) {
4484 case ACX_MODE_0_ADHOC
:
4485 needed_cap
= WF_MGMT_CAP_IBSS
; /* 2, we require Ad-Hoc */
4487 case ACX_MODE_2_STA
:
4488 needed_cap
= WF_MGMT_CAP_ESS
; /* 1, we require Managed */
4491 printk("acx: driver bug: mode=%d in complete_scan()\n", priv
->mode
);
4496 acx_lock(priv
, flags
);
4498 /* TODO: sta_iterator hiding implementation would be nice here... */
4500 for (i
= 0; i
< VEC_SIZE(priv
->sta_list
); i
++) {
4501 bss
= &priv
->sta_list
[i
];
4502 if (!bss
->used
) continue;
4504 acxlog(L_ASSOC
, "Scan Table: SSID='%s' CH=%d SIR=%d SNR=%d\n",
4505 bss
->essid
, bss
->channel
, bss
->sir
, bss
->snr
);
4507 if (!mac_is_bcast(priv
->ap
))
4508 if (!mac_is_equal(bss
->bssid
, priv
->ap
))
4509 continue; /* keep looking */
4511 /* broken peer with no mode flags set? */
4512 if (unlikely(!(bss
->cap_info
& (WF_MGMT_CAP_ESS
| WF_MGMT_CAP_IBSS
)))) {
4513 printk("%s: strange peer "MACSTR
" found with "
4514 "neither ESS (AP) nor IBSS (Ad-Hoc) "
4515 "capability - skipped\n",
4516 priv
->netdev
->name
, MAC(bss
->address
));
4519 acxlog(L_ASSOC
, "peer_cap 0x%04X, needed_cap 0x%04X\n",
4520 bss
->cap_info
, needed_cap
);
4522 /* does peer station support what we need? */
4523 if ((bss
->cap_info
& needed_cap
) != needed_cap
)
4524 continue; /* keep looking */
4526 /* strange peer with NO basic rates?! */
4527 if (unlikely(!bss
->rate_bas
)) {
4528 printk("%s: strange peer "MACSTR
" with empty rate set "
4530 priv
->netdev
->name
, MAC(bss
->address
));
4534 /* do we support all basic rates of this peer? */
4535 if ((bss
->rate_bas
& priv
->rate_oper
) != bss
->rate_bas
) {
4536 /* we probably need to have all rates as operational rates,
4537 even in case of an 11M-only configuration */
4538 #ifdef THIS_IS_TROUBLESOME
4539 printk("%s: peer "MACSTR
": incompatible basic rates "
4540 "(AP requests 0x%04X, we have 0x%04X) "
4542 priv
->netdev
->name
, MAC(bss
->address
),
4543 bss
->rate_bas
, priv
->rate_oper
);
4546 printk("%s: peer "MACSTR
": incompatible basic rates "
4547 "(AP requests 0x%04X, we have 0x%04X). "
4548 "Considering anyway...\n",
4549 priv
->netdev
->name
, MAC(bss
->address
),
4550 bss
->rate_bas
, priv
->rate_oper
);
4554 if ( !(priv
->reg_dom_chanmask
& (1<<(bss
->channel
-1))) ) {
4555 printk("%s: warning: peer "MACSTR
" is on channel %d "
4556 "outside of channel range of current "
4557 "regulatory domain - couldn't join "
4558 "even if other settings match. "
4559 "You might want to adapt your config\n",
4560 priv
->netdev
->name
, MAC(bss
->address
),
4562 continue; /* keep looking */
4565 if (!priv
->essid_active
|| !strcmp(bss
->essid
, priv
->essid
)) {
4567 "found station with matching ESSID! ('%s' "
4568 "station, '%s' config)\n",
4570 (priv
->essid_active
) ? priv
->essid
: "[any]");
4571 /* TODO: continue looking for peer with better SNR */
4572 bss
->used
= CLIENT_JOIN_CANDIDATE
;
4575 /* stop searching if this station is
4576 * on the current channel, otherwise
4577 * keep looking for an even better match */
4578 if (bss
->channel
== priv
->channel
)
4582 || ((' ' == bss
->essid
[0]) && !bss
->essid
[1])
4584 /* hmm, station with empty or single-space SSID:
4585 * using hidden SSID broadcast?
4587 /* This behaviour is broken: which AP from zillion
4588 ** of APs with hidden SSID you'd try?
4589 ** We should use Probe requests to get Probe responses
4590 ** and check for real SSID (are those never hidden?) */
4591 bss
->used
= CLIENT_JOIN_CANDIDATE
;
4592 if (idx_found
== -1)
4594 acxlog(L_ASSOC
, "found station with empty or "
4595 "single-space (hidden) SSID, considering "
4596 "for assoc attempt\n");
4597 /* ...and keep looking for better matches */
4599 acxlog(L_ASSOC
, "ESSID doesn't match! ('%s' "
4600 "station, '%s' config)\n",
4602 (priv
->essid_active
) ? priv
->essid
: "[any]");
4606 /* TODO: iterate thru join candidates instead */
4607 /* TODO: rescan if not associated within some timeout */
4608 if (idx_found
!= -1) {
4612 bss
= &priv
->sta_list
[idx_found
];
4613 priv
->ap_client
= bss
;
4615 if (bss
->essid
[0] == '\0') {
4616 /* if the ESSID of the station we found is empty
4617 * (no broadcast), then use user configured ESSID
4619 essid_src
= priv
->essid
;
4620 essid_len
= priv
->essid_len
;
4622 essid_src
= bss
->essid
;
4623 essid_len
= strlen(bss
->essid
);
4626 acx_update_capabilities(priv
);
4628 memcpy(priv
->essid_for_assoc
, essid_src
, essid_len
);
4629 priv
->essid_for_assoc
[essid_len
] = '\0';
4630 priv
->channel
= bss
->channel
;
4631 MAC_COPY(priv
->bssid
, bss
->bssid
);
4633 bss
->rate_cfg
= (bss
->rate_cap
& priv
->rate_oper
);
4634 bss
->rate_cur
= 1 << lowest_bit(bss
->rate_cfg
);
4635 bss
->rate_100
= acx_rate111to100(bss
->rate_cur
);
4638 "matching station found: ", priv
->bssid
, ", joining\n");
4640 /* TODO: do we need to switch to the peer's channel first? */
4642 if (ACX_MODE_0_ADHOC
== priv
->mode
) {
4643 acx_set_status(priv
, ACX_STATUS_4_ASSOCIATED
);
4645 acx_l_transmit_authen1(priv
);
4646 acx_set_status(priv
, ACX_STATUS_2_WAIT_AUTH
);
4648 } else { /* idx_found == -1 */
4649 /* uh oh, no station found in range */
4650 if (ACX_MODE_0_ADHOC
== priv
->mode
) {
4651 printk("%s: no matching station found in range, "
4652 "generating our own IBSS instead\n",
4653 priv
->netdev
->name
);
4654 /* we do it hostap way: */
4655 MAC_COPY(priv
->bssid
, priv
->dev_addr
);
4656 priv
->bssid
[0] |= 0x02; /* 'local assigned addr' bit */
4657 /* add IBSS bit to our caps... */
4658 acx_update_capabilities(priv
);
4659 acx_set_status(priv
, ACX_STATUS_4_ASSOCIATED
);
4660 /* In order to cmd_join be called below */
4663 /* we shall scan again, AP can be
4664 ** just temporarily powered off */
4666 "no matching station found in range yet\n");
4667 acx_set_status(priv
, ACX_STATUS_1_SCANNING
);
4672 acx_unlock(priv
, flags
);
4674 if (idx_found
!= -1) {
4675 if (ACX_MODE_0_ADHOC
== priv
->mode
) {
4676 /* need to update channel in beacon template */
4677 SET_BIT(priv
->set_mask
, SET_TEMPLATES
);
4678 if (ACX_STATE_IFACE_UP
& priv
->dev_state_mask
)
4679 acx_s_update_card_settings(priv
, 0, 0);
4681 /* Inform firmware on our decision to start or join BSS */
4682 acx_s_cmd_join_bssid(priv
, priv
->bssid
);
4691 /***********************************************************************
4694 ** Loads a firmware image
4697 ** 0 unable to load file
4698 ** pointer to firmware success
4700 #if USE_FW_LOADER_26
4702 acx_s_read_fw(struct device
*dev
, const char *file
, u32
*size
)
4704 #undef acx_s_read_fw
4706 acx_s_read_fw(const char *file
, u32
*size
)
4709 firmware_image_t
*res
;
4711 #if USE_FW_LOADER_LEGACY
4721 #if USE_FW_LOADER_26
4722 const struct firmware
*fw_entry
;
4725 acxlog(L_INIT
, "requesting firmware image '%s'\n", file
);
4726 if (!request_firmware(&fw_entry
, file
, dev
)) {
4728 if (fw_entry
->size
>= 8)
4729 *size
= 8 + le32_to_cpu(*(u32
*)(fw_entry
->data
+ 4));
4730 if (fw_entry
->size
!= *size
) {
4731 printk("acx: firmware size does not match "
4732 "firmware header: %d != %d, "
4733 "aborting fw upload\n",
4734 (int) fw_entry
->size
, (int) *size
);
4737 res
= vmalloc(*size
);
4739 printk("acx: no memory for firmware "
4740 "(%u bytes)\n", *size
);
4743 memcpy(res
, fw_entry
->data
, fw_entry
->size
);
4745 release_firmware(fw_entry
);
4748 printk("acx: firmware image '%s' was not provided. "
4749 "Check your hotplug scripts\n", file
);
4752 #if USE_FW_LOADER_LEGACY
4753 printk("acx: firmware upload via firmware_dir module parameter "
4754 "is deprecated. Switch to using hotplug\n");
4757 orgfs
= get_fs(); /* store original fs */
4760 /* Read in whole file then check the size */
4761 page
= __get_free_page(GFP_KERNEL
);
4762 if (unlikely(0 == page
)) {
4763 printk("acx: no memory for firmware upload\n");
4767 filename
= kmalloc(PATH_MAX
, GFP_KERNEL
);
4768 if (unlikely(!filename
)) {
4769 printk("acx: no memory for firmware upload\n");
4772 if (!firmware_dir
) {
4773 firmware_dir
= "/usr/share/acx";
4774 acxlog(L_DEBUG
, "no firmware directory specified "
4775 "via module parameter firmware_dir, "
4776 "using default %s\n", firmware_dir
);
4778 snprintf(filename
, PATH_MAX
, "%s/%s", firmware_dir
, file
);
4779 acxlog(L_INIT
, "reading firmware image '%s'\n", filename
);
4781 buffer
= (char*)page
;
4783 /* Note that file must be given as absolute path:
4784 * a relative path works on first loading,
4785 * but any subsequent firmware loading during card
4786 * eject/insert will fail, most likely since the first
4787 * module loading happens in user space (and thus
4788 * filp_open can figure out the absolute path from a
4789 * relative path) whereas the card reinsert processing
4790 * probably happens in kernel space where you don't have
4791 * a current directory to be able to figure out an
4792 * absolute path from a relative path... */
4793 inf
= filp_open(filename
, O_RDONLY
, 0);
4795 if (OK
!= IS_ERR(inf
)) {
4798 switch (-PTR_ERR(inf
)) {
4799 case 2: err
= "file not found";
4802 err
= "unknown error";
4805 printk("acx: error %ld trying to open file '%s': %s\n",
4806 -PTR_ERR(inf
), file
, err
);
4810 if (unlikely((NULL
== inf
->f_op
) || (NULL
== inf
->f_op
->read
))) {
4811 printk("acx: %s does not have a read method?!\n", file
);
4817 retval
= inf
->f_op
->read(inf
, buffer
, PAGE_SIZE
, &inf
->f_pos
);
4819 if (unlikely(0 > retval
)) {
4820 printk("acx: error %d reading file '%s'\n",
4824 } else if (0 == retval
) {
4826 printk("acx: firmware image file "
4827 "'%s' is empty?!\n", file
);
4829 } else if (0 < retval
) {
4830 /* allocate result buffer here if needed,
4831 * since we don't want to waste resources/time
4832 * (in case file opening/reading fails)
4833 * by doing allocation in front of the loop instead. */
4835 *size
= 8 + le32_to_cpu(*(u32
*)(4 + buffer
));
4837 res
= vmalloc(*size
);
4839 printk("acx: unable to "
4840 "allocate %u bytes for "
4841 "firmware module upload\n",
4845 acxlog(L_DEBUG
, "allocated %u bytes "
4846 "for firmware module loading\n",
4849 if ((unlikely(offset
+ retval
> *size
))) {
4850 printk("acx: ERROR: allocation "
4851 "was less than firmware image size?!\n");
4854 memcpy((u8
*)res
+ offset
, buffer
, retval
);
4857 } while (0 < retval
);
4860 retval
= filp_close(inf
, NULL
);
4862 if (unlikely(retval
)) {
4863 printk("acx: error %d closing file '%s'\n", -retval
, file
);
4866 if (unlikely((NULL
!= res
) && (offset
!= le32_to_cpu(res
->size
) + 8))) {
4867 printk("acx: firmware is reporting a different size "
4868 "(0x%08X; 0x%08X was read)\n",
4869 le32_to_cpu(res
->size
) + 8, offset
);
4880 /* checksum will be verified in write_fw, so don't bother here */
4885 #ifdef POWER_SAVE_80211
4886 /*----------------------------------------------------------------
4887 * acx_s_activate_power_save_mode
4888 *----------------------------------------------------------------*/
4890 acx_s_activate_power_save_mode(wlandevice_t
*priv
)
4892 acx100_ie_powermgmt_t pm
;
4896 acx_s_interrogate(priv
, &pm
, ACX1xx_IE_POWER_MGMT
);
4897 if (pm
.wakeup_cfg
!= 0x81)
4902 pm
.hangover_period
= 0;
4903 acx_s_configure(priv
, &pm
, ACX1xx_IE_POWER_MGMT
);
4910 /***********************************************************************
4914 acx100_s_set_wepkey(wlandevice_t
*priv
)
4916 ie_dot11WEPDefaultKey_t dk
;
4919 for (i
= 0; i
< DOT11_MAX_DEFAULT_WEP_KEYS
; i
++) {
4920 if (priv
->wep_keys
[i
].size
!= 0) {
4921 acxlog(L_INIT
, "setting WEP key: %d with "
4922 "total size: %d\n", i
, (int) priv
->wep_keys
[i
].size
);
4924 dk
.keySize
= priv
->wep_keys
[i
].size
;
4925 dk
.defaultKeyNum
= i
;
4926 memcpy(dk
.key
, priv
->wep_keys
[i
].key
, dk
.keySize
);
4927 acx_s_configure(priv
, &dk
, ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE
);
4933 acx111_s_set_wepkey(wlandevice_t
*priv
)
4935 acx111WEPDefaultKey_t dk
;
4938 for (i
= 0; i
< DOT11_MAX_DEFAULT_WEP_KEYS
; i
++) {
4939 if (priv
->wep_keys
[i
].size
!= 0) {
4940 acxlog(L_INIT
, "setting WEP key: %d with "
4941 "total size: %d\n", i
, (int) priv
->wep_keys
[i
].size
);
4942 memset(&dk
, 0, sizeof(dk
));
4943 dk
.action
= cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
4944 dk
.keySize
= priv
->wep_keys
[i
].size
;
4946 /* are these two lines necessary? */
4947 dk
.type
= 0; /* default WEP key */
4948 dk
.index
= 0; /* ignored when setting default key */
4950 dk
.defaultKeyNum
= i
;
4951 memcpy(dk
.key
, priv
->wep_keys
[i
].key
, dk
.keySize
);
4952 acx_s_issue_cmd(priv
, ACX1xx_CMD_WEP_MGMT
, &dk
, sizeof(dk
));
4958 acx_s_set_wepkey(wlandevice_t
*priv
)
4960 if (IS_ACX111(priv
))
4961 acx111_s_set_wepkey(priv
);
4963 acx100_s_set_wepkey(priv
);
4967 /***********************************************************************
4968 ** acx100_s_init_wep
4970 ** FIXME: this should probably be moved into the new card settings
4971 ** management, but since we're also modifying the memory map layout here
4972 ** due to the WEP key space we want, we should take care...
4975 acx100_s_init_wep(wlandevice_t
*priv
)
4978 acx100_cmd_wep_mgmt_t wep_mgmt; size = 37 bytes */
4979 acx100_ie_wep_options_t options
;
4980 ie_dot11WEPDefaultKeyID_t dk
;
4986 if (OK
!= acx_s_interrogate(priv
, &pt
, ACX1xx_IE_MEMORY_MAP
)) {
4990 acxlog(L_DEBUG
, "CodeEnd:%X\n", pt
.CodeEnd
);
4992 pt
.WEPCacheStart
= cpu_to_le32(le32_to_cpu(pt
.CodeEnd
) + 0x4);
4993 pt
.WEPCacheEnd
= cpu_to_le32(le32_to_cpu(pt
.CodeEnd
) + 0x4);
4995 if (OK
!= acx_s_configure(priv
, &pt
, ACX1xx_IE_MEMORY_MAP
)) {
4999 /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
5000 options
.NumKeys
= cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS
+ 10);
5001 options
.WEPOption
= 0x00;
5003 acxlog(L_ASSOC
, "%s: writing WEP options\n", __func__
);
5004 acx_s_configure(priv
, &options
, ACX100_IE_WEP_OPTIONS
);
5006 acx100_s_set_wepkey(priv
);
5008 if (priv
->wep_keys
[priv
->wep_current_index
].size
!= 0) {
5009 acxlog(L_ASSOC
, "setting active default WEP key number: %d\n",
5010 priv
->wep_current_index
);
5011 dk
.KeyID
= priv
->wep_current_index
;
5012 acx_s_configure(priv
, &dk
, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET
); /* 0x1010 */
5014 /* FIXME!!! wep_key_struct is filled nowhere! But priv
5015 * is initialized to 0, and we don't REALLY need those keys either */
5016 /* for (i = 0; i < 10; i++) {
5017 if (priv->wep_key_struct[i].len != 0) {
5018 MAC_COPY(wep_mgmt.MacAddr, priv->wep_key_struct[i].addr);
5019 wep_mgmt.KeySize = cpu_to_le16(priv->wep_key_struct[i].len);
5020 memcpy(&wep_mgmt.Key, priv->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
5021 wep_mgmt.Action = cpu_to_le16(1);
5022 acxlog(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
5023 if (OK == acx_s_issue_cmd(priv, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
5024 priv->wep_key_struct[i].index = i;
5029 /* now retrieve the updated WEPCacheEnd pointer... */
5030 if (OK
!= acx_s_interrogate(priv
, &pt
, ACX1xx_IE_MEMORY_MAP
)) {
5031 printk("%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
5032 priv
->netdev
->name
);
5035 /* ...and tell it to start allocating templates at that location */
5036 /* (no endianness conversion needed) */
5037 pt
.PacketTemplateStart
= pt
.WEPCacheEnd
;
5039 if (OK
!= acx_s_configure(priv
, &pt
, ACX1xx_IE_MEMORY_MAP
)) {
5040 printk("%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
5041 priv
->netdev
->name
);
5052 /***********************************************************************
5055 acx_s_init_max_null_data_template(wlandevice_t
*priv
)
5057 struct acx_template_nullframe b
;
5061 memset(&b
, 0, sizeof(b
));
5062 b
.size
= cpu_to_le16(sizeof(b
) - 2);
5063 result
= acx_s_issue_cmd(priv
, ACX1xx_CMD_CONFIG_NULL_DATA
, &b
, sizeof(b
));
5069 /***********************************************************************
5070 ** acx_s_init_max_beacon_template
5073 acx_s_init_max_beacon_template(wlandevice_t
*priv
)
5075 struct acx_template_beacon b
;
5079 memset(&b
, 0, sizeof(b
));
5080 b
.size
= cpu_to_le16(sizeof(b
) - 2);
5081 result
= acx_s_issue_cmd(priv
, ACX1xx_CMD_CONFIG_BEACON
, &b
, sizeof(b
));
5087 /***********************************************************************
5088 ** acx_s_init_max_tim_template
5091 acx_s_init_max_tim_template(wlandevice_t
*priv
)
5093 acx_template_tim_t t
;
5095 memset(&t
, 0, sizeof(t
));
5096 t
.size
= cpu_to_le16(sizeof(t
) - 2);
5097 return acx_s_issue_cmd(priv
, ACX1xx_CMD_CONFIG_TIM
, &t
, sizeof(t
));
5101 /***********************************************************************
5102 ** acx_s_init_max_probe_response_template
5105 acx_s_init_max_probe_response_template(wlandevice_t
*priv
)
5107 struct acx_template_proberesp pr
;
5109 memset(&pr
, 0, sizeof(pr
));
5110 pr
.size
= cpu_to_le16(sizeof(pr
) - 2);
5112 return acx_s_issue_cmd(priv
, ACX1xx_CMD_CONFIG_PROBE_RESPONSE
, &pr
, sizeof(pr
));
5116 /***********************************************************************
5117 ** acx_s_init_max_probe_request_template
5120 acx_s_init_max_probe_request_template(wlandevice_t
*priv
)
5123 acx100_template_probereq_t p100
;
5124 acx111_template_probereq_t p111
;
5129 memset(&pr
, 0, sizeof(pr
));
5130 pr
.p100
.size
= cpu_to_le16(sizeof(pr
) - 2);
5131 res
= acx_s_issue_cmd(priv
, ACX1xx_CMD_CONFIG_PROBE_REQUEST
, &pr
, sizeof(pr
));
5137 /***********************************************************************
5138 ** acx_s_set_tim_template
5140 ** In full blown driver we will regularly update partial virtual bitmap
5141 ** by calling this function
5142 ** (it can be done by irq handler on each DTIM irq or by timer...)
5144 [802.11 7.3.2.6] TIM information element:
5148 indicates how many beacons (including this) appear before next DTIM
5149 (0=this one is a DTIM)
5151 number of beacons between successive DTIMs
5152 (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
5154 bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
5155 set to 1 in TIM elements with a value of 0 in the DTIM Count field
5156 when one or more broadcast or multicast frames are buffered at the AP.
5157 bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
5158 4 n Partial Virtual Bitmap
5159 Visible part of traffic-indication bitmap.
5160 Full bitmap consists of 2008 bits (251 octets) such that bit number N
5161 (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
5162 in octet number N/8 where the low-order bit of each octet is bit0,
5163 and the high order bit is bit7.
5164 Each set bit in virtual bitmap corresponds to traffic buffered by AP
5165 for a specific station (with corresponding AID?).
5166 Partial Virtual Bitmap shows a part of bitmap which has non-zero.
5167 Bitmap Offset is a number of skipped zero octets (see above).
5168 'Missing' octets at the tail are also assumed to be zero.
5169 Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
5170 This means that traffic-indication bitmap is:
5171 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
5172 (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
5175 acx_s_set_tim_template(wlandevice_t
*priv
)
5177 /* For now, configure smallish test bitmap, all zero ("no pending data") */
5178 enum { bitmap_size
= 5 };
5180 acx_template_tim_t t
;
5185 memset(&t
, 0, sizeof(t
));
5186 t
.size
= 5 + bitmap_size
; /* eid+len+count+period+bmap_ctrl + bmap */
5187 t
.tim_eid
= WLAN_EID_TIM
;
5188 t
.len
= 3 + bitmap_size
; /* count+period+bmap_ctrl + bmap */
5189 result
= acx_s_issue_cmd(priv
, ACX1xx_CMD_CONFIG_TIM
, &t
, sizeof(t
));
5195 /***********************************************************************
5196 ** acx_fill_beacon_or_proberesp_template
5198 ** For frame format info, please see 802.11-1999.pdf item 7.2.3.9 and below!!
5200 ** NB: we use the fact that
5201 ** struct acx_template_proberesp and struct acx_template_beacon are the same
5202 ** (well, almost...)
5204 ** [802.11] Beacon's body consist of these IEs:
5206 ** 2 Beacon interval
5207 ** 3 Capability information
5209 ** 5 Supported rates (up to 8 rates)
5210 ** 6 FH Parameter Set (frequency-hopping PHYs only)
5211 ** 7 DS Parameter Set (direct sequence PHYs only)
5212 ** 8 CF Parameter Set (only if PCF is supported)
5213 ** 9 IBSS Parameter Set (ad-hoc only)
5216 ** 10 TIM (AP only) (see 802.11 7.3.2.6)
5217 ** 11 Country Information (802.11d)
5218 ** 12 FH Parameters (802.11d)
5219 ** 13 FH Pattern Table (802.11d)
5220 ** ... (?!! did not yet find relevant PDF file... --vda)
5221 ** 19 ERP Information (extended rate PHYs)
5222 ** 20 Extended Supported Rates (if more than 8 rates)
5225 ** 10 Country information (802.11d)
5226 ** 11 FH Parameters (802.11d)
5227 ** 12 FH Pattern Table (802.11d)
5228 ** 13-n Requested information elements (802.11d)
5230 ** 18 ERP Information (extended rate PHYs)
5231 ** 19 Extended Supported Rates (if more than 8 rates)
5234 acx_fill_beacon_or_proberesp_template(wlandevice_t
*priv
,
5235 struct acx_template_beacon
*templ
,
5236 u16 fc
/* in host order! */)
5243 memset(templ
, 0, sizeof(*templ
));
5244 MAC_BCAST(templ
->da
);
5245 MAC_COPY(templ
->sa
, priv
->dev_addr
);
5246 MAC_COPY(templ
->bssid
, priv
->bssid
);
5248 templ
->beacon_interval
= cpu_to_le16(priv
->beacon_interval
);
5249 acx_update_capabilities(priv
);
5250 templ
->cap
= cpu_to_le16(priv
->capabilities
);
5252 p
= templ
->variable
;
5253 p
= wlan_fill_ie_ssid(p
, priv
->essid_len
, priv
->essid
);
5254 p
= wlan_fill_ie_rates(p
, priv
->rate_supported_len
, priv
->rate_supported
);
5255 p
= wlan_fill_ie_ds_parms(p
, priv
->channel
);
5256 /* NB: should go AFTER tim, but acx seem to keep tim last always */
5257 p
= wlan_fill_ie_rates_ext(p
, priv
->rate_supported_len
, priv
->rate_supported
);
5259 switch (priv
->mode
) {
5260 case ACX_MODE_0_ADHOC
:
5262 p
= wlan_fill_ie_ibss_parms(p
, 0); break;
5264 /* TIM IE is set up as separate template */
5268 len
= p
- (u8
*)templ
;
5269 templ
->fc
= cpu_to_le16(WF_FTYPE_MGMT
| fc
);
5270 /* - 2: do not count 'u16 size' field */
5271 templ
->size
= cpu_to_le16(len
- 2);
5278 /***********************************************************************
5279 ** acx_s_set_beacon_template
5282 acx_s_set_beacon_template(wlandevice_t
*priv
)
5284 struct acx_template_beacon bcn
;
5289 len
= acx_fill_beacon_or_proberesp_template(priv
, &bcn
, WF_FSTYPE_BEACON
);
5290 result
= acx_s_issue_cmd(priv
, ACX1xx_CMD_CONFIG_BEACON
, &bcn
, len
);
5297 /***********************************************************************
5298 ** acx_s_set_probe_response_template
5301 acx_s_set_probe_response_template(wlandevice_t
*priv
)
5303 struct acx_template_proberesp pr
;
5308 len
= acx_fill_beacon_or_proberesp_template(priv
, &pr
, WF_FSTYPE_PROBERESP
);
5309 result
= acx_s_issue_cmd(priv
, ACX1xx_CMD_CONFIG_PROBE_RESPONSE
, &pr
, len
);
5316 /***********************************************************************
5317 ** acx100_s_init_packet_templates()
5319 ** NOTE: order is very important here, to have a correct memory layout!
5320 ** init templates: max Probe Request (station mode), max NULL data,
5321 ** max Beacon, max TIM, max Probe Response.
5324 acx100_s_init_packet_templates(wlandevice_t
*priv
)
5327 int result
= NOT_OK
;
5331 acxlog(L_DEBUG
, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm
));
5333 /* acx100 still do not emit probe requests, thus this call
5334 ** is sourt of not needed. But we want it to work someday */
5335 if (OK
!= acx_s_init_max_probe_request_template(priv
))
5338 #ifdef NOT_WORKING_YET
5339 /* FIXME: creating the NULL data template breaks
5340 * communication right now, needs further testing.
5341 * Also, need to set the template once we're joining a network. */
5342 if (OK
!= acx_s_init_max_null_data_template(priv
))
5346 if (OK
!= acx_s_init_max_beacon_template(priv
))
5349 if (OK
!= acx_s_init_max_tim_template(priv
))
5352 if (OK
!= acx_s_init_max_probe_response_template(priv
))
5355 if (OK
!= acx_s_set_tim_template(priv
))
5358 if (OK
!= acx_s_interrogate(priv
, &mm
, ACX1xx_IE_MEMORY_MAP
)) {
5362 mm
.QueueStart
= cpu_to_le32(le32_to_cpu(mm
.PacketTemplateEnd
) + 4);
5363 if (OK
!= acx_s_configure(priv
, &mm
, ACX1xx_IE_MEMORY_MAP
)) {
5371 acxlog(L_DEBUG
|L_INIT
,
5376 ".WEPCacheStart=0x%X\n"
5377 ".WEPCacheEnd=0x%X\n"
5378 ".PacketTemplateStart=0x%X\n"
5379 ".PacketTemplateEnd=0x%X\n",
5381 le32_to_cpu(mm
.CodeStart
),
5382 le32_to_cpu(mm
.CodeEnd
),
5383 le32_to_cpu(mm
.WEPCacheStart
),
5384 le32_to_cpu(mm
.WEPCacheEnd
),
5385 le32_to_cpu(mm
.PacketTemplateStart
),
5386 le32_to_cpu(mm
.PacketTemplateEnd
));
5394 acx111_s_init_packet_templates(wlandevice_t
*priv
)
5396 int result
= NOT_OK
;
5400 acxlog(L_DEBUG
|L_INIT
, "initializing max packet templates\n");
5402 if (OK
!= acx_s_init_max_probe_request_template(priv
))
5405 if (OK
!= acx_s_init_max_null_data_template(priv
))
5408 if (OK
!= acx_s_init_max_beacon_template(priv
))
5411 if (OK
!= acx_s_init_max_tim_template(priv
))
5414 if (OK
!= acx_s_init_max_probe_response_template(priv
))
5417 /* the other templates will be set later (acx_start) */
5419 if (OK != acx_s_set_tim_template(priv))
5426 printk("%s: acx111_init_packet_templates() FAILED\n", priv
->netdev
->name
);
5434 /***********************************************************************
5437 acx100_s_set_probe_request_template(wlandevice_t
*priv
)
5439 struct acx100_template_probereq probereq
;
5446 memset(&probereq
, 0, sizeof(probereq
));
5448 probereq
.fc
= WF_FTYPE_MGMTi
| WF_FSTYPE_PROBEREQi
;
5449 MAC_BCAST(probereq
.da
);
5450 MAC_COPY(probereq
.sa
, priv
->dev_addr
);
5451 MAC_BCAST(probereq
.bssid
);
5453 probereq
.beacon_interval
= cpu_to_le16(priv
->beacon_interval
);
5454 acx_update_capabilities(priv
);
5455 probereq
.cap
= cpu_to_le16(priv
->capabilities
);
5457 p
= probereq
.variable
;
5458 acxlog(L_ASSOC
, "SSID='%s' len=%d\n", priv
->essid
, priv
->essid_len
);
5459 p
= wlan_fill_ie_ssid(p
, priv
->essid_len
, priv
->essid
);
5460 p
= wlan_fill_ie_rates(p
, priv
->rate_supported_len
, priv
->rate_supported
);
5461 /* FIXME: should these be here or AFTER ds_parms? */
5462 p
= wlan_fill_ie_rates_ext(p
, priv
->rate_supported_len
, priv
->rate_supported
);
5463 /* HUH?? who said it must be here? I've found nothing in 802.11! --vda*/
5464 /* p = wlan_fill_ie_ds_parms(p, priv->channel); */
5465 frame_len
= p
- (char*)&probereq
;
5466 probereq
.size
= frame_len
- 2;
5468 res
= acx_s_issue_cmd(priv
, ACX1xx_CMD_CONFIG_PROBE_REQUEST
, &probereq
, frame_len
);
5474 acx111_s_set_probe_request_template(wlandevice_t
*priv
)
5476 struct acx111_template_probereq probereq
;
5483 memset(&probereq
, 0, sizeof(probereq
));
5485 probereq
.fc
= WF_FTYPE_MGMTi
| WF_FSTYPE_PROBEREQi
;
5486 MAC_BCAST(probereq
.da
);
5487 MAC_COPY(probereq
.sa
, priv
->dev_addr
);
5488 MAC_BCAST(probereq
.bssid
);
5490 p
= probereq
.variable
;
5491 p
= wlan_fill_ie_ssid(p
, priv
->essid_len
, priv
->essid
);
5492 p
= wlan_fill_ie_rates(p
, priv
->rate_supported_len
, priv
->rate_supported
);
5493 p
= wlan_fill_ie_rates_ext(p
, priv
->rate_supported_len
, priv
->rate_supported
);
5494 frame_len
= p
- (char*)&probereq
;
5495 probereq
.size
= frame_len
- 2;
5497 res
= acx_s_issue_cmd(priv
, ACX1xx_CMD_CONFIG_PROBE_REQUEST
, &probereq
, frame_len
);
5503 acx_s_set_probe_request_template(wlandevice_t
*priv
)
5505 if (IS_ACX111(priv
)) {
5506 return acx111_s_set_probe_request_template(priv
);
5508 return acx100_s_set_probe_request_template(priv
);
5513 /***********************************************************************
5514 ** acx_s_update_card_settings
5516 ** Applies accumulated changes in various priv->xxxx members
5517 ** Called by ioctl commit handler, acx_start, acx_set_defaults,
5518 ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
5521 acx111_s_sens_radio_16_17(wlandevice_t
*priv
)
5523 u32 feature1
, feature2
;
5525 if ((priv
->sensitivity
< 1) || (priv
->sensitivity
> 3)) {
5526 printk("%s: invalid sensitivity setting (1..3), "
5527 "setting to 1\n", priv
->netdev
->name
);
5528 priv
->sensitivity
= 1;
5530 acx111_s_get_feature_config(priv
, &feature1
, &feature2
);
5531 CLEAR_BIT(feature1
, FEATURE1_LOW_RX
|FEATURE1_EXTRA_LOW_RX
);
5532 if (priv
->sensitivity
> 1)
5533 SET_BIT(feature1
, FEATURE1_LOW_RX
);
5534 if (priv
->sensitivity
> 2)
5535 SET_BIT(feature1
, FEATURE1_EXTRA_LOW_RX
);
5536 acx111_s_feature_set(priv
, feature1
, feature2
);
5540 acx_s_update_card_settings(wlandevice_t
*priv
, int get_all
, int set_all
)
5542 unsigned long flags
;
5543 unsigned int start_scan
= 0;
5549 SET_BIT(priv
->get_mask
, GETSET_ALL
);
5551 SET_BIT(priv
->set_mask
, GETSET_ALL
);
5552 /* Why not just set masks to 0xffffffff? We can get rid of GETSET_ALL */
5554 acxlog(L_INIT
, "get_mask 0x%08X, set_mask 0x%08X\n",
5555 priv
->get_mask
, priv
->set_mask
);
5557 /* Track dependencies betweed various settings */
5559 if (priv
->set_mask
& (GETSET_MODE
|GETSET_RESCAN
|GETSET_WEP
)) {
5560 acxlog(L_INIT
, "important setting has been changed. "
5561 "Need to update packet templates, too\n");
5562 SET_BIT(priv
->set_mask
, SET_TEMPLATES
);
5564 if (priv
->set_mask
& (GETSET_CHANNEL
|GETSET_ALL
)) {
5565 /* This will actually tune RX/TX to the channel */
5566 SET_BIT(priv
->set_mask
, GETSET_RX
|GETSET_TX
);
5567 switch (priv
->mode
) {
5568 case ACX_MODE_0_ADHOC
:
5570 /* Beacons contain channel# - update them */
5571 SET_BIT(priv
->set_mask
, SET_TEMPLATES
);
5573 switch (priv
->mode
) {
5574 case ACX_MODE_0_ADHOC
:
5575 case ACX_MODE_2_STA
:
5580 /* Apply settings */
5582 #ifdef WHY_SHOULD_WE_BOTHER /* imagine we were just powered off */
5583 /* send a disassoc request in case it's required */
5584 if (priv
->set_mask
& (GETSET_MODE
|GETSET_RESCAN
|GETSET_CHANNEL
|GETSET_WEP
|GETSET_ALL
)) {
5585 if (ACX_MODE_2_STA
== priv
->mode
) {
5586 if (ACX_STATUS_4_ASSOCIATED
== priv
->status
) {
5587 acxlog(L_ASSOC
, "we were ASSOCIATED - "
5588 "sending disassoc request\n");
5589 acx_lock(priv
, flags
);
5590 acx_l_transmit_disassoc(priv
, NULL
);
5591 /* FIXME: deauth? */
5592 acx_unlock(priv
, flags
);
5594 /* need to reset some other stuff as well */
5595 acxlog(L_DEBUG
, "resetting bssid\n");
5596 MAC_ZERO(priv
->bssid
);
5597 SET_BIT(priv
->set_mask
, SET_TEMPLATES
|SET_STA_LIST
);
5598 /* FIXME: should start scanning */
5604 if (priv
->get_mask
& (GETSET_STATION_ID
|GETSET_ALL
)) {
5605 u8 stationID
[4 + ACX1xx_IE_DOT11_STATION_ID_LEN
];
5608 acx_s_interrogate(priv
, &stationID
, ACX1xx_IE_DOT11_STATION_ID
);
5609 paddr
= &stationID
[4];
5610 for (i
= 0; i
< ETH_ALEN
; i
++) {
5611 /* we copy the MAC address (reversed in
5612 * the card) to the netdevice's MAC
5613 * address, and on ifup it will be
5614 * copied into iwpriv->dev_addr */
5615 priv
->netdev
->dev_addr
[ETH_ALEN
- 1 - i
] = paddr
[i
];
5617 CLEAR_BIT(priv
->get_mask
, GETSET_STATION_ID
);
5620 if (priv
->get_mask
& (GETSET_SENSITIVITY
|GETSET_ALL
)) {
5621 if ((RADIO_RFMD_11
== priv
->radio_type
)
5622 || (RADIO_MAXIM_0D
== priv
->radio_type
)
5623 || (RADIO_RALINK_15
== priv
->radio_type
)) {
5624 acx_s_read_phy_reg(priv
, 0x30, &priv
->sensitivity
);
5626 acxlog(L_INIT
, "don't know how to get sensitivity "
5627 "for radio type 0x%02X\n", priv
->radio_type
);
5628 priv
->sensitivity
= 0;
5630 acxlog(L_INIT
, "got sensitivity value %u\n", priv
->sensitivity
);
5632 CLEAR_BIT(priv
->get_mask
, GETSET_SENSITIVITY
);
5635 if (priv
->get_mask
& (GETSET_ANTENNA
|GETSET_ALL
)) {
5636 u8 antenna
[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN
];
5638 memset(antenna
, 0, sizeof(antenna
));
5639 acx_s_interrogate(priv
, antenna
, ACX1xx_IE_DOT11_CURRENT_ANTENNA
);
5640 priv
->antenna
= antenna
[4];
5641 acxlog(L_INIT
, "got antenna value 0x%02X\n", priv
->antenna
);
5642 CLEAR_BIT(priv
->get_mask
, GETSET_ANTENNA
);
5645 if (priv
->get_mask
& (GETSET_ED_THRESH
|GETSET_ALL
)) {
5646 if (IS_ACX100(priv
)) {
5647 u8 ed_threshold
[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN
];
5649 memset(ed_threshold
, 0, sizeof(ed_threshold
));
5650 acx_s_interrogate(priv
, ed_threshold
, ACX100_IE_DOT11_ED_THRESHOLD
);
5651 priv
->ed_threshold
= ed_threshold
[4];
5653 acxlog(L_INIT
, "acx111 doesn't support ED\n");
5654 priv
->ed_threshold
= 0;
5656 acxlog(L_INIT
, "got Energy Detect (ED) threshold %u\n", priv
->ed_threshold
);
5657 CLEAR_BIT(priv
->get_mask
, GETSET_ED_THRESH
);
5660 if (priv
->get_mask
& (GETSET_CCA
|GETSET_ALL
)) {
5661 if (IS_ACX100(priv
)) {
5662 u8 cca
[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN
];
5664 memset(cca
, 0, sizeof(priv
->cca
));
5665 acx_s_interrogate(priv
, cca
, ACX1xx_IE_DOT11_CURRENT_CCA_MODE
);
5668 acxlog(L_INIT
, "acx111 doesn't support CCA\n");
5671 acxlog(L_INIT
, "got Channel Clear Assessment (CCA) value %u\n", priv
->cca
);
5672 CLEAR_BIT(priv
->get_mask
, GETSET_CCA
);
5675 if (priv
->get_mask
& (GETSET_REG_DOMAIN
|GETSET_ALL
)) {
5676 acx_ie_generic_t dom
;
5678 acx_s_interrogate(priv
, &dom
, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN
);
5679 priv
->reg_dom_id
= dom
.m
.bytes
[0];
5680 /* FIXME: should also set chanmask somehow */
5681 acxlog(L_INIT
, "got regulatory domain 0x%02X\n", priv
->reg_dom_id
);
5682 CLEAR_BIT(priv
->get_mask
, GETSET_REG_DOMAIN
);
5685 if (priv
->set_mask
& (GETSET_STATION_ID
|GETSET_ALL
)) {
5686 u8 stationID
[4 + ACX1xx_IE_DOT11_STATION_ID_LEN
];
5689 paddr
= &stationID
[4];
5690 for (i
= 0; i
< ETH_ALEN
; i
++) {
5691 /* copy the MAC address we obtained when we noticed
5692 * that the ethernet iface's MAC changed
5693 * to the card (reversed in
5695 paddr
[i
] = priv
->dev_addr
[ETH_ALEN
- 1 - i
];
5697 acx_s_configure(priv
, &stationID
, ACX1xx_IE_DOT11_STATION_ID
);
5698 CLEAR_BIT(priv
->set_mask
, GETSET_STATION_ID
);
5701 if (priv
->set_mask
& (SET_TEMPLATES
|GETSET_ALL
)) {
5702 acxlog(L_INIT
, "updating packet templates\n");
5703 /* Doesn't work for acx100, do it only for acx111 for now */
5704 if (IS_ACX111(priv
)) {
5705 switch (priv
->mode
) {
5706 case ACX_MODE_0_ADHOC
:
5707 case ACX_MODE_2_STA
:
5708 acx_s_set_probe_request_template(priv
);
5711 switch (priv
->mode
) {
5712 case ACX_MODE_0_ADHOC
:
5714 /* FIXME: why only for AP? STA need probe req templates... */
5715 acx_s_set_beacon_template(priv
);
5716 acx_s_set_tim_template(priv
);
5717 /* BTW acx111 firmware would not send probe responses
5718 ** if probe request does not have all basic rates flagged
5719 ** by 0x80! Thus firmware does not conform to 802.11,
5720 ** it should ignore 0x80 bit in ratevector from STA.
5721 ** We can 'fix' it by not using this template and
5722 ** sending probe responses by hand. TODO --vda */
5723 acx_s_set_probe_response_template(priv
);
5725 /* Needed if generated frames are to be emitted at different tx rate now */
5726 acxlog(L_IRQ
, "redoing cmd_join_bssid() after template cfg\n");
5727 acx_s_cmd_join_bssid(priv
, priv
->bssid
);
5728 CLEAR_BIT(priv
->set_mask
, SET_TEMPLATES
);
5730 if (priv
->set_mask
& (SET_STA_LIST
|GETSET_ALL
)) {
5731 acx_lock(priv
, flags
);
5732 acx_l_sta_list_init(priv
);
5733 CLEAR_BIT(priv
->set_mask
, SET_STA_LIST
);
5734 acx_unlock(priv
, flags
);
5736 if (priv
->set_mask
& (SET_RATE_FALLBACK
|GETSET_ALL
)) {
5737 u8 rate
[4 + ACX1xx_IE_RATE_FALLBACK_LEN
];
5739 /* configure to not do fallbacks when not in auto rate mode */
5740 rate
[4] = (priv
->rate_auto
) ? /* priv->txrate_fallback_retries */ 1 : 0;
5741 acxlog(L_INIT
, "updating Tx fallback to %u retries\n", rate
[4]);
5742 acx_s_configure(priv
, &rate
, ACX1xx_IE_RATE_FALLBACK
);
5743 CLEAR_BIT(priv
->set_mask
, SET_RATE_FALLBACK
);
5745 if (priv
->set_mask
& (GETSET_TXPOWER
|GETSET_ALL
)) {
5746 acxlog(L_INIT
, "updating transmit power: %u dBm\n",
5747 priv
->tx_level_dbm
);
5748 acx_s_set_tx_level(priv
, priv
->tx_level_dbm
);
5749 CLEAR_BIT(priv
->set_mask
, GETSET_TXPOWER
);
5752 if (priv
->set_mask
& (GETSET_SENSITIVITY
|GETSET_ALL
)) {
5753 acxlog(L_INIT
, "updating sensitivity value: %u\n",
5755 switch (priv
->radio_type
) {
5757 case RADIO_MAXIM_0D
:
5758 case RADIO_RALINK_15
:
5759 acx_s_write_phy_reg(priv
, 0x30, priv
->sensitivity
);
5761 case RADIO_RADIA_16
:
5762 case RADIO_UNKNOWN_17
:
5763 acx111_s_sens_radio_16_17(priv
);
5766 acxlog(L_INIT
, "don't know how to modify sensitivity "
5767 "for radio type 0x%02X\n", priv
->radio_type
);
5769 CLEAR_BIT(priv
->set_mask
, GETSET_SENSITIVITY
);
5772 if (priv
->set_mask
& (GETSET_ANTENNA
|GETSET_ALL
)) {
5774 u8 antenna
[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN
];
5776 memset(antenna
, 0, sizeof(antenna
));
5777 antenna
[4] = priv
->antenna
;
5778 acxlog(L_INIT
, "updating antenna value: 0x%02X\n",
5780 acx_s_configure(priv
, &antenna
, ACX1xx_IE_DOT11_CURRENT_ANTENNA
);
5781 CLEAR_BIT(priv
->set_mask
, GETSET_ANTENNA
);
5784 if (priv
->set_mask
& (GETSET_ED_THRESH
|GETSET_ALL
)) {
5786 acxlog(L_INIT
, "updating Energy Detect (ED) threshold: %u\n",
5787 priv
->ed_threshold
);
5788 if (IS_ACX100(priv
)) {
5789 u8 ed_threshold
[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN
];
5791 memset(ed_threshold
, 0, sizeof(ed_threshold
));
5792 ed_threshold
[4] = priv
->ed_threshold
;
5793 acx_s_configure(priv
, &ed_threshold
, ACX100_IE_DOT11_ED_THRESHOLD
);
5796 acxlog(L_INIT
, "acx111 doesn't support ED!\n");
5797 CLEAR_BIT(priv
->set_mask
, GETSET_ED_THRESH
);
5800 if (priv
->set_mask
& (GETSET_CCA
|GETSET_ALL
)) {
5802 acxlog(L_INIT
, "updating Channel Clear Assessment "
5803 "(CCA) value: 0x%02X\n", priv
->cca
);
5804 if (IS_ACX100(priv
)) {
5805 u8 cca
[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN
];
5807 memset(cca
, 0, sizeof(cca
));
5809 acx_s_configure(priv
, &cca
, ACX1xx_IE_DOT11_CURRENT_CCA_MODE
);
5812 acxlog(L_INIT
, "acx111 doesn't support CCA!\n");
5813 CLEAR_BIT(priv
->set_mask
, GETSET_CCA
);
5816 if (priv
->set_mask
& (GETSET_LED_POWER
|GETSET_ALL
)) {
5818 acxlog(L_INIT
, "updating power LED status: %u\n", priv
->led_power
);
5820 acx_lock(priv
, flags
);
5822 acxpci_l_power_led(priv
, priv
->led_power
);
5823 CLEAR_BIT(priv
->set_mask
, GETSET_LED_POWER
);
5824 acx_unlock(priv
, flags
);
5827 /* this seems to cause Tx lockup after some random time (Tx error 0x20),
5828 * so let's disable it for now until further investigation */
5829 /* Maybe fixed now after locking is fixed. Need to retest */
5830 #ifdef POWER_SAVE_80211
5831 if (priv
->set_mask
& (GETSET_POWER_80211
|GETSET_ALL
)) {
5832 acx100_ie_powermgmt_t pm
;
5834 /* change 802.11 power save mode settings */
5835 acxlog(L_INIT
, "updating 802.11 power save mode settings: "
5836 "wakeup_cfg 0x%02X, listen interval %u, "
5837 "options 0x%02X, hangover period %u, "
5838 "enhanced_ps_transition_time %d\n",
5839 priv
->ps_wakeup_cfg
, priv
->ps_listen_interval
,
5840 priv
->ps_options
, priv
->ps_hangover_period
,
5841 priv
->ps_enhanced_transition_time
);
5842 acx_s_interrogate(priv
, &pm
, ACX100_IE_POWER_MGMT
);
5843 acxlog(L_INIT
, "Previous PS mode settings: wakeup_cfg 0x%02X, "
5844 "listen interval %u, options 0x%02X, "
5845 "hangover period %u, "
5846 "enhanced_ps_transition_time %d\n",
5847 pm
.wakeup_cfg
, pm
.listen_interval
, pm
.options
,
5848 pm
.hangover_period
, pm
.enhanced_ps_transition_time
);
5849 pm
.wakeup_cfg
= priv
->ps_wakeup_cfg
;
5850 pm
.listen_interval
= priv
->ps_listen_interval
;
5851 pm
.options
= priv
->ps_options
;
5852 pm
.hangover_period
= priv
->ps_hangover_period
;
5853 pm
.enhanced_ps_transition_time
= cpu_to_le16(priv
->ps_enhanced_transition_time
);
5854 acx_s_configure(priv
, &pm
, ACX100_IE_POWER_MGMT
);
5855 acx_s_interrogate(priv
, &pm
, ACX100_IE_POWER_MGMT
);
5856 acxlog(L_INIT
, "wakeup_cfg: 0x%02X\n", pm
.wakeup_cfg
);
5858 acx_s_interrogate(priv
, &pm
, ACX100_IE_POWER_MGMT
);
5859 acxlog(L_INIT
, "power save mode change %s\n",
5860 (pm
.wakeup_cfg
& PS_CFG_PENDING
) ? "FAILED" : "was successful");
5861 /* FIXME: maybe verify via PS_CFG_PENDING bit here
5862 * that power save mode change was successful. */
5863 /* FIXME: we shouldn't trigger a scan immediately after
5864 * fiddling with power save mode (since the firmware is sending
5865 * a NULL frame then). Does this need locking?? */
5866 CLEAR_BIT(priv
->set_mask
, GETSET_POWER_80211
);
5870 if (priv
->set_mask
& (GETSET_CHANNEL
|GETSET_ALL
)) {
5872 acxlog(L_INIT
, "updating channel to: %u\n", priv
->channel
);
5873 CLEAR_BIT(priv
->set_mask
, GETSET_CHANNEL
);
5876 if (priv
->set_mask
& (GETSET_TX
|GETSET_ALL
)) {
5878 acxlog(L_INIT
, "updating: %s Tx\n",
5879 priv
->tx_disabled
? "disable" : "enable");
5880 if (priv
->tx_disabled
)
5881 acx_s_issue_cmd(priv
, ACX1xx_CMD_DISABLE_TX
, NULL
, 0);
5883 /* FIXME: this used to be 1, but since we don't transfer a parameter... */
5885 acx_s_issue_cmd(priv
, ACX1xx_CMD_ENABLE_TX
, &(priv
->channel
), 1);
5886 CLEAR_BIT(priv
->set_mask
, GETSET_TX
);
5889 if (priv
->set_mask
& (GETSET_RX
|GETSET_ALL
)) {
5891 acxlog(L_INIT
, "updating: enable Rx on channel: %u\n",
5893 acx_s_issue_cmd(priv
, ACX1xx_CMD_ENABLE_RX
, &(priv
->channel
), 1);
5894 CLEAR_BIT(priv
->set_mask
, GETSET_RX
);
5897 if (priv
->set_mask
& (GETSET_RETRY
|GETSET_ALL
)) {
5898 u8 short_retry
[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN
];
5899 u8 long_retry
[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN
];
5901 acxlog(L_INIT
, "updating short retry limit: %u, long retry limit: %u\n",
5902 priv
->short_retry
, priv
->long_retry
);
5903 short_retry
[0x4] = priv
->short_retry
;
5904 long_retry
[0x4] = priv
->long_retry
;
5905 acx_s_configure(priv
, &short_retry
, ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT
);
5906 acx_s_configure(priv
, &long_retry
, ACX1xx_IE_DOT11_LONG_RETRY_LIMIT
);
5907 CLEAR_BIT(priv
->set_mask
, GETSET_RETRY
);
5910 if (priv
->set_mask
& (SET_MSDU_LIFETIME
|GETSET_ALL
)) {
5911 u8 xmt_msdu_lifetime
[4 + ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN
];
5913 acxlog(L_INIT
, "updating tx MSDU lifetime: %u\n",
5914 priv
->msdu_lifetime
);
5915 *(u32
*)&xmt_msdu_lifetime
[4] = cpu_to_le32((u32
)priv
->msdu_lifetime
);
5916 acx_s_configure(priv
, &xmt_msdu_lifetime
, ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME
);
5917 CLEAR_BIT(priv
->set_mask
, SET_MSDU_LIFETIME
);
5920 if (priv
->set_mask
& (GETSET_REG_DOMAIN
|GETSET_ALL
)) {
5922 acx_ie_generic_t dom
;
5925 acxlog(L_INIT
, "updating regulatory domain: 0x%02X\n",
5927 for (i
= 0; i
< sizeof(reg_domain_ids
); i
++)
5928 if (reg_domain_ids
[i
] == priv
->reg_dom_id
)
5931 if (sizeof(reg_domain_ids
) == i
) {
5932 acxlog(L_INIT
, "Invalid or unsupported regulatory "
5933 "domain 0x%02X specified, falling back to "
5934 "FCC (USA)! Please report if this sounds "
5935 "fishy!\n", priv
->reg_dom_id
);
5937 priv
->reg_dom_id
= reg_domain_ids
[i
];
5940 priv
->reg_dom_chanmask
= reg_domain_channel_masks
[i
];
5941 dom
.m
.bytes
[0] = priv
->reg_dom_id
;
5942 acx_s_configure(priv
, &dom
, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN
);
5944 mask
= (1 << (priv
->channel
- 1));
5945 if (!(priv
->reg_dom_chanmask
& mask
)) {
5946 /* hmm, need to adjust our channel to reside within domain */
5948 for (i
= 1; i
<= 14; i
++) {
5949 if (priv
->reg_dom_chanmask
& mask
) {
5950 printk("%s: adjusting "
5951 "selected channel from %d "
5952 "to %d due to new regulatory "
5953 "domain\n", priv
->netdev
->name
,
5961 CLEAR_BIT(priv
->set_mask
, GETSET_REG_DOMAIN
);
5964 if (priv
->set_mask
& (GETSET_MODE
|GETSET_ALL
)) {
5965 priv
->netdev
->type
= ARPHRD_ETHER
;
5967 switch (priv
->mode
) {
5970 acx_lock(priv
, flags
);
5971 acx_l_sta_list_init(priv
);
5973 priv
->ap_client
= NULL
;
5974 MAC_COPY(priv
->bssid
, priv
->dev_addr
);
5975 /* this basically says "we're connected" */
5976 acx_set_status(priv
, ACX_STATUS_4_ASSOCIATED
);
5977 acx_unlock(priv
, flags
);
5979 acx111_s_feature_off(priv
, 0, FEATURE2_NO_TXCRYPT
|FEATURE2_SNIFFER
);
5980 /* start sending beacons */
5981 acx_s_cmd_join_bssid(priv
, priv
->bssid
);
5983 case ACX_MODE_MONITOR
:
5984 /* priv->netdev->type = ARPHRD_ETHER; */
5985 /* priv->netdev->type = ARPHRD_IEEE80211; */
5986 priv
->netdev
->type
= ARPHRD_IEEE80211_PRISM
;
5987 acx111_s_feature_on(priv
, 0, FEATURE2_NO_TXCRYPT
|FEATURE2_SNIFFER
);
5988 /* this stops beacons */
5989 acx_s_cmd_join_bssid(priv
, priv
->bssid
);
5990 /* this basically says "we're connected" */
5991 acx_set_status(priv
, ACX_STATUS_4_ASSOCIATED
);
5992 SET_BIT(priv
->set_mask
, SET_RXCONFIG
|SET_WEP_OPTIONS
);
5994 case ACX_MODE_0_ADHOC
:
5995 case ACX_MODE_2_STA
:
5996 acx111_s_feature_off(priv
, 0, FEATURE2_NO_TXCRYPT
|FEATURE2_SNIFFER
);
5998 priv
->ap_client
= NULL
;
5999 /* we want to start looking for peer or AP */
6003 /* TODO: disable RX/TX, stop any scanning activity etc: */
6004 /* priv->tx_disabled = 1; */
6005 /* SET_BIT(priv->set_mask, GETSET_RX|GETSET_TX); */
6007 /* This stops beacons (invalid macmode...) */
6008 acx_s_cmd_join_bssid(priv
, priv
->bssid
);
6009 acx_set_status(priv
, ACX_STATUS_0_STOPPED
);
6012 CLEAR_BIT(priv
->set_mask
, GETSET_MODE
);
6015 if (priv
->set_mask
& (SET_RXCONFIG
|GETSET_ALL
)) {
6016 acx_s_initialize_rx_config(priv
);
6017 CLEAR_BIT(priv
->set_mask
, SET_RXCONFIG
);
6020 if (priv
->set_mask
& (GETSET_RESCAN
|GETSET_ALL
)) {
6021 switch (priv
->mode
) {
6022 case ACX_MODE_0_ADHOC
:
6023 case ACX_MODE_2_STA
:
6027 CLEAR_BIT(priv
->set_mask
, GETSET_RESCAN
);
6030 if (priv
->set_mask
& (GETSET_WEP
|GETSET_ALL
)) {
6033 ie_dot11WEPDefaultKeyID_t dkey
;
6036 u16 type ACX_PACKED
;
6041 acxlog(L_INIT
, "updating WEP key settings\n");
6043 acx_s_set_wepkey(priv
);
6045 dkey
.KeyID
= priv
->wep_current_index
;
6046 acxlog(L_INIT
, "setting WEP key %u as default\n", dkey
.KeyID
);
6047 acx_s_configure(priv
, &dkey
, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET
);
6050 acx_s_configure(priv
, &keyindic
, ACX111_IE_KEY_CHOOSE
);
6053 CLEAR_BIT(priv
->set_mask
, GETSET_WEP
);
6056 if (priv
->set_mask
& (SET_WEP_OPTIONS
|GETSET_ALL
)) {
6057 acx100_ie_wep_options_t options
;
6059 if (IS_ACX111(priv
)) {
6060 acxlog(L_DEBUG
, "setting WEP Options for acx111 is not supported\n");
6062 acxlog(L_INIT
, "setting WEP Options\n");
6064 /* let's choose maximum setting: 4 default keys,
6065 * plus 10 other keys: */
6066 options
.NumKeys
= cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS
+ 10);
6067 /* don't decrypt default key only,
6068 * don't override decryption: */
6069 options
.WEPOption
= 0;
6070 if (priv
->mode
== ACX_MODE_MONITOR
) {
6071 /* don't decrypt default key only,
6072 * override decryption mechanism: */
6073 options
.WEPOption
= 2;
6076 acx_s_configure(priv
, &options
, ACX100_IE_WEP_OPTIONS
);
6078 CLEAR_BIT(priv
->set_mask
, SET_WEP_OPTIONS
);
6081 /* Rescan was requested */
6083 switch (priv
->mode
) {
6084 case ACX_MODE_0_ADHOC
:
6085 case ACX_MODE_2_STA
:
6086 /* We can avoid clearing list if join code
6087 ** will be a bit more clever about not picking
6088 ** 'bad' AP over and over again */
6089 acx_lock(priv
, flags
);
6090 priv
->ap_client
= NULL
;
6091 acx_l_sta_list_init(priv
);
6092 acx_set_status(priv
, ACX_STATUS_1_SCANNING
);
6093 acx_unlock(priv
, flags
);
6095 acx_s_cmd_start_scan(priv
);
6099 /* debug, rate, and nick don't need any handling */
6100 /* what about sniffing mode?? */
6102 acxlog(L_INIT
, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
6103 priv
->get_mask
, priv
->set_mask
);
6110 /***********************************************************************
6113 acx_s_initialize_rx_config(wlandevice_t
*priv
)
6118 u16 rx_cfg1 ACX_PACKED
;
6119 u16 rx_cfg2 ACX_PACKED
;
6122 switch (priv
->mode
) {
6124 priv
->rx_config_1
= (u16
) (0
6125 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
6126 /* | RX_CFG1_FILTER_SSID */
6127 /* | RX_CFG1_FILTER_BCAST */
6128 /* | RX_CFG1_RCV_MC_ADDR1 */
6129 /* | RX_CFG1_RCV_MC_ADDR0 */
6130 /* | RX_CFG1_FILTER_ALL_MULTI */
6131 /* | RX_CFG1_FILTER_BSSID */
6132 /* | RX_CFG1_FILTER_MAC */
6133 /* | RX_CFG1_RCV_PROMISCUOUS */
6134 /* | RX_CFG1_INCLUDE_FCS */
6135 /* | RX_CFG1_INCLUDE_PHY_HDR */
6137 priv
->rx_config_2
= (u16
) (0
6138 /*| RX_CFG2_RCV_ASSOC_REQ */
6139 /*| RX_CFG2_RCV_AUTH_FRAMES */
6140 /*| RX_CFG2_RCV_BEACON_FRAMES */
6141 /*| RX_CFG2_RCV_CONTENTION_FREE */
6142 /*| RX_CFG2_RCV_CTRL_FRAMES */
6143 /*| RX_CFG2_RCV_DATA_FRAMES */
6144 /*| RX_CFG2_RCV_BROKEN_FRAMES */
6145 /*| RX_CFG2_RCV_MGMT_FRAMES */
6146 /*| RX_CFG2_RCV_PROBE_REQ */
6147 /*| RX_CFG2_RCV_PROBE_RESP */
6148 /*| RX_CFG2_RCV_ACK_FRAMES */
6149 /*| RX_CFG2_RCV_OTHER */
6152 case ACX_MODE_MONITOR
:
6153 priv
->rx_config_1
= (u16
) (0
6154 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
6155 /* | RX_CFG1_FILTER_SSID */
6156 /* | RX_CFG1_FILTER_BCAST */
6157 /* | RX_CFG1_RCV_MC_ADDR1 */
6158 /* | RX_CFG1_RCV_MC_ADDR0 */
6159 /* | RX_CFG1_FILTER_ALL_MULTI */
6160 /* | RX_CFG1_FILTER_BSSID */
6161 /* | RX_CFG1_FILTER_MAC */
6162 | RX_CFG1_RCV_PROMISCUOUS
6163 /* | RX_CFG1_INCLUDE_FCS */
6164 /* | RX_CFG1_INCLUDE_PHY_HDR */
6166 priv
->rx_config_2
= (u16
) (0
6167 | RX_CFG2_RCV_ASSOC_REQ
6168 | RX_CFG2_RCV_AUTH_FRAMES
6169 | RX_CFG2_RCV_BEACON_FRAMES
6170 | RX_CFG2_RCV_CONTENTION_FREE
6171 | RX_CFG2_RCV_CTRL_FRAMES
6172 | RX_CFG2_RCV_DATA_FRAMES
6173 | RX_CFG2_RCV_BROKEN_FRAMES
6174 | RX_CFG2_RCV_MGMT_FRAMES
6175 | RX_CFG2_RCV_PROBE_REQ
6176 | RX_CFG2_RCV_PROBE_RESP
6177 | RX_CFG2_RCV_ACK_FRAMES
6182 priv
->rx_config_1
= (u16
) (0
6183 /* | RX_CFG1_INCLUDE_RXBUF_HDR */
6184 /* | RX_CFG1_FILTER_SSID */
6185 /* | RX_CFG1_FILTER_BCAST */
6186 /* | RX_CFG1_RCV_MC_ADDR1 */
6187 /* | RX_CFG1_RCV_MC_ADDR0 */
6188 /* | RX_CFG1_FILTER_ALL_MULTI */
6189 /* | RX_CFG1_FILTER_BSSID */
6190 | RX_CFG1_FILTER_MAC
6191 /* | RX_CFG1_RCV_PROMISCUOUS */
6192 /* | RX_CFG1_INCLUDE_FCS */
6193 /* | RX_CFG1_INCLUDE_PHY_HDR */
6195 priv
->rx_config_2
= (u16
) (0
6196 | RX_CFG2_RCV_ASSOC_REQ
6197 | RX_CFG2_RCV_AUTH_FRAMES
6198 | RX_CFG2_RCV_BEACON_FRAMES
6199 | RX_CFG2_RCV_CONTENTION_FREE
6200 | RX_CFG2_RCV_CTRL_FRAMES
6201 | RX_CFG2_RCV_DATA_FRAMES
6202 /*| RX_CFG2_RCV_BROKEN_FRAMES */
6203 | RX_CFG2_RCV_MGMT_FRAMES
6204 | RX_CFG2_RCV_PROBE_REQ
6205 | RX_CFG2_RCV_PROBE_RESP
6206 /*| RX_CFG2_RCV_ACK_FRAMES */
6212 if (IS_ACX100(priv
))
6213 /* only ACX100 supports that */
6215 priv
->rx_config_1
|= RX_CFG1_INCLUDE_RXBUF_HDR
;
6217 acxlog(L_INIT
, "setting RXconfig to %04X:%04X\n",
6218 priv
->rx_config_1
, priv
->rx_config_2
);
6219 cfg
.rx_cfg1
= cpu_to_le16(priv
->rx_config_1
);
6220 cfg
.rx_cfg2
= cpu_to_le16(priv
->rx_config_2
);
6221 acx_s_configure(priv
, &cfg
, ACX1xx_IE_RXCONFIG
);
6225 /***********************************************************************
6226 ** acx_e_after_interrupt_task
6229 acx_s_recalib_radio(wlandevice_t
*priv
)
6231 if (IS_ACX111(priv
)) {
6232 acx111_cmd_radiocalib_t cal
;
6234 printk("%s: recalibrating radio\n", priv
->netdev
->name
);
6235 /* automatic recalibration, choose all methods: */
6236 cal
.methods
= cpu_to_le32(0x8000000f);
6237 /* automatic recalibration every 60 seconds (value in TUs)
6238 * FIXME: what is the firmware default here?? */
6239 cal
.interval
= cpu_to_le32(58594);
6240 return acx_s_issue_cmd_timeo(priv
, ACX111_CMD_RADIOCALIB
,
6241 &cal
, sizeof(cal
), CMD_TIMEOUT_MS(100));
6243 if (/* (OK == acx_s_issue_cmd(priv, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
6244 (OK == acx_s_issue_cmd(priv, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
6245 (OK
== acx_s_issue_cmd(priv
, ACX1xx_CMD_ENABLE_TX
, &(priv
->channel
), 1)) &&
6246 (OK
== acx_s_issue_cmd(priv
, ACX1xx_CMD_ENABLE_RX
, &(priv
->channel
), 1)) )
6253 acx_s_after_interrupt_recalib(wlandevice_t
*priv
)
6257 /* this helps with ACX100 at least;
6258 * hopefully ACX111 also does a
6259 * recalibration here */
6261 /* clear flag beforehand, since we want to make sure
6262 * it's cleared; then only set it again on specific circumstances */
6263 CLEAR_BIT(priv
->after_interrupt_jobs
, ACX_AFTER_IRQ_CMD_RADIO_RECALIB
);
6265 /* better wait a bit between recalibrations to
6266 * prevent overheating due to torturing the card
6267 * into working too long despite high temperature
6268 * (just a safety measure) */
6269 if (priv
->recalib_time_last_success
6270 && time_before(jiffies
, priv
->recalib_time_last_success
6271 + RECALIB_PAUSE
* 60 * HZ
)) {
6272 priv
->recalib_msg_ratelimit
++;
6273 if (priv
->recalib_msg_ratelimit
<= 5)
6274 printk("%s: less than " STRING(RECALIB_PAUSE
)
6275 " minutes since last radio recalibration, "
6276 "not recalibrating (maybe card is too hot?)\n",
6277 priv
->netdev
->name
);
6278 if (priv
->recalib_msg_ratelimit
== 5)
6279 printk("disabling above message\n");
6283 priv
->recalib_msg_ratelimit
= 0;
6285 /* note that commands sometimes fail (card busy),
6286 * so only clear flag if we were fully successful */
6287 res
= acx_s_recalib_radio(priv
);
6289 printk("%s: successfully recalibrated radio\n",
6290 priv
->netdev
->name
);
6291 priv
->recalib_time_last_success
= jiffies
;
6292 priv
->recalib_failure_count
= 0;
6294 /* failed: resubmit, but only limited
6295 * amount of times within some time range
6296 * to prevent endless loop */
6298 priv
->recalib_time_last_success
= 0; /* we failed */
6300 /* if some time passed between last
6301 * attempts, then reset failure retry counter
6302 * to be able to do next recalib attempt */
6303 if (time_after(jiffies
, priv
->recalib_time_last_attempt
+ HZ
))
6304 priv
->recalib_failure_count
= 0;
6306 if (++priv
->recalib_failure_count
<= 5) {
6307 priv
->recalib_time_last_attempt
= jiffies
;
6308 acx_schedule_task(priv
, ACX_AFTER_IRQ_CMD_RADIO_RECALIB
);
6314 acx_e_after_interrupt_task(void *data
)
6316 netdevice_t
*dev
= (netdevice_t
*) data
;
6317 wlandevice_t
*priv
= netdev_priv(dev
);
6323 if (!priv
->after_interrupt_jobs
)
6324 goto end
; /* no jobs to do */
6326 #if TX_CLEANUP_IN_SOFTIRQ
6327 /* can happen only on PCI */
6328 if (priv
->after_interrupt_jobs
& ACX_AFTER_IRQ_TX_CLEANUP
) {
6329 acx_lock(priv
, flags
);
6330 acxpci_l_clean_txdesc(priv
);
6331 CLEAR_BIT(priv
->after_interrupt_jobs
, ACX_AFTER_IRQ_TX_CLEANUP
);
6332 acx_unlock(priv
, flags
);
6335 /* we see lotsa tx errors */
6336 if (priv
->after_interrupt_jobs
& ACX_AFTER_IRQ_CMD_RADIO_RECALIB
) {
6337 acx_s_after_interrupt_recalib(priv
);
6340 /* a poor interrupt code wanted to do update_card_settings() */
6341 if (priv
->after_interrupt_jobs
& ACX_AFTER_IRQ_UPDATE_CARD_CFG
) {
6342 if (ACX_STATE_IFACE_UP
& priv
->dev_state_mask
)
6343 acx_s_update_card_settings(priv
, 0, 0);
6344 CLEAR_BIT(priv
->after_interrupt_jobs
, ACX_AFTER_IRQ_UPDATE_CARD_CFG
);
6347 /* 1) we detected that no Scan_Complete IRQ came from fw, or
6348 ** 2) we found too many STAs */
6349 if (priv
->after_interrupt_jobs
& ACX_AFTER_IRQ_CMD_STOP_SCAN
) {
6350 acxlog(L_IRQ
, "sending a stop scan cmd...\n");
6351 acx_s_issue_cmd(priv
, ACX1xx_CMD_STOP_SCAN
, NULL
, 0);
6352 /* HACK: set the IRQ bit, since we won't get a
6353 * scan complete IRQ any more on ACX111 (works on ACX100!),
6354 * since _we_, not a fw, have stopped the scan */
6355 SET_BIT(priv
->irq_status
, HOST_INT_SCAN_COMPLETE
);
6356 CLEAR_BIT(priv
->after_interrupt_jobs
, ACX_AFTER_IRQ_CMD_STOP_SCAN
);
6359 /* either fw sent Scan_Complete or we detected that
6360 ** no Scan_Complete IRQ came from fw. Finish scanning,
6361 ** pick join partner if any */
6362 if (priv
->after_interrupt_jobs
& ACX_AFTER_IRQ_COMPLETE_SCAN
) {
6363 if (priv
->status
== ACX_STATUS_1_SCANNING
) {
6364 if (OK
!= acx_s_complete_scan(priv
)) {
6365 SET_BIT(priv
->after_interrupt_jobs
,
6366 ACX_AFTER_IRQ_RESTART_SCAN
);
6369 /* + scan kills current join status - restore it
6370 ** (do we need it for STA?) */
6371 /* + does it happen only with active scans?
6372 ** active and passive scans? ALL scans including
6373 ** background one? */
6374 /* + was not verified that everything is restored
6375 ** (but at least we start to emit beacons again) */
6376 switch (priv
->mode
) {
6377 case ACX_MODE_0_ADHOC
:
6379 acxlog(L_IRQ
, "redoing cmd_join_bssid() after scan\n");
6380 acx_s_cmd_join_bssid(priv
, priv
->bssid
);
6383 CLEAR_BIT(priv
->after_interrupt_jobs
, ACX_AFTER_IRQ_COMPLETE_SCAN
);
6386 /* STA auth or assoc timed out, start over again */
6387 if (priv
->after_interrupt_jobs
& ACX_AFTER_IRQ_RESTART_SCAN
) {
6388 acxlog(L_IRQ
, "sending a start_scan cmd...\n");
6389 acx_s_cmd_start_scan(priv
);
6390 CLEAR_BIT(priv
->after_interrupt_jobs
, ACX_AFTER_IRQ_RESTART_SCAN
);
6393 /* whee, we got positive assoc response! 8) */
6394 if (priv
->after_interrupt_jobs
& ACX_AFTER_IRQ_CMD_ASSOCIATE
) {
6395 acx_ie_generic_t pdr
;
6396 /* tiny race window exists, checking that we still a STA */
6397 switch (priv
->mode
) {
6398 case ACX_MODE_2_STA
:
6399 pdr
.m
.aid
= cpu_to_le16(priv
->aid
);
6400 acx_s_configure(priv
, &pdr
, ACX1xx_IE_ASSOC_ID
);
6401 acx_set_status(priv
, ACX_STATUS_4_ASSOCIATED
);
6402 acxlog(L_ASSOC
|L_DEBUG
, "ASSOCIATED!\n");
6403 CLEAR_BIT(priv
->after_interrupt_jobs
, ACX_AFTER_IRQ_CMD_ASSOCIATE
);
6407 acx_sem_unlock(priv
);
6412 /***********************************************************************
6413 ** acx_schedule_task
6415 ** Schedule the call of the after_interrupt method after leaving
6416 ** the interrupt context.
6419 acx_schedule_task(wlandevice_t
*priv
, unsigned int set_flag
)
6421 SET_BIT(priv
->after_interrupt_jobs
, set_flag
);
6422 SCHEDULE_WORK(&priv
->after_interrupt_task
);
6426 /***********************************************************************
6429 acx_init_task_scheduler(wlandevice_t
*priv
)
6431 /* configure task scheduler */
6432 INIT_WORK(&priv
->after_interrupt_task
, acx_e_after_interrupt_task
,
6437 /***********************************************************************
6441 acx_s_start(wlandevice_t
*priv
)
6446 * Ok, now we do everything that can possibly be done with ioctl
6447 * calls to make sure that when it was called before the card
6448 * was up we get the changes asked for
6451 SET_BIT(priv
->set_mask
, SET_TEMPLATES
|SET_STA_LIST
|GETSET_WEP
6452 |GETSET_TXPOWER
|GETSET_ANTENNA
|GETSET_ED_THRESH
|GETSET_CCA
6453 |GETSET_REG_DOMAIN
|GETSET_MODE
|GETSET_CHANNEL
6454 |GETSET_TX
|GETSET_RX
);
6456 acxlog(L_INIT
, "updating initial settings on iface activation...\n");
6457 acx_s_update_card_settings(priv
, 0, 0);
6463 /***********************************************************************
6464 ** acx_update_capabilities
6467 acx_update_capabilities(wlandevice_t
*priv
)
6471 switch (priv
->mode
) {
6473 SET_BIT(cap
, WF_MGMT_CAP_ESS
); break;
6474 case ACX_MODE_0_ADHOC
:
6475 SET_BIT(cap
, WF_MGMT_CAP_IBSS
); break;
6476 /* other types of stations do not emit beacons */
6479 if (priv
->wep_restricted
) {
6480 SET_BIT(cap
, WF_MGMT_CAP_PRIVACY
);
6482 if (priv
->capab_short
) {
6483 SET_BIT(cap
, WF_MGMT_CAP_SHORT
);
6485 if (priv
->capab_pbcc
) {
6486 SET_BIT(cap
, WF_MGMT_CAP_PBCC
);
6488 if (priv
->capab_agility
) {
6489 SET_BIT(cap
, WF_MGMT_CAP_AGILITY
);
6491 acxlog(L_DEBUG
, "caps updated from 0x%04X to 0x%04X\n",
6492 priv
->capabilities
, cap
);
6493 priv
->capabilities
= cap
;
6497 /***********************************************************************
6498 ** FIXME: check whether this function is indeed acx111 only,
6499 ** rename ALL relevant definitions to indicate actual card scope!
6502 acx111_s_read_configoption(wlandevice_t
*priv
)
6504 acx111_ie_configoption_t co
, co2
;
6508 if (OK
!= acx_s_interrogate(priv
, &co
, ACX111_IE_CONFIG_OPTIONS
) ) {
6511 if (!(acx_debug
& L_DEBUG
))
6514 memcpy(&co2
.configoption_fixed
, &co
.configoption_fixed
,
6515 sizeof(co
.configoption_fixed
));
6517 pEle
= (u8
*)&co
.configoption_fixed
+ sizeof(co
.configoption_fixed
) - 4;
6519 co2
.antennas
.type
= pEle
[0];
6520 co2
.antennas
.len
= pEle
[1];
6521 printk("AntennaID:%02X Len:%02X Data:",
6522 co2
.antennas
.type
, co2
.antennas
.len
);
6523 for (i
= 0; i
< pEle
[1]; i
++) {
6524 co2
.antennas
.list
[i
] = pEle
[i
+2];
6525 printk("%02X ", pEle
[i
+2]);
6529 pEle
+= pEle
[1] + 2;
6530 co2
.power_levels
.type
= pEle
[0];
6531 co2
.power_levels
.len
= pEle
[1];
6532 printk("PowerLevelID:%02X Len:%02X Data:",
6533 co2
.power_levels
.type
, co2
.power_levels
.len
);
6534 for (i
= 0; i
< pEle
[1]*2; i
++) {
6535 co2
.power_levels
.list
[i
] = pEle
[i
+2];
6536 printk("%02X ", pEle
[i
+2]);
6540 pEle
+= pEle
[1]*2 + 2;
6541 co2
.data_rates
.type
= pEle
[0];
6542 co2
.data_rates
.len
= pEle
[1];
6543 printk("DataRatesID:%02X Len:%02X Data:",
6544 co2
.data_rates
.type
, co2
.data_rates
.len
);
6545 for (i
= 0; i
< pEle
[1]; i
++) {
6546 co2
.data_rates
.list
[i
] = pEle
[i
+2];
6547 printk("%02X ", pEle
[i
+2]);
6551 pEle
+= pEle
[1] + 2;
6552 co2
.domains
.type
= pEle
[0];
6553 co2
.domains
.len
= pEle
[1];
6554 printk("DomainID:%02X Len:%02X Data:",
6555 co2
.domains
.type
, co2
.domains
.len
);
6556 for (i
= 0; i
< pEle
[1]; i
++) {
6557 co2
.domains
.list
[i
] = pEle
[i
+2];
6558 printk("%02X ", pEle
[i
+2]);
6562 pEle
+= pEle
[1] + 2;
6563 co2
.product_id
.type
= pEle
[0];
6564 co2
.product_id
.len
= pEle
[1];
6565 for (i
= 0; i
< pEle
[1]; i
++) {
6566 co2
.product_id
.list
[i
] = pEle
[i
+2];
6568 printk("ProductID:%02X Len:%02X Data:%.*s\n",
6569 co2
.product_id
.type
, co2
.product_id
.len
,
6570 co2
.product_id
.len
, (char *)co2
.product_id
.list
);
6572 pEle
+= pEle
[1] + 2;
6573 co2
.manufacturer
.type
= pEle
[0];
6574 co2
.manufacturer
.len
= pEle
[1];
6575 for (i
= 0; i
< pEle
[1]; i
++) {
6576 co2
.manufacturer
.list
[i
] = pEle
[i
+2];
6578 printk("ManufacturerID:%02X Len:%02X Data:%.*s\n",
6579 co2
.manufacturer
.type
, co2
.manufacturer
.len
,
6580 co2
.manufacturer
.len
, (char *)co2
.manufacturer
.list
);
6582 printk("EEPROM part:\n");
6583 for (i=0; i<58; i++) {
6584 printk("%02X =======> 0x%02X\n",
6585 i, (u8 *)co.configoption_fixed.NVSv[i-2]);
6592 /***********************************************************************
6595 acx_e_init_module(void)
6599 acx_struct_size_check();
6601 printk("acx: this driver is still EXPERIMENTAL\n"
6602 "acx: reading README file and/or Craig's HOWTO is "
6603 "recommended, visit http://acx100.sf.net in case "
6604 "of further questions/discussion\n");
6606 #if defined(CONFIG_ACX_PCI)
6607 r1
= acxpci_e_init_module();
6611 #if defined(CONFIG_ACX_USB)
6612 r2
= acxusb_e_init_module();
6616 if (r2
&& r1
) /* both failed! */
6617 return r2
? r2
: r1
;
6618 /* return success if at least one succeeded */
6623 acx_e_cleanup_module(void)
6625 #if defined(CONFIG_ACX_PCI)
6626 acxpci_e_cleanup_module();
6628 #if defined(CONFIG_ACX_USB)
6629 acxusb_e_cleanup_module();
6633 module_init(acx_e_init_module
)
6634 module_exit(acx_e_cleanup_module
)