Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: chromeos/drivers/ath6kl/os/linux/ar6000_drv.c

Issue 646055: Atheros AR600x driver + build glue (Closed)
Patch Set: Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 *
3 * Copyright (c) 2004-2010 Atheros Communications Inc.
4 * All rights reserved.
5 *
6 *
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2 as
9 // published by the Free Software Foundation;
10 //
11 // Software distributed under the License is distributed on an "AS
12 // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
13 // implied. See the License for the specific language governing
14 // rights and limitations under the License.
15 //
16 //
17 *
18 */
19
20 /*
21 * This driver is a pseudo ethernet driver to access the Atheros AR6000
22 * WLAN Device
23 */
24 #ifdef ANDROID_ENV
25 /* ATHENV */
26 #include <linux/fs.h>
27 /* ATHENV */
28 #endif
29
30 #include "ar6000_drv.h"
31 #ifdef CONFIG_CFG80211
32 #include "cfg80211.h"
33 #endif /* CONFIG_CFG80211 */
34 #include "htc.h"
35 #include "wmi_filter_linux.h"
36 #include "epping_test.h"
37 #include "wlan_config.h"
38 #include "ar3kconfig.h"
39
40 /* LINUX_HACK_FUDGE_FACTOR -- this is used to provide a workaround for linux beh avior. When
41 * the meta data was added to the header it was found that linux did not correc tly provide
42 * enough headroom. However when more headroom was requested beyond what was t ruly needed
43 * Linux gave the requested headroom. Therefore to get the necessary headroom f rom Linux
44 * the driver requests more than is needed by the amount = LINUX_HACK_FUDGE_FAC TOR */
45 #define LINUX_HACK_FUDGE_FACTOR 16
46
47 A_UINT8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
48 A_UINT8 null_mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
49
50 #ifdef DEBUG
51
52 #define ATH_DEBUG_DBG_LOG ATH_DEBUG_MAKE_MODULE_MASK(0)
53 #define ATH_DEBUG_WLAN_CONNECT ATH_DEBUG_MAKE_MODULE_MASK(1)
54 #define ATH_DEBUG_WLAN_SCAN ATH_DEBUG_MAKE_MODULE_MASK(2)
55 #define ATH_DEBUG_WLAN_TX ATH_DEBUG_MAKE_MODULE_MASK(3)
56 #define ATH_DEBUG_WLAN_RX ATH_DEBUG_MAKE_MODULE_MASK(4)
57 #define ATH_DEBUG_HTC_RAW ATH_DEBUG_MAKE_MODULE_MASK(5)
58 #define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
59
60 static ATH_DEBUG_MASK_DESCRIPTION driver_debug_desc[] = {
61 { ATH_DEBUG_DBG_LOG , "Target Debug Logs"},
62 { ATH_DEBUG_WLAN_CONNECT , "WLAN connect"},
63 { ATH_DEBUG_WLAN_SCAN , "WLAN scan"},
64 { ATH_DEBUG_WLAN_TX , "WLAN Tx"},
65 { ATH_DEBUG_WLAN_RX , "WLAN Rx"},
66 { ATH_DEBUG_HTC_RAW , "HTC Raw IF tracing"},
67 { ATH_DEBUG_HCI_BRIDGE , "HCI Bridge Setup"},
68 { ATH_DEBUG_HCI_RECV , "HCI Recv tracing"},
69 { ATH_DEBUG_HCI_SEND , "HCI Send tracing"},
70 { ATH_DEBUG_HCI_DUMP , "HCI Packet dumps"},
71 };
72
73 ATH_DEBUG_INSTANTIATE_MODULE_VAR(driver,
74 "driver",
75 "Linux Driver Interface",
76 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_WLAN_SCAN |
77 ATH_DEBUG_HCI_BRIDGE,
78 ATH_DEBUG_DESCRIPTION_COUNT(driver_debug_desc),
79 driver_debug_desc);
80
81 #endif
82
83
84 #define IS_MAC_NULL(mac) (mac[0]==0 && mac[1]==0 && mac[2]==0 && mac[3]==0 && ma c[4]==0 && mac[5]==0)
85 #define IS_MAC_BCAST(mac) (*mac==0xff)
86
87 MODULE_LICENSE("GPL and additional rights");
88
89 #ifndef REORG_APTC_HEURISTICS
90 #undef ADAPTIVE_POWER_THROUGHPUT_CONTROL
91 #endif /* REORG_APTC_HEURISTICS */
92
93 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
94 #define APTC_TRAFFIC_SAMPLING_INTERVAL 100 /* msec */
95 #define APTC_UPPER_THROUGHPUT_THRESHOLD 3000 /* Kbps */
96 #define APTC_LOWER_THROUGHPUT_THRESHOLD 2000 /* Kbps */
97
98 typedef struct aptc_traffic_record {
99 A_BOOL timerScheduled;
100 struct timeval samplingTS;
101 unsigned long bytesReceived;
102 unsigned long bytesTransmitted;
103 } APTC_TRAFFIC_RECORD;
104
105 A_TIMER aptcTimer;
106 APTC_TRAFFIC_RECORD aptcTR;
107 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
108
109 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
110 // callbacks registered by HCI transport driver
111 HCI_TRANSPORT_CALLBACKS ar6kHciTransCallbacks = { NULL };
112 #endif
113
114 unsigned int processDot11Hdr = 0;
115 int bmienable = 1;
116
117 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
118 char ifname[IFNAMSIZ] = {0,};
119 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
120
121 int wlaninitmode = WLAN_INIT_MODE_DRV;
122 unsigned int bypasswmi = 0;
123 unsigned int debuglevel = 0;
124 int tspecCompliance = ATHEROS_COMPLIANCE;
125 unsigned int busspeedlow = 0;
126 unsigned int onebitmode = 0;
127 unsigned int skipflash = 0;
128 unsigned int wmitimeout = 2;
129 unsigned int wlanNodeCaching = 1;
130 unsigned int enableuartprint = 1;
131 unsigned int logWmiRawMsgs = 0;
132 unsigned int enabletimerwar = 0;
133 unsigned int fwmode = 1;
134 unsigned int mbox_yield_limit = 99;
135 unsigned int enablerssicompensation = 0;
136 int reduce_credit_dribble = 1 + HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF;
137 int allow_trace_signal = 0;
138 #ifdef CONFIG_HOST_TCMD_SUPPORT
139 unsigned int testmode =0;
140 #endif
141
142 unsigned int irqprocmode = HIF_DEVICE_IRQ_ASYNC_SYNC;
143 unsigned int nohifscattersupport = 0;
144 unsigned int panic_on_assert = 1;
145
146 unsigned int setuphci = 0;
147 unsigned int loghci = 0;
148 unsigned int setupbtdev = 0;
149 #ifndef EXPORT_HCI_BRIDGE_INTERFACE
150 unsigned int ar3khcibaud = 0;
151 unsigned int hciuartscale = 0;
152 unsigned int hciuartstep = 0;
153 #endif
154 #ifdef CONFIG_CHECKSUM_OFFLOAD
155 unsigned int csumOffload=0;
156 unsigned int csumOffloadTest=0;
157 #endif
158 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
159 module_param_string(ifname, ifname, sizeof(ifname), 0644);
160 module_param(wlaninitmode, int, 0644);
161 module_param(bmienable, int, 0644);
162 module_param(bypasswmi, int, 0644);
163 module_param(debuglevel, int, 0644);
164 module_param(tspecCompliance, int, 0644);
165 module_param(onebitmode, int, 0644);
166 module_param(busspeedlow, int, 0644);
167 module_param(skipflash, int, 0644);
168 module_param(wmitimeout, int, 0644);
169 module_param(wlanNodeCaching, int, 0644);
170 module_param(logWmiRawMsgs, int, 0644);
171 module_param(enableuartprint, int, 0644);
172 module_param(enabletimerwar, int, 0644);
173 module_param(fwmode, int, 0644);
174 module_param(mbox_yield_limit, int, 0644);
175 module_param(reduce_credit_dribble, int, 0644);
176 module_param(allow_trace_signal, int, 0644);
177 module_param(enablerssicompensation, int, 0644);
178 module_param(processDot11Hdr, int, 0644);
179 #ifdef CONFIG_CHECKSUM_OFFLOAD
180 module_param(csumOffload, int, 0644);
181 #endif
182 #ifdef CONFIG_HOST_TCMD_SUPPORT
183 module_param(testmode, int, 0644);
184 #endif
185 module_param(irqprocmode, int, 0644);
186 module_param(nohifscattersupport, int, 0644);
187 module_param(panic_on_assert, int, 0644);
188 module_param(setuphci, int, 0644);
189 module_param(loghci, int, 0644);
190 module_param(setupbtdev, int, 0644);
191 #ifndef EXPORT_HCI_BRIDGE_INTERFACE
192 module_param(ar3khcibaud, int, 0644);
193 module_param(hciuartscale, int, 0644);
194 module_param(hciuartstep, int, 0644);
195 #endif
196 #else
197
198 #define __user
199 /* for linux 2.4 and lower */
200 MODULE_PARM(bmienable,"i");
201 MODULE_PARM(wlaninitmode,"i");
202 MODULE_PARM(bypasswmi,"i");
203 MODULE_PARM(debuglevel, "i");
204 MODULE_PARM(onebitmode,"i");
205 MODULE_PARM(busspeedlow, "i");
206 MODULE_PARM(skipflash, "i");
207 MODULE_PARM(wmitimeout, "i");
208 MODULE_PARM(wlanNodeCaching, "i");
209 MODULE_PARM(enableuartprint,"i");
210 MODULE_PARM(logWmiRawMsgs, "i");
211 MODULE_PARM(enabletimerwar,"i");
212 MODULE_PARM(fwmode,"i");
213 MODULE_PARM(mbox_yield_limit,"i");
214 MODULE_PARM(reduce_credit_dribble,"i");
215 MODULE_PARM(allow_trace_signal,"i");
216 MODULE_PARM(enablerssicompensation,"i");
217 MODULE_PARM(processDot11Hdr,"i");
218 #ifdef CONFIG_CHECKSUM_OFFLOAD
219 MODULE_PARM(csumOffload,"i");
220 #endif
221 #ifdef CONFIG_HOST_TCMD_SUPPORT
222 MODULE_PARM(testmode, "i");
223 #endif
224 MODULE_PARM(irqprocmode, "i");
225 MODULE_PARM(nohifscattersupport, "i");
226 MODULE_PARM(panic_on_assert, "i");
227 MODULE_PARM(setuphci, "i");
228 MODULE_PARM(loghci, "i");
229 #endif
230
231 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
232 /* in 2.6.10 and later this is now a pointer to a uint */
233 unsigned int _mboxnum = HTC_MAILBOX_NUM_MAX;
234 #define mboxnum &_mboxnum
235 #else
236 unsigned int mboxnum = HTC_MAILBOX_NUM_MAX;
237 #endif
238
239 #ifdef DEBUG
240 A_UINT32 g_dbg_flags = DBG_DEFAULTS;
241 unsigned int debugflags = 0;
242 int debugdriver = 0;
243 unsigned int debughtc = 0;
244 unsigned int debugbmi = 0;
245 unsigned int debughif = 0;
246 unsigned int txcreditsavailable[HTC_MAILBOX_NUM_MAX] = {0};
247 unsigned int txcreditsconsumed[HTC_MAILBOX_NUM_MAX] = {0};
248 unsigned int txcreditintrenable[HTC_MAILBOX_NUM_MAX] = {0};
249 unsigned int txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX] = {0};
250 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
251 module_param(debugflags, int, 0644);
252 module_param(debugdriver, int, 0644);
253 module_param(debughtc, int, 0644);
254 module_param(debugbmi, int, 0644);
255 module_param(debughif, int, 0644);
256 module_param_array(txcreditsavailable, int, mboxnum, 0644);
257 module_param_array(txcreditsconsumed, int, mboxnum, 0644);
258 module_param_array(txcreditintrenable, int, mboxnum, 0644);
259 module_param_array(txcreditintrenableaggregate, int, mboxnum, 0644);
260 #else
261 /* linux 2.4 and lower */
262 MODULE_PARM(debugflags,"i");
263 MODULE_PARM(debugdriver, "i");
264 MODULE_PARM(debughtc, "i");
265 MODULE_PARM(debugbmi, "i");
266 MODULE_PARM(debughif, "i");
267 MODULE_PARM(txcreditsavailable, "0-3i");
268 MODULE_PARM(txcreditsconsumed, "0-3i");
269 MODULE_PARM(txcreditintrenable, "0-3i");
270 MODULE_PARM(txcreditintrenableaggregate, "0-3i");
271 #endif
272
273 #endif /* DEBUG */
274
275 unsigned int resetok = 1;
276 unsigned int tx_attempt[HTC_MAILBOX_NUM_MAX] = {0};
277 unsigned int tx_post[HTC_MAILBOX_NUM_MAX] = {0};
278 unsigned int tx_complete[HTC_MAILBOX_NUM_MAX] = {0};
279 unsigned int hifBusRequestNumMax = 40;
280 unsigned int war23838_disabled = 0;
281 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
282 unsigned int enableAPTCHeuristics = 1;
283 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
284 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
285 module_param_array(tx_attempt, int, mboxnum, 0644);
286 module_param_array(tx_post, int, mboxnum, 0644);
287 module_param_array(tx_complete, int, mboxnum, 0644);
288 module_param(hifBusRequestNumMax, int, 0644);
289 module_param(war23838_disabled, int, 0644);
290 module_param(resetok, int, 0644);
291 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
292 module_param(enableAPTCHeuristics, int, 0644);
293 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
294 #else
295 MODULE_PARM(tx_attempt, "0-3i");
296 MODULE_PARM(tx_post, "0-3i");
297 MODULE_PARM(tx_complete, "0-3i");
298 MODULE_PARM(hifBusRequestNumMax, "i");
299 MODULE_PARM(war23838_disabled, "i");
300 MODULE_PARM(resetok, "i");
301 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
302 MODULE_PARM(enableAPTCHeuristics, "i");
303 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
304 #endif
305
306 #ifdef BLOCK_TX_PATH_FLAG
307 int blocktx = 0;
308 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
309 module_param(blocktx, int, 0644);
310 #else
311 MODULE_PARM(blocktx, "i");
312 #endif
313 #endif /* BLOCK_TX_PATH_FLAG */
314
315 typedef struct user_rssi_compensation_t {
316 A_UINT16 a_enable;
317 A_INT16 a_param_a;
318 A_INT16 a_param_b;
319 A_UINT16 bg_enable;
320 A_INT16 bg_param_a;
321 A_INT16 bg_param_b;
322 } USER_RSSI_CPENSATION;
323
324 static USER_RSSI_CPENSATION rssi_compensation_param;
325
326 static A_INT16 rssi_compensation_table[96];
327
328 int reconnect_flag = 0;
329
330 /* Function declarations */
331 static int ar6000_init_module(void);
332 static void ar6000_cleanup_module(void);
333
334 int ar6000_init(struct net_device *dev);
335 static int ar6000_open(struct net_device *dev);
336 static int ar6000_close(struct net_device *dev);
337 static void ar6000_init_control_info(AR_SOFTC_T *ar);
338 static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev);
339
340 static void ar6000_destroy(struct net_device *dev, unsigned int unregister);
341 static void ar6000_detect_error(unsigned long ptr);
342 static struct net_device_stats *ar6000_get_stats(struct net_device *dev);
343 static struct iw_statistics *ar6000_get_iwstats(struct net_device * dev);
344
345 static void disconnect_timer_handler(unsigned long ptr);
346
347 void read_rssi_compensation_param(AR_SOFTC_T *ar);
348
349 /*
350 * HTC service connection handlers
351 */
352 static A_STATUS ar6000_avail_ev(void *context, void *hif_handle);
353
354 static A_STATUS ar6000_unavail_ev(void *context, void *hif_handle);
355
356 static void ar6000_target_failure(void *Instance, A_STATUS Status);
357
358 static void ar6000_rx(void *Context, HTC_PACKET *pPacket);
359
360 static void ar6000_rx_refill(void *Context,HTC_ENDPOINT_ID Endpoint);
361
362 static void ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPackets);
363
364 static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, HTC_PACKET *pPac ket);
365
366 #ifdef ATH_AR6K_11N_SUPPORT
367 static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, A_UINT16 num);
368 #endif
369 static void ar6000_deliver_frames_to_nw_stack(void * dev, void *osbuf);
370 //static void ar6000_deliver_frames_to_bt_stack(void * dev, void *osbuf);
371
372 static HTC_PACKET *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpo int, int Length);
373
374 static void ar6000_refill_amsdu_rxbufs(AR_SOFTC_T *ar, int Count);
375
376 static void ar6000_cleanup_amsdu_rxbufs(AR_SOFTC_T *ar);
377
378 static ssize_t
379 ar6000_sysfs_bmi_read(struct kobject *kobj, struct bin_attribute *bin_attr,
380 char *buf, loff_t pos, size_t count);
381
382 static ssize_t
383 ar6000_sysfs_bmi_write(struct kobject *kobj, struct bin_attribute *bin_attr,
384 char *buf, loff_t pos, size_t count);
385
386 static A_STATUS
387 ar6000_sysfs_bmi_init(AR_SOFTC_T *ar);
388
389 static void
390 ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar);
391
392 static A_STATUS
393 ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode);
394
395 /*
396 * Static variables
397 */
398
399 static struct net_device *ar6000_devices[MAX_AR6000];
400 extern struct iw_handler_def ath_iw_handler_def;
401 DECLARE_WAIT_QUEUE_HEAD(arEvent);
402 static void ar6000_cookie_init(AR_SOFTC_T *ar);
403 static void ar6000_cookie_cleanup(AR_SOFTC_T *ar);
404 static void ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie);
405 static struct ar_cookie *ar6000_alloc_cookie(AR_SOFTC_T *ar);
406
407 #ifdef USER_KEYS
408 static A_STATUS ar6000_reinstall_keys(AR_SOFTC_T *ar,A_UINT8 key_op_ctrl);
409 #endif
410
411
412 static struct ar_cookie s_ar_cookie_mem[MAX_COOKIE_NUM];
413
414 #define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
415 (((ar)->arTargetType == TARGET_TYPE_AR6001) ? AR6001_HOST_INTEREST_ITEM_ ADDRESS(item) : \
416 (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ ADDRESS(item) : \
417 (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ ADDRESS(item) : 0)))
418
419
420 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
421 static struct net_device_ops ar6000_netdev_ops = {
422 .ndo_init = NULL,
423 .ndo_open = ar6000_open,
424 .ndo_stop = ar6000_close,
425 .ndo_get_stats = ar6000_get_stats,
426 .ndo_do_ioctl = ar6000_ioctl,
427 .ndo_start_xmit = ar6000_data_tx,
428 };
429 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) */
430
431 /* Debug log support */
432
433 /*
434 * Flag to govern whether the debug logs should be parsed in the kernel
435 * or reported to the application.
436 */
437 #define REPORT_DEBUG_LOGS_TO_APP
438
439 A_STATUS
440 ar6000_set_host_app_area(AR_SOFTC_T *ar)
441 {
442 A_UINT32 address, data;
443 struct host_app_area_s host_app_area;
444
445 /* Fetch the address of the host_app_area_s instance in the host interest ar ea */
446 address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_ host_interest));
447 if (ar6000_ReadRegDiag(ar->arHifDevice, &address, &data) != A_OK) {
448 return A_ERROR;
449 }
450 address = TARG_VTOP(ar->arTargetType, data);
451 host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION;
452 if (ar6000_WriteDataDiag(ar->arHifDevice, address,
453 (A_UCHAR *)&host_app_area,
454 sizeof(struct host_app_area_s)) != A_OK)
455 {
456 return A_ERROR;
457 }
458
459 return A_OK;
460 }
461
462 A_UINT32
463 dbglog_get_debug_hdr_ptr(AR_SOFTC_T *ar)
464 {
465 A_UINT32 param;
466 A_UINT32 address;
467 A_STATUS status;
468
469 address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbgl og_hdr));
470 if ((status = ar6000_ReadDataDiag(ar->arHifDevice, address,
471 (A_UCHAR *)&param, 4)) != A_OK)
472 {
473 param = 0;
474 }
475
476 return param;
477 }
478
479 /*
480 * The dbglog module has been initialized. Its ok to access the relevant
481 * data stuctures over the diagnostic window.
482 */
483 void
484 ar6000_dbglog_init_done(AR_SOFTC_T *ar)
485 {
486 ar->dbglog_init_done = TRUE;
487 }
488
489 A_UINT32
490 dbglog_get_debug_fragment(A_INT8 *datap, A_UINT32 len, A_UINT32 limit)
491 {
492 A_INT32 *buffer;
493 A_UINT32 count;
494 A_UINT32 numargs;
495 A_UINT32 length;
496 A_UINT32 fraglen;
497
498 count = fraglen = 0;
499 buffer = (A_INT32 *)datap;
500 length = (limit >> 2);
501
502 if (len <= limit) {
503 fraglen = len;
504 } else {
505 while (count < length) {
506 numargs = DBGLOG_GET_NUMARGS(buffer[count]);
507 fraglen = (count << 2);
508 count += numargs + 1;
509 }
510 }
511
512 return fraglen;
513 }
514
515 void
516 dbglog_parse_debug_logs(A_INT8 *datap, A_UINT32 len)
517 {
518 A_INT32 *buffer;
519 A_UINT32 count;
520 A_UINT32 timestamp;
521 A_UINT32 debugid;
522 A_UINT32 moduleid;
523 A_UINT32 numargs;
524 A_UINT32 length;
525
526 count = 0;
527 buffer = (A_INT32 *)datap;
528 length = (len >> 2);
529 while (count < length) {
530 debugid = DBGLOG_GET_DBGID(buffer[count]);
531 moduleid = DBGLOG_GET_MODULEID(buffer[count]);
532 numargs = DBGLOG_GET_NUMARGS(buffer[count]);
533 timestamp = DBGLOG_GET_TIMESTAMP(buffer[count]);
534 switch (numargs) {
535 case 0:
536 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d)\n", moduleid, debugid , timestamp));
537 break;
538
539 case 1:
540 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x\n", moduleid, d ebugid,
541 timestamp, buffer[count+1]));
542 break;
543
544 case 2:
545 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x, 0x%x\n", modul eid, debugid,
546 timestamp, buffer[count+1], buffer[count+2]));
547 break;
548
549 default:
550 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid args: %d\n", numargs));
551 }
552 count += numargs + 1;
553 }
554 }
555
556 int
557 ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar)
558 {
559 struct dbglog_hdr_s debug_hdr;
560 struct dbglog_buf_s debug_buf;
561 A_UINT32 address;
562 A_UINT32 length;
563 A_UINT32 dropped;
564 A_UINT32 firstbuf;
565 A_UINT32 debug_hdr_ptr;
566
567 if (!ar->dbglog_init_done) return A_ERROR;
568
569
570 AR6000_SPIN_LOCK(&ar->arLock, 0);
571
572 if (ar->dbgLogFetchInProgress) {
573 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
574 return A_EBUSY;
575 }
576
577 /* block out others */
578 ar->dbgLogFetchInProgress = TRUE;
579
580 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
581
582 debug_hdr_ptr = dbglog_get_debug_hdr_ptr(ar);
583 printk("debug_hdr_ptr: 0x%x\n", debug_hdr_ptr);
584
585 /* Get the contents of the ring buffer */
586 if (debug_hdr_ptr) {
587 address = TARG_VTOP(ar->arTargetType, debug_hdr_ptr);
588 length = sizeof(struct dbglog_hdr_s);
589 ar6000_ReadDataDiag(ar->arHifDevice, address,
590 (A_UCHAR *)&debug_hdr, length);
591 address = TARG_VTOP(ar->arTargetType, (A_UINT32)debug_hdr.dbuf);
592 firstbuf = address;
593 dropped = debug_hdr.dropped;
594 length = sizeof(struct dbglog_buf_s);
595 ar6000_ReadDataDiag(ar->arHifDevice, address,
596 (A_UCHAR *)&debug_buf, length);
597
598 do {
599 address = TARG_VTOP(ar->arTargetType, (A_UINT32)debug_buf.buffer);
600 length = debug_buf.length;
601 if ((length) && (debug_buf.length <= debug_buf.bufsize)) {
602 /* Rewind the index if it is about to overrun the buffer */
603 if (ar->log_cnt > (DBGLOG_HOST_LOG_BUFFER_SIZE - length)) {
604 ar->log_cnt = 0;
605 }
606 if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address,
607 (A_UCHAR *)&ar->log_buffer[ar->log_cnt], len gth))
608 {
609 break;
610 }
611 ar6000_dbglog_event(ar, dropped, &ar->log_buffer[ar->log_cnt], l ength);
612 ar->log_cnt += length;
613 } else {
614 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("Length: %d (Total size: %d)\ n",
615 debug_buf.length, debug_buf.bufsize));
616 }
617
618 address = TARG_VTOP(ar->arTargetType, (A_UINT32)debug_buf.next);
619 length = sizeof(struct dbglog_buf_s);
620 if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address,
621 (A_UCHAR *)&debug_buf, length))
622 {
623 break;
624 }
625
626 } while (address != firstbuf);
627 }
628
629 ar->dbgLogFetchInProgress = FALSE;
630
631 return A_OK;
632 }
633
634 void
635 ar6000_dbglog_event(AR_SOFTC_T *ar, A_UINT32 dropped,
636 A_INT8 *buffer, A_UINT32 length)
637 {
638 #ifdef REPORT_DEBUG_LOGS_TO_APP
639 #define MAX_WIRELESS_EVENT_SIZE 252
640 /*
641 * Break it up into chunks of MAX_WIRELESS_EVENT_SIZE bytes of messages.
642 * There seems to be a limitation on the length of message that could be
643 * transmitted to the user app via this mechanism.
644 */
645 A_UINT32 send, sent;
646
647 sent = 0;
648 send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
649 MAX_WIRELESS_EVENT_SIZE);
650 while (send) {
651 ar6000_send_event_to_app(ar, WMIX_DBGLOG_EVENTID, &buffer[sent], send);
652 sent += send;
653 send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
654 MAX_WIRELESS_EVENT_SIZE);
655 }
656 #else
657 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Dropped logs: 0x%x\nDebug info length: %d\n" ,
658 dropped, length));
659
660 /* Interpret the debug logs */
661 dbglog_parse_debug_logs(buffer, length);
662 #endif /* REPORT_DEBUG_LOGS_TO_APP */
663 }
664
665
666 static int __init
667 ar6000_init_module(void)
668 {
669 static int probed = 0;
670 A_STATUS status;
671 OSDRV_CALLBACKS osdrvCallbacks;
672
673 a_module_debug_support_init();
674
675 #ifdef DEBUG
676 /* check for debug mask overrides */
677 if (debughtc != 0) {
678 ATH_DEBUG_SET_DEBUG_MASK(htc,debughtc);
679 }
680 if (debugbmi != 0) {
681 ATH_DEBUG_SET_DEBUG_MASK(bmi,debugbmi);
682 }
683 if (debughif != 0) {
684 ATH_DEBUG_SET_DEBUG_MASK(hif,debughif);
685 }
686 if (debugdriver != 0) {
687 ATH_DEBUG_SET_DEBUG_MASK(driver,debugdriver);
688 }
689
690 #endif
691
692 A_REGISTER_MODULE_DEBUG_INFO(driver);
693
694 A_MEMZERO(&osdrvCallbacks,sizeof(osdrvCallbacks));
695 osdrvCallbacks.deviceInsertedHandler = ar6000_avail_ev;
696 osdrvCallbacks.deviceRemovedHandler = ar6000_unavail_ev;
697
698 #ifdef DEBUG
699 /* Set the debug flags if specified at load time */
700 if(debugflags != 0)
701 {
702 g_dbg_flags = debugflags;
703 }
704 #endif
705
706 if (probed) {
707 return -ENODEV;
708 }
709 probed++;
710
711 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
712 memset(&aptcTR, 0, sizeof(APTC_TRAFFIC_RECORD));
713 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
714
715 #ifdef CONFIG_HOST_GPIO_SUPPORT
716 ar6000_gpio_init();
717 #endif /* CONFIG_HOST_GPIO_SUPPORT */
718
719 status = HIFInit(&osdrvCallbacks);
720 if(status != A_OK)
721 return -ENODEV;
722
723 return 0;
724 }
725
726 static void __exit
727 ar6000_cleanup_module(void)
728 {
729 int i = 0;
730 struct net_device *ar6000_netdev;
731
732 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
733 /* Delete the Adaptive Power Control timer */
734 if (timer_pending(&aptcTimer)) {
735 del_timer_sync(&aptcTimer);
736 }
737 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
738
739 for (i=0; i < MAX_AR6000; i++) {
740 if (ar6000_devices[i] != NULL) {
741 ar6000_netdev = ar6000_devices[i];
742 ar6000_devices[i] = NULL;
743 ar6000_destroy(ar6000_netdev, 1);
744 }
745 }
746
747 HIFShutDownDevice(NULL);
748
749 a_module_debug_support_cleanup();
750
751 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_cleanup: success\n"));
752 }
753
754 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
755 void
756 aptcTimerHandler(unsigned long arg)
757 {
758 A_UINT32 numbytes;
759 A_UINT32 throughput;
760 AR_SOFTC_T *ar;
761 A_STATUS status;
762
763 ar = (AR_SOFTC_T *)arg;
764 A_ASSERT(ar != NULL);
765 A_ASSERT(!timer_pending(&aptcTimer));
766
767 AR6000_SPIN_LOCK(&ar->arLock, 0);
768
769 /* Get the number of bytes transferred */
770 numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
771 aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
772
773 /* Calculate and decide based on throughput thresholds */
774 throughput = ((numbytes * 8)/APTC_TRAFFIC_SAMPLING_INTERVAL); /* Kbps */
775 if (throughput < APTC_LOWER_THROUGHPUT_THRESHOLD) {
776 /* Enable Sleep and delete the timer */
777 A_ASSERT(ar->arWmiReady == TRUE);
778 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
779 status = wmi_powermode_cmd(ar->arWmi, REC_POWER);
780 AR6000_SPIN_LOCK(&ar->arLock, 0);
781 A_ASSERT(status == A_OK);
782 aptcTR.timerScheduled = FALSE;
783 } else {
784 A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
785 }
786
787 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
788 }
789 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
790
791 /* ATHENV */
792 #ifdef ANDROID_ENV
793 extern void eeprom_ar6000_transfer(HIF_DEVICE *device, char *fake_file);
794 #endif
795 /* ATHENV */
796
797 /* ATHENV */
798 #ifdef ANDROID_ENV
799
800 #define MAX_BUF (8*1024)
801 #define A_ROUND_UP(x, y) ((((x)+((y)-1))/(y))*(y))
802
803 char * fw_buf;
804 static void firmware_transfer(HIF_DEVICE *device, char* filename, A_UINT32 addre ss, A_BOOL isCompressed)
805 {
806 struct file *filp;
807 struct inode *inode = NULL;
808 int length, remaining;
809 int length1;
810 A_STATUS ret;
811 mm_segment_t oldfs;
812
813
814 printk("%s: Enter, filename=%s\n", __FUNCTION__, filename);
815
816 // Open file
817 oldfs = get_fs();
818 set_fs(KERNEL_DS);
819
820 filp = filp_open(filename, O_RDONLY, S_IRUSR);
821 if ( IS_ERR(filp) ) {
822 printk("%s: file %s filp_open error\n", __FUNCTION__, filename);
823 return;
824 }
825 if (!filp->f_op) {
826 printk("%s: File Operation Method Error\n", __FUNCTION__);
827 return;
828 }
829 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
830 inode = filp->f_path.dentry->d_inode;
831 #else
832 inode = filp->f_dentry->d_inode;
833 #endif
834
835 if (!inode) {
836 printk("%s: Get inode from filp failed\n", __FUNCTION__);
837 filp_close(filp, NULL);
838 return;
839 }
840
841 printk("%s file offset opsition: %xh\n", __FUNCTION__, (unsigned)filp->f_pos );
842
843 fw_buf = (char*)kmalloc((MAX_BUF+12), GFP_KERNEL);
844 if (fw_buf==NULL) {
845 printk("%s: kernel memory alloc error\n", __FUNCTION__);
846 filp_close(filp, NULL);
847 return;
848 }
849
850 length = i_size_read(inode->i_mapping->host);
851 if (length==0 ) {
852 printk("%s: Try to get file size error\n", __FUNCTION__);
853 goto Transfer_DONE;
854 }
855 printk("%s: length=%d, address=0x%x\n", __FUNCTION__, length, address);
856
857 if ( isCompressed) {
858 ret = BMILZStreamStart(device, address);
859 if (ret != A_OK) {
860 printk("%s: BMILZStreamStart failed, ret=%d\n", __FUNCTION__, ret);
861 goto Transfer_DONE;
862 }
863 }
864
865 remaining = length;
866
867 while (remaining>0) {
868 length = (remaining > MAX_BUF)? MAX_BUF : remaining;
869
870 if ( isCompressed ) {
871 ((A_UINT32 *)fw_buf)[((length-1)/4)] = 0;
872 }
873
874 if (filp->f_op->read(filp, fw_buf, length, &filp->f_pos) != length) {
875 printk("%s: file read error, remaining=%d\n", __FUNCTION__, remaining);
876 goto Transfer_DONE;
877 }
878
879 length1 = A_ROUND_UP(length, 4);
880
881 if ( isCompressed ) {
882 printk("%s: BMILZData: len=%d, org_len=%d\n", __FUNCTION__, length1, length);
883 ret = BMILZData(device, fw_buf, length1);
884 if (ret != A_OK) {
885 printk("%s: BMILZData failed, ret=%d\n", __FUNCTION__, ret);
886 goto Transfer_DONE;
887 }
888 } else {
889 ret = BMIWriteMemory(device, address, fw_buf, length1);
890 if (ret != A_OK) {
891 printk("%s: BMIWriteMemory failed, ret=%d\n", __FUNCTION__, ret);
892 goto Transfer_DONE;
893 }
894 }
895
896 remaining -= length;
897 address += length;
898 }
899
900 Transfer_DONE:
901 kfree(fw_buf);
902 filp_close(filp, NULL);
903 set_fs(oldfs);
904 }
905
906 #endif
907 /* ATHENV */
908
909 #ifdef ATH_AR6K_11N_SUPPORT
910 static void
911 ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, A_UINT16 num)
912 {
913 void * osbuf;
914
915 while(num) {
916 if((osbuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE))) {
917 A_NETBUF_ENQUEUE(q, osbuf);
918 } else {
919 break;
920 }
921 num--;
922 }
923
924 if(num) {
925 A_PRINTF("%s(), allocation of netbuf failed", __func__);
926 }
927 }
928 #endif
929
930 static struct bin_attribute bmi_attr = {
931 .attr = {.name = "bmi", .mode = 0600},
932 .read = ar6000_sysfs_bmi_read,
933 .write = ar6000_sysfs_bmi_write,
934 };
935
936 static ssize_t
937 ar6000_sysfs_bmi_read(struct kobject *kobj, struct bin_attribute *bin_attr,
938 char *buf, loff_t pos, size_t count)
939 {
940 int index;
941 AR_SOFTC_T *ar;
942 HIF_DEVICE_OS_DEVICE_INFO *osDevInfo;
943
944 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Read %d bytes\n", count));
945 for (index=0; index < MAX_AR6000; index++) {
946 ar = (AR_SOFTC_T *)ar6k_priv(ar6000_devices[index]);
947 osDevInfo = &ar->osDevInfo;
948 if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) {
949 break;
950 }
951 }
952
953 if (index == MAX_AR6000) return 0;
954
955 if ((BMIRawRead(ar->arHifDevice, buf, count, TRUE)) != A_OK) {
956 return 0;
957 }
958
959 return count;
960 }
961
962 static ssize_t
963 ar6000_sysfs_bmi_write(struct kobject *kobj, struct bin_attribute *bin_attr,
964 char *buf, loff_t pos, size_t count)
965 {
966 int index;
967 AR_SOFTC_T *ar;
968 HIF_DEVICE_OS_DEVICE_INFO *osDevInfo;
969
970 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Write %d bytes\n", count));
971 for (index=0; index < MAX_AR6000; index++) {
972 ar = (AR_SOFTC_T *)ar6k_priv(ar6000_devices[index]);
973 osDevInfo = &ar->osDevInfo;
974 if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) {
975 break;
976 }
977 }
978
979 if (index == MAX_AR6000) return 0;
980
981 if ((BMIRawWrite(ar->arHifDevice, buf, count)) != A_OK) {
982 return 0;
983 }
984
985 return count;
986 }
987
988 static A_STATUS
989 ar6000_sysfs_bmi_init(AR_SOFTC_T *ar)
990 {
991 A_STATUS status;
992
993 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Creating sysfs entry\n"));
994 A_MEMZERO(&ar->osDevInfo, sizeof(HIF_DEVICE_OS_DEVICE_INFO));
995
996 /* Get the underlying OS device */
997 status = HIFConfigureDevice(ar->arHifDevice,
998 HIF_DEVICE_GET_OS_DEVICE,
999 &ar->osDevInfo,
1000 sizeof(HIF_DEVICE_OS_DEVICE_INFO));
1001
1002 if (A_FAILED(status)) {
1003 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failed to get OS device info from HIF\n"));
1004 return A_ERROR;
1005 }
1006
1007 /* Create a bmi entry in the sysfs filesystem */
1008 if ((sysfs_create_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kob j), &bmi_attr)) < 0)
1009 {
1010 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to create entry for bmi in s ysfs filesystem\n"));
1011 return A_ERROR;
1012 }
1013
1014 return A_OK;
1015 }
1016
1017 static void
1018 ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar)
1019 {
1020 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Deleting sysfs entry\n"));
1021
1022 sysfs_remove_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), & bmi_attr);
1023 }
1024
1025 #define bmifn(fn) do { \
1026 if ((fn) < A_OK) { \
1027 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)) ; \
1028 return A_ERROR; \
1029 } \
1030 } while(0)
1031
1032 static A_STATUS
1033 ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode)
1034 {
1035 const struct firmware *fw_entry;
1036
1037 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Requesting User Space Config\n"));
1038
1039 if (mode == WLAN_INIT_MODE_UDEV) {
1040 /* Get config using udev through a script in user space */
1041 if ((request_firmware(&fw_entry, AR6003_HW10_CONFIG, ((struct device *)a r->osDevInfo.pOSDevice))) != 0)
1042 {
1043 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failure to get %s\n", AR6003_H W10_CONFIG));
1044 return A_ERROR;
1045 }
1046
1047 release_firmware(fw_entry);
1048 #ifdef INIT_MODE_DRV_ENABLED
1049 } else {
1050 /* The config is compiled into the driver itself */
1051 A_UINT32 param, options, sleep, address;
1052
1053 /* Temporarily disable system sleep */
1054 address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1055 bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1056 options = param;
1057 param |= AR6K_OPTION_SLEEP_DISABLE;
1058 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1059
1060 address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1061 bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1062 sleep = param;
1063 param |= WLAN_SYSTEM_SLEEP_DISABLE_SET(1);
1064 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1065 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("old options: %d, old sleep: %d\n", opt ions, sleep));
1066
1067 /* Run at 80/88MHz by default */
1068 address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
1069 param = CPU_CLOCK_STANDARD_SET(1);
1070 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1071
1072 /* LPO_CAL.ENABLE = 1 */
1073 address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
1074 param = LPO_CAL_ENABLE_SET(1);
1075 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1076
1077 /* Transfer Board Data from Target EEPROM to Target RAM */
1078 /* Determine where in Target RAM to write Board Data */
1079 bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_b oard_data), (A_UCHAR *)&param, 4));
1080 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board Data download address: 0x%x\n", param));
1081
1082 /* Write EEPROM data to Target RAM */
1083 if ((request_firmware(&fw_entry, AR6K_BOARD_DATA_FILE, ((struct device * )ar->osDevInfo.pOSDevice))) != 0)
1084 {
1085 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failure to get %s\n", AR6K_BOA RD_DATA_FILE));
1086 return A_ERROR;
1087 }
1088
1089 if ((BMIWriteMemory(ar->arHifDevice, param, (A_UCHAR *)fw_entry->data, f w_entry->size)) < A_OK)
1090 {
1091 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE __)); \
1092 release_firmware(fw_entry);
1093 return A_ERROR;
1094 }
1095 release_firmware(fw_entry);
1096
1097 /* Record the fact that Board Data IS initialized */
1098 param = 1;
1099 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ board_data_initialized), (A_UCHAR *)&param, 4));
1100
1101 /* Transfer One time Programmable data */
1102 /* Data segment */
1103 if ((request_firmware(&fw_entry, AR6K_OTP_DATA_FILE, ((struct device *)a r->osDevInfo.pOSDevice))) != 0)
1104 {
1105 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failure to get %s\n", AR6K_OTP _DATA_FILE));
1106 return A_ERROR;
1107 }
1108 param = DATA_DOWNLOAD_ADDRESS;
1109 if ((BMIWriteMemory(ar->arHifDevice, param, (A_UCHAR *)fw_entry->data, f w_entry->size)) < A_OK)
1110 {
1111 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE __)); \
1112 release_firmware(fw_entry);
1113 return A_ERROR;
1114 }
1115 release_firmware(fw_entry);
1116
1117 /* Code segment */
1118 if ((request_firmware(&fw_entry, AR6K_OTP_BIN_FILE, ((struct device *)ar ->osDevInfo.pOSDevice))) != 0)
1119 {
1120 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failure to get %s\n", AR6K_OTP _BIN_FILE));
1121 return A_ERROR;
1122 }
1123 param = ((AR6003_REV1_APP_START_OVERRIDE & 0x7FFFFF) | 0x400000);
1124 if ((BMIWriteMemory(ar->arHifDevice, param, (A_UCHAR *)fw_entry->data, f w_entry->size)) < A_OK)
1125 {
1126 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE __)); \
1127 release_firmware(fw_entry);
1128 return A_ERROR;
1129 }
1130 release_firmware(fw_entry);
1131
1132 /* Execute the OTP code */
1133 param = 0;
1134 bmifn(BMIExecute(ar->arHifDevice, AR6003_REV1_APP_START_OVERRIDE, &param ));
1135
1136 /* Download Target firmware */
1137 if ((request_firmware(&fw_entry, AR6K_FIRMWARE_FILE, ((struct device *)a r->osDevInfo.pOSDevice))) != 0)
1138 {
1139 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failure to get %s\n", AR6K_FIR MWARE_FILE));
1140 return A_ERROR;
1141 }
1142 param = DATA_DOWNLOAD_ADDRESS;
1143 if ((BMIFastDownload(ar->arHifDevice, param, (A_UCHAR *)fw_entry->data, fw_entry->size)) < A_OK)
1144 {
1145 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE __)); \
1146 release_firmware(fw_entry);
1147 return A_ERROR;
1148 }
1149 release_firmware(fw_entry);
1150
1151 /* Set starting address for firmware */
1152 bmifn(BMISetAppStart(ar->arHifDevice, AR6003_REV1_APP_START_OVERRIDE));
1153
1154 /* Reserve 5.5K of RAM */
1155 param = 5632;
1156 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ end_RAM_reserve_sz), (A_UCHAR *)&param, 4));
1157
1158 /* Apply the patches */
1159 if ((request_firmware(&fw_entry, AR6K_PATCH_FILE, ((struct device *)ar-> osDevInfo.pOSDevice))) != 0)
1160 {
1161 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failure to get %s\n", AR6K_PAT CH_FILE));
1162 return A_ERROR;
1163 }
1164 param = PATCH_DOWNLOAD_ADDRESS;
1165 if ((BMIWriteMemory(ar->arHifDevice, param, (A_UCHAR *)fw_entry->data, f w_entry->size)) < A_OK)
1166 {
1167 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE __)); \
1168 release_firmware(fw_entry);
1169 return A_ERROR;
1170 }
1171 release_firmware(fw_entry);
1172 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ dset_list_head), (A_UCHAR *)&param, 4));
1173
1174 /* Restore system sleep */
1175 address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1176 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, sleep));
1177
1178 address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1179 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, options));
1180
1181 /* Configure GPIO AR6003 UART */
1182 param = 8;
1183 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ dbg_uart_txpin), (A_UCHAR *)&param, 4));
1184
1185 /* Tell Target to execute loaded firmware */
1186 bmifn(BMIDone(ar->arHifDevice));
1187 #endif /* INIT_MODE_DRV_ENABLED */
1188 }
1189
1190 return A_OK;
1191 }
1192
1193 /*
1194 * HTC Event handlers
1195 */
1196 static A_STATUS
1197 ar6000_avail_ev(void *context, void *hif_handle)
1198 {
1199 int i;
1200 struct net_device *dev;
1201 void *ar_netif;
1202 AR_SOFTC_T *ar;
1203 int device_index = 0;
1204 A_UINT32 param;
1205 HTC_INIT_INFO htcInfo;
1206 #ifdef CONFIG_CFG80211
1207 struct wireless_dev *wdev;
1208 #endif /* CONFIG_CFG80211 */
1209
1210 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_available\n"));
1211
1212 for (i=0; i < MAX_AR6000; i++) {
1213 if (ar6000_devices[i] == NULL) {
1214 break;
1215 }
1216 }
1217
1218 if (i == MAX_AR6000) {
1219 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_available: max devices reached\n" ));
1220 return A_ERROR;
1221 }
1222
1223 /* Save this. It gives a bit better readability especially since */
1224 /* we use another local "i" variable below. */
1225 device_index = i;
1226
1227 #ifdef CONFIG_CFG80211
1228 wdev = ar6k_cfg80211_init(NULL);
1229 if (IS_ERR(wdev)) {
1230 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ar6k_cfg80211_init failed\n", __fun c__));
1231 return A_ERROR;
1232 }
1233 ar_netif = wdev_priv(wdev);
1234 #else
1235 dev = alloc_etherdev(sizeof(AR_SOFTC_T));
1236 if (dev == NULL) {
1237 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_available: can't alloc etherdev\n "));
1238 return A_ERROR;
1239 }
1240 ether_setup(dev);
1241 ar_netif = ar6k_priv(dev);
1242 #endif /* CONFIG_CFG80211 */
1243
1244 if (ar_netif == NULL) {
1245 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Can't allocate ar6k priv memory\n", __func__));
1246 return A_ERROR;
1247 }
1248
1249 A_MEMZERO(ar_netif, sizeof(AR_SOFTC_T));
1250 ar = (AR_SOFTC_T *)ar_netif;
1251
1252 #ifdef CONFIG_CFG80211
1253 ar->wdev = wdev;
1254 wdev->iftype = NL80211_IFTYPE_STATION;
1255
1256 dev = alloc_netdev_mq(0, "wlan%d", ether_setup, 5);//IWM_TX_QUEUES);
1257 if (!dev) {
1258 printk(KERN_CRIT "AR6K: no memory for network device instance\n");
1259 ar6k_cfg80211_deinit(ar);
1260 return A_ERROR;
1261 }
1262
1263 dev->ieee80211_ptr = wdev;
1264 SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
1265 wdev->netdev = dev;
1266 ar->arNetworkType = INFRA_NETWORK;
1267 #endif /* CONFIG_CFG80211 */
1268
1269 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
1270 if (ifname[0])
1271 {
1272 strcpy(dev->name, ifname);
1273 }
1274 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
1275
1276 #ifdef SET_MODULE_OWNER
1277 SET_MODULE_OWNER(dev);
1278 #endif
1279
1280 ar->arNetDev = dev;
1281 ar->arHifDevice = hif_handle;
1282 ar->arWlanState = WLAN_ENABLED;
1283 ar->arDeviceIndex = device_index;
1284
1285 A_INIT_TIMER(&ar->arHBChallengeResp.timer, ar6000_detect_error, dev);
1286 ar->arHBChallengeResp.seqNum = 0;
1287 ar->arHBChallengeResp.outstanding = FALSE;
1288 ar->arHBChallengeResp.missCnt = 0;
1289 ar->arHBChallengeResp.frequency = AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT;
1290 ar->arHBChallengeResp.missThres = AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAUL T;
1291
1292 ar6000_init_control_info(ar);
1293 init_waitqueue_head(&arEvent);
1294 sema_init(&ar->arSem, 1);
1295 ar->bIsDestroyProgress = FALSE;
1296
1297 INIT_HTC_PACKET_QUEUE(&ar->amsdu_rx_buffer_queue);
1298
1299 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1300 A_INIT_TIMER(&aptcTimer, aptcTimerHandler, ar);
1301 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1302
1303 A_INIT_TIMER(&ar->disconnect_timer, disconnect_timer_handler, dev);
1304
1305 /*
1306 * If requested, perform some magic which requires no cooperation from
1307 * the Target. It causes the Target to ignore flash and execute to the
1308 * OS from ROM.
1309 *
1310 * This is intended to support recovery from a corrupted flash on Targets
1311 * that support flash.
1312 */
1313 if (skipflash)
1314 {
1315 //ar6000_reset_device_skipflash(ar->arHifDevice);
1316 }
1317
1318 BMIInit();
1319
1320 if (bmienable) {
1321 ar6000_sysfs_bmi_init(ar);
1322 }
1323
1324 {
1325 struct bmi_target_info targ_info;
1326
1327 if (BMIGetTargetInfo(ar->arHifDevice, &targ_info) != A_OK) {
1328 return A_ERROR;
1329 }
1330
1331 ar->arVersion.target_ver = targ_info.target_ver;
1332 ar->arTargetType = targ_info.target_type;
1333
1334 /* do any target-specific preparation that can be done through BMI * /
1335 if (ar6000_prepare_target(ar->arHifDevice,
1336 targ_info.target_type,
1337 targ_info.target_ver) != A_OK) {
1338 return A_ERROR;
1339 }
1340
1341 }
1342
1343 if (enableuartprint) {
1344 param = 1;
1345 if (BMIWriteMemory(ar->arHifDevice,
1346 HOST_INTEREST_ITEM_ADDRESS(ar, hi_serial_enable),
1347 (A_UCHAR *)&param,
1348 4)!= A_OK)
1349 {
1350 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enableuartprint failed \n"));
1351 return A_ERROR;
1352 }
1353 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Serial console prints enabled\n"));
1354 }
1355
1356 /* Tell target which HTC version it is used*/
1357 param = HTC_PROTOCOL_VERSION;
1358 if (BMIWriteMemory(ar->arHifDevice,
1359 HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest),
1360 (A_UCHAR *)&param,
1361 4)!= A_OK)
1362 {
1363 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for htc version failed \ n"));
1364 return A_ERROR;
1365 }
1366
1367 #ifdef CONFIG_HOST_TCMD_SUPPORT
1368 if(testmode) {
1369 ar->arTargetMode = AR6000_TCMD_MODE;
1370 }else {
1371 ar->arTargetMode = AR6000_WLAN_MODE;
1372 }
1373 #endif
1374 if (enabletimerwar) {
1375 A_UINT32 param;
1376
1377 if (BMIReadMemory(ar->arHifDevice,
1378 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1379 (A_UCHAR *)&param,
1380 4)!= A_OK)
1381 {
1382 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for enabletimerwar fai led \n"));
1383 return A_ERROR;
1384 }
1385
1386 param |= HI_OPTION_TIMER_WAR;
1387
1388 if (BMIWriteMemory(ar->arHifDevice,
1389 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1390 (A_UCHAR *)&param,
1391 4) != A_OK)
1392 {
1393 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enabletimerwar fa iled \n"));
1394 return A_ERROR;
1395 }
1396 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Timer WAR enabled\n"));
1397 }
1398
1399 /* set the firmware mode to STA/IBSS/AP */
1400 {
1401 A_UINT32 param;
1402
1403 if (BMIReadMemory(ar->arHifDevice,
1404 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1405 (A_UCHAR *)&param,
1406 4)!= A_OK)
1407 {
1408 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for setting fwmode fai led \n"));
1409 return A_ERROR;
1410 }
1411
1412 param |= (fwmode << HI_OPTION_FW_MODE_SHIFT);
1413
1414 if (BMIWriteMemory(ar->arHifDevice,
1415 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1416 (A_UCHAR *)&param,
1417 4) != A_OK)
1418 {
1419 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for setting fwmode fa iled \n"));
1420 return A_ERROR;
1421 }
1422 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n"));
1423 }
1424 #if 0 /* HOST_INTEREST is no longer used to configure dot11 processing rule */
1425 if (processDot11Hdr) {
1426 A_UINT32 param;
1427
1428 if (BMIReadMemory(ar->arHifDevice,
1429 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1430 (A_UCHAR *)&param,
1431 4)!= A_OK)
1432 {
1433 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for processDot11Hdr fa iled \n"));
1434 return A_ERROR;
1435 }
1436
1437 param |= HI_OPTION_RELAY_DOT11_HDR;
1438
1439 if (BMIWriteMemory(ar->arHifDevice,
1440 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1441 (A_UCHAR *)&param,
1442 4) != A_OK)
1443 {
1444 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for processDot11Hdr f ailed \n"));
1445 return A_ERROR;
1446 }
1447 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("processDot11Hdr enabled\n"));
1448 }
1449 #endif
1450
1451 // No need to reserve RAM space for patch as AR6001 is flash based
1452 if (ar->arTargetType == TARGET_TYPE_AR6001) {
1453 param = 0;
1454 if (BMIWriteMemory(ar->arHifDevice,
1455 HOST_INTEREST_ITEM_ADDRESS(ar, hi_end_RAM_reserve_sz),
1456 (A_UCHAR *)&param,
1457 4) != A_OK)
1458 {
1459 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for hi_end_RAM_reserv e_sz failed \n"));
1460 return A_ERROR;
1461 }
1462 }
1463
1464
1465 /* since BMIInit is called in the driver layer, we have to set the block
1466 * size here for the target */
1467
1468 if (A_FAILED(ar6000_set_htc_params(ar->arHifDevice,
1469 ar->arTargetType,
1470 mbox_yield_limit,
1471 0 /* use default number of control buffer s */
1472 ))) {
1473 return A_ERROR;
1474 }
1475
1476 if (setupbtdev != 0) {
1477 if (A_FAILED(ar6000_set_hci_bridge_flags(ar->arHifDevice,
1478 ar->arTargetType,
1479 setupbtdev))) {
1480 return A_ERROR;
1481 }
1482 }
1483
1484 A_MEMZERO(&htcInfo,sizeof(htcInfo));
1485 htcInfo.pContext = ar;
1486 htcInfo.TargetFailure = ar6000_target_failure;
1487
1488 ar->arHtcTarget = HTCCreate(ar->arHifDevice,&htcInfo);
1489
1490 if (ar->arHtcTarget == NULL) {
1491 return A_ERROR;
1492 }
1493
1494 spin_lock_init(&ar->arLock);
1495
1496 #ifdef WAPI_ENABLE
1497 ar->arWapiEnable = 0;
1498 #endif
1499
1500 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
1501 dev->open = &ar6000_open;
1502 dev->stop = &ar6000_close;
1503 dev->hard_start_xmit = &ar6000_data_tx;
1504 dev->get_stats = &ar6000_get_stats;
1505
1506 /* dev->tx_timeout = ar6000_tx_timeout; */
1507 dev->do_ioctl = &ar6000_ioctl;
1508 #else
1509 dev->netdev_ops = &ar6000_netdev_ops;
1510 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) */
1511 dev->watchdog_timeo = AR6000_TX_TIMEOUT;
1512 dev->wireless_handlers = &ath_iw_handler_def;
1513
1514 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
1515 dev->get_wireless_stats = ar6000_get_iwstats; /*Displayed via proc fs */
1516 #else
1517 ath_iw_handler_def.get_wireless_stats = ar6000_get_iwstats; /*Displayed via proc fs */
1518 #endif
1519 #ifdef CONFIG_CHECKSUM_OFFLOAD
1520 if(csumOffload){
1521
1522 dev->features |= NETIF_F_IP_CSUM;/*advertise kernel capability
1523 to do TCP/UDP CSUM offload for IPV4 */
1524 ar->rxMetaVersion=WMI_META_VERSION_2;/*if external frame work is also ne eded, change and use an extended rxMetaVerion*/
1525 }
1526 #endif
1527 if (processDot11Hdr) {
1528 dev->hard_header_len = sizeof(struct ieee80211_qosframe) + sizeof(ATH_LL C_SNAP_HDR) + sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX _HACK_FUDGE_FACTOR;
1529 } else {
1530 /*
1531 * We need the OS to provide us with more headroom in order to
1532 * perform dix to 802.3, WMI header encap, and the HTC header
1533 */
1534 dev->hard_header_len = ETH_HLEN + sizeof(ATH_LLC_SNAP_HDR) +
1535 sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_H ACK_FUDGE_FACTOR;
1536 }
1537
1538 #ifdef ATH_AR6K_11N_SUPPORT
1539 if((ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs)) == NULL) {
1540 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize aggr.\n", __func__));
1541 return A_ERROR;
1542 }
1543
1544 aggr_register_rx_dispatcher(ar->aggr_cntxt, (void *)dev, ar6000_deliver_fram es_to_nw_stack);
1545 #endif
1546
1547 HIFClaimDevice(ar->arHifDevice, ar);
1548
1549 /* We only register the device in the global list if we succeed. */
1550 /* If the device is in the global list, it will be destroyed */
1551 /* when the module is unloaded. */
1552 ar6000_devices[device_index] = dev;
1553
1554 /* Don't install the init function if BMI is requested */
1555 if (!bmienable) {
1556 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
1557 dev->init = ar6000_init;
1558 #else
1559 ar6000_netdev_ops.ndo_init = ar6000_init;
1560 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) */
1561 } else {
1562 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode));
1563 if ((wlaninitmode == WLAN_INIT_MODE_UDEV) ||
1564 (wlaninitmode == WLAN_INIT_MODE_DRV))
1565 {
1566 A_STATUS status = A_OK;
1567 do {
1568 if ((status = ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != A_OK)
1569 {
1570 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_b mi_get_config failed\n"));
1571 break;
1572 }
1573
1574 if ((ar6000_init(dev)) < A_OK) {
1575 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n" ));
1576 status = A_ERROR;
1577 }
1578 } while (FALSE);
1579
1580 if (status != A_OK) {
1581 /* Clean up TODO */
1582 return status;
1583 }
1584 }
1585 }
1586
1587 /* This runs the init function if registered */
1588 if (register_netdev(dev)) {
1589 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: register_netdev failed\n") );
1590 ar6000_destroy(dev, 0);
1591 return A_ERROR;
1592 }
1593
1594 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_avail: name=%s hifdevice=0x%x, dev=0 x%x (%d), ar=0x%x\n",
1595 dev->name, (A_UINT32)ar->arHifDevice, (A_UINT32)dev, device_ index,
1596 (A_UINT32)ar));
1597
1598 return A_OK;
1599 }
1600
1601 static void ar6000_target_failure(void *Instance, A_STATUS Status)
1602 {
1603 AR_SOFTC_T *ar = (AR_SOFTC_T *)Instance;
1604 WMI_TARGET_ERROR_REPORT_EVENT errEvent;
1605 static A_BOOL sip = FALSE;
1606
1607 if (Status != A_OK) {
1608
1609 printk(KERN_ERR "ar6000_target_failure: target asserted \n");
1610
1611 if (timer_pending(&ar->arHBChallengeResp.timer)) {
1612 A_UNTIMEOUT(&ar->arHBChallengeResp.timer);
1613 }
1614
1615 /* try dumping target assertion information (if any) */
1616 ar6000_dump_target_assert_info(ar->arHifDevice,ar->arTargetType);
1617
1618 /*
1619 * Fetch the logs from the target via the diagnostic
1620 * window.
1621 */
1622 ar6000_dbglog_get_debug_logs(ar);
1623
1624 /* Report the error only once */
1625 if (!sip) {
1626 sip = TRUE;
1627 errEvent.errorVal = WMI_TARGET_COM_ERR |
1628 WMI_TARGET_FATAL_ERR;
1629 ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID,
1630 (A_UINT8 *)&errEvent,
1631 sizeof(WMI_TARGET_ERROR_REPORT_EVENT));
1632 }
1633 }
1634 }
1635
1636 static A_STATUS
1637 ar6000_unavail_ev(void *context, void *hif_handle)
1638 {
1639 AR_SOFTC_T *ar = (AR_SOFTC_T *)context;
1640 /* NULL out it's entry in the global list */
1641 ar6000_devices[ar->arDeviceIndex] = NULL;
1642 ar6000_destroy(ar->arNetDev, 1);
1643
1644 return A_OK;
1645 }
1646
1647 /*
1648 * We need to differentiate between the surprise and planned removal of the
1649 * device because of the following consideration:
1650 * - In case of surprise removal, the hcd already frees up the pending
1651 * for the device and hence there is no need to unregister the function
1652 * driver inorder to get these requests. For planned removal, the function
1653 * driver has to explictly unregister itself to have the hcd return all the
1654 * pending requests before the data structures for the devices are freed up.
1655 * Note that as per the current implementation, the function driver will
1656 * end up releasing all the devices since there is no API to selectively
1657 * release a particular device.
1658 * - Certain commands issued to the target can be skipped for surprise
1659 * removal since they will anyway not go through.
1660 */
1661 static void
1662 ar6000_destroy(struct net_device *dev, unsigned int unregister)
1663 {
1664 AR_SOFTC_T *ar;
1665
1666 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("+ar6000_destroy \n"));
1667
1668 if((dev == NULL) || ((ar = ar6k_priv(dev)) == NULL))
1669 {
1670 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): Failed to get device structure.\n" , __func__));
1671 return;
1672 }
1673
1674 ar->bIsDestroyProgress = TRUE;
1675
1676 if (down_interruptible(&ar->arSem)) {
1677 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): down_interruptible failed \n", __f unc__));
1678 return;
1679 }
1680
1681 /* Stop the transmit queues */
1682 netif_stop_queue(dev);
1683
1684 /* Disable the target and the interrupts associated with it */
1685 if (ar->arWmiReady == TRUE)
1686 {
1687 if (!bypasswmi)
1688 {
1689 if (ar->arConnected == TRUE || ar->arConnectPending == TRUE)
1690 {
1691 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Disconnect\n", __func__)) ;
1692 AR6000_SPIN_LOCK(&ar->arLock, 0);
1693 ar6000_init_profile_info(ar);
1694 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
1695 wmi_disconnect_cmd(ar->arWmi);
1696 }
1697
1698 ar6000_dbglog_get_debug_logs(ar);
1699 ar->arWmiReady = FALSE;
1700 ar->arConnected = FALSE;
1701 ar->arConnectPending = FALSE;
1702 wmi_shutdown(ar->arWmi);
1703 ar->arWmiEnabled = FALSE;
1704 ar->arWmi = NULL;
1705 ar->arWlanState = WLAN_ENABLED;
1706 #ifdef USER_KEYS
1707 ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
1708 ar->user_key_ctrl = 0;
1709 #endif
1710 }
1711
1712 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI stopped\n", __func__));
1713 }
1714 else
1715 {
1716 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI not ready 0x%08x 0x%08x\n",
1717 __func__, (unsigned int) ar, (unsigned int) ar->arWmi));
1718
1719 /* Shut down WMI if we have started it */
1720 if(ar->arWmiEnabled == TRUE)
1721 {
1722 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Shut down WMI\n", __func__));
1723 wmi_shutdown(ar->arWmi);
1724 ar->arWmiEnabled = FALSE;
1725 ar->arWmi = NULL;
1726 }
1727 }
1728
1729 if (ar->arHtcTarget != NULL) {
1730 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
1731 if (NULL != ar6kHciTransCallbacks.cleanupTransport) {
1732 ar6kHciTransCallbacks.cleanupTransport(NULL);
1733 }
1734 #else
1735 // FIXME: workaround to reset BT's UART baud rate to default
1736 if (NULL != ar->exitCallback) {
1737 AR3K_CONFIG_INFO ar3kconfig;
1738 A_STATUS status;
1739
1740 A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
1741 ar6000_set_default_ar3kconfig(ar, (void *)&ar3kconfig);
1742 status = ar->exitCallback(&ar3kconfig);
1743 if (A_OK != status) {
1744 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to reset AR3K baud rate! \n"));
1745 }
1746 }
1747 // END workaround
1748 ar6000_cleanup_hci(ar);
1749 #endif
1750 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Shutting down HTC .... \n"));
1751 /* stop HTC */
1752 HTCStop(ar->arHtcTarget);
1753 /* destroy HTC */
1754 HTCDestroy(ar->arHtcTarget);
1755 }
1756
1757 if (resetok) {
1758 /* try to reset the device if we can
1759 * The driver may have been configure NOT to reset the target during
1760 * a debug session */
1761 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Attempting to reset target on instance destroy.... \n"));
1762 if (ar->arHifDevice != NULL) {
1763 ar6000_reset_device(ar->arHifDevice, ar->arTargetType, TRUE, FALSE);
1764 }
1765 } else {
1766 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Host does not want target reset. \n")) ;
1767 }
1768
1769 if (ar->arHifDevice != NULL) {
1770 /*release the device so we do not get called back on remove incase we
1771 * we're explicity destroyed by module unload */
1772 HIFReleaseDevice(ar->arHifDevice);
1773 HIFShutDownDevice(ar->arHifDevice);
1774 }
1775 #ifdef ATH_AR6K_11N_SUPPORT
1776 aggr_module_destroy(ar->aggr_cntxt);
1777 #endif
1778
1779 /* Done with cookies */
1780 ar6000_cookie_cleanup(ar);
1781
1782 /* cleanup any allocated AMSDU buffers */
1783 ar6000_cleanup_amsdu_rxbufs(ar);
1784
1785 if (bmienable) {
1786 ar6000_sysfs_bmi_deinit(ar);
1787 }
1788
1789 /* Cleanup BMI */
1790 BMIInit();
1791
1792 /* Clear the tx counters */
1793 memset(tx_attempt, 0, sizeof(tx_attempt));
1794 memset(tx_post, 0, sizeof(tx_post));
1795 memset(tx_complete, 0, sizeof(tx_complete));
1796
1797
1798 /* Free up the device data structure */
1799 if( unregister )
1800 unregister_netdev(dev);
1801 #ifndef free_netdev
1802 kfree(dev);
1803 #else
1804 free_netdev(dev);
1805 #endif
1806
1807 #ifdef CONFIG_CFG80211
1808 ar6k_cfg80211_deinit(ar);
1809 #endif /* CONFIG_CFG80211 */
1810
1811 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("-ar6000_destroy \n"));
1812 }
1813
1814 static void disconnect_timer_handler(unsigned long ptr)
1815 {
1816 struct net_device *dev = (struct net_device *)ptr;
1817 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1818
1819 A_UNTIMEOUT(&ar->disconnect_timer);
1820
1821 ar6000_init_profile_info(ar);
1822 wmi_disconnect_cmd(ar->arWmi);
1823 }
1824
1825 static void ar6000_detect_error(unsigned long ptr)
1826 {
1827 struct net_device *dev = (struct net_device *)ptr;
1828 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1829 WMI_TARGET_ERROR_REPORT_EVENT errEvent;
1830
1831 AR6000_SPIN_LOCK(&ar->arLock, 0);
1832
1833 if (ar->arHBChallengeResp.outstanding) {
1834 ar->arHBChallengeResp.missCnt++;
1835 } else {
1836 ar->arHBChallengeResp.missCnt = 0;
1837 }
1838
1839 if (ar->arHBChallengeResp.missCnt > ar->arHBChallengeResp.missThres) {
1840 /* Send Error Detect event to the application layer and do not reschedul e the error detection module timer */
1841 ar->arHBChallengeResp.missCnt = 0;
1842 ar->arHBChallengeResp.seqNum = 0;
1843 errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR;
1844 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
1845 ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID,
1846 (A_UINT8 *)&errEvent,
1847 sizeof(WMI_TARGET_ERROR_REPORT_EVENT));
1848 return;
1849 }
1850
1851 /* Generate the sequence number for the next challenge */
1852 ar->arHBChallengeResp.seqNum++;
1853 ar->arHBChallengeResp.outstanding = TRUE;
1854
1855 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
1856
1857 /* Send the challenge on the control channel */
1858 if (wmi_get_challenge_resp_cmd(ar->arWmi, ar->arHBChallengeResp.seqNum, DRV_ HB_CHALLENGE) != A_OK) {
1859 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to send heart beat challenge\n")) ;
1860 }
1861
1862
1863 /* Reschedule the timer for the next challenge */
1864 A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0);
1865 }
1866
1867 void ar6000_init_profile_info(AR_SOFTC_T *ar)
1868 {
1869 ar->arSsidLen = 0;
1870 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1871
1872 switch(fwmode) {
1873 case HI_OPTION_FW_MODE_IBSS:
1874 ar->arNetworkType = ar->arNextMode = ADHOC_NETWORK;
1875 break;
1876 case HI_OPTION_FW_MODE_BSS_STA:
1877 ar->arNetworkType = ar->arNextMode = INFRA_NETWORK;
1878 break;
1879 case HI_OPTION_FW_MODE_AP:
1880 ar->arNetworkType = ar->arNextMode = AP_NETWORK;
1881 break;
1882 }
1883
1884 ar->arDot11AuthMode = OPEN_AUTH;
1885 ar->arAuthMode = NONE_AUTH;
1886 ar->arPairwiseCrypto = NONE_CRYPT;
1887 ar->arPairwiseCryptoLen = 0;
1888 ar->arGroupCrypto = NONE_CRYPT;
1889 ar->arGroupCryptoLen = 0;
1890 A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
1891 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
1892 A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
1893 ar->arBssChannel = 0;
1894 ar->arConnected = FALSE;
1895 }
1896
1897 static void
1898 ar6000_init_control_info(AR_SOFTC_T *ar)
1899 {
1900 ar->arWmiEnabled = FALSE;
1901 ar6000_init_profile_info(ar);
1902 ar->arDefTxKeyIndex = 0;
1903 A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
1904 ar->arChannelHint = 0;
1905 ar->arListenInterval = MAX_LISTEN_INTERVAL;
1906 ar->arVersion.host_ver = AR6K_SW_VERSION;
1907 ar->arRssi = 0;
1908 ar->arTxPwr = 0;
1909 ar->arTxPwrSet = FALSE;
1910 ar->arSkipScan = 0;
1911 ar->arBeaconInterval = 0;
1912 ar->arBitRate = 0;
1913 ar->arMaxRetries = 0;
1914 ar->arWmmEnabled = TRUE;
1915 ar->intra_bss = 1;
1916
1917 /* Initialize the AP mode state info */
1918 {
1919 A_UINT8 ctr;
1920 A_MEMZERO((A_UINT8 *)ar->sta_list, AP_MAX_NUM_STA * sizeof(sta_t));
1921
1922 /* init the Mutexes */
1923 A_MUTEX_INIT(&ar->mcastpsqLock);
1924
1925 /* Init the PS queues */
1926 for (ctr=0; ctr < AP_MAX_NUM_STA ; ctr++) {
1927 A_MUTEX_INIT(&ar->sta_list[ctr].psqLock);
1928 A_NETBUF_QUEUE_INIT(&ar->sta_list[ctr].psq);
1929 }
1930
1931 ar->ap_profile_flag = 0;
1932 A_NETBUF_QUEUE_INIT(&ar->mcastpsq);
1933
1934 A_MEMCPY(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
1935 ar->ap_wmode = DEF_AP_WMODE_G;
1936 ar->ap_dtim_period = DEF_AP_DTIM;
1937 ar->ap_beacon_interval = DEF_BEACON_INTERVAL;
1938 }
1939 }
1940
1941 static int
1942 ar6000_open(struct net_device *dev)
1943 {
1944 unsigned long flags;
1945 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1946
1947 spin_lock_irqsave(&ar->arLock, flags);
1948
1949 if(ar->arWlanState == WLAN_DISABLED) {
1950 ar->arWlanState = WLAN_ENABLED;
1951 }
1952
1953 if( ar->arConnected || bypasswmi) {
1954 netif_carrier_on(dev);
1955 /* Wake up the queues */
1956 netif_wake_queue(dev);
1957 }
1958 else
1959 netif_carrier_off(dev);
1960
1961 spin_unlock_irqrestore(&ar->arLock, flags);
1962 return 0;
1963 }
1964
1965 static int
1966 ar6000_close(struct net_device *dev)
1967 {
1968 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1969 netif_stop_queue(dev);
1970
1971 AR6000_SPIN_LOCK(&ar->arLock, 0);
1972 if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) {
1973 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
1974 wmi_disconnect_cmd(ar->arWmi);
1975 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1976 ar->arSsidLen = 0;
1977 } else {
1978 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
1979 }
1980
1981 if(ar->arWmiReady == TRUE) {
1982 if (wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0,
1983 0, 0, 0, 0, 0, 0xFF, 0, 0) != A_OK) {
1984 return -EIO;
1985 }
1986 ar->arWlanState = WLAN_DISABLED;
1987 }
1988
1989 return 0;
1990 }
1991
1992 /* connect to a service */
1993 static A_STATUS ar6000_connectservice(AR_SOFTC_T *ar,
1994 HTC_SERVICE_CONNECT_REQ *pConnect,
1995 char *pDesc)
1996 {
1997 A_STATUS status;
1998 HTC_SERVICE_CONNECT_RESP response;
1999
2000 do {
2001
2002 A_MEMZERO(&response,sizeof(response));
2003
2004 status = HTCConnectService(ar->arHtcTarget,
2005 pConnect,
2006 &response);
2007
2008 if (A_FAILED(status)) {
2009 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Failed to connect to %s service sta tus:%d \n",
2010 pDesc, status));
2011 break;
2012 }
2013 switch (pConnect->ServiceID) {
2014 case WMI_CONTROL_SVC :
2015 if (ar->arWmiEnabled) {
2016 /* set control endpoint for WMI use */
2017 wmi_set_control_ep(ar->arWmi, response.Endpoint);
2018 }
2019 /* save EP for fast lookup */
2020 ar->arControlEp = response.Endpoint;
2021 break;
2022 case WMI_DATA_BE_SVC :
2023 arSetAc2EndpointIDMap(ar, WMM_AC_BE, response.Endpoint);
2024 break;
2025 case WMI_DATA_BK_SVC :
2026 arSetAc2EndpointIDMap(ar, WMM_AC_BK, response.Endpoint);
2027 break;
2028 case WMI_DATA_VI_SVC :
2029 arSetAc2EndpointIDMap(ar, WMM_AC_VI, response.Endpoint);
2030 break;
2031 case WMI_DATA_VO_SVC :
2032 arSetAc2EndpointIDMap(ar, WMM_AC_VO, response.Endpoint);
2033 break;
2034 default:
2035 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ServiceID not mapped %d\n", pCon nect->ServiceID));
2036 status = A_EINVAL;
2037 break;
2038 }
2039
2040 } while (FALSE);
2041
2042 return status;
2043 }
2044
2045 void ar6000_TxDataCleanup(AR_SOFTC_T *ar)
2046 {
2047 /* flush all the data (non-control) streams
2048 * we only flush packets that are tagged as data, we leave any control p ackets that
2049 * were in the TX queues alone */
2050 HTCFlushEndpoint(ar->arHtcTarget,
2051 arAc2EndpointID(ar, WMM_AC_BE),
2052 AR6K_DATA_PKT_TAG);
2053 HTCFlushEndpoint(ar->arHtcTarget,
2054 arAc2EndpointID(ar, WMM_AC_BK),
2055 AR6K_DATA_PKT_TAG);
2056 HTCFlushEndpoint(ar->arHtcTarget,
2057 arAc2EndpointID(ar, WMM_AC_VI),
2058 AR6K_DATA_PKT_TAG);
2059 HTCFlushEndpoint(ar->arHtcTarget,
2060 arAc2EndpointID(ar, WMM_AC_VO),
2061 AR6K_DATA_PKT_TAG);
2062 }
2063
2064 HTC_ENDPOINT_ID
2065 ar6000_ac2_endpoint_id ( void * devt, A_UINT8 ac)
2066 {
2067 AR_SOFTC_T *ar = (AR_SOFTC_T *) devt;
2068 return(arAc2EndpointID(ar, ac));
2069 }
2070
2071 A_UINT8
2072 ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep )
2073 {
2074 AR_SOFTC_T *ar = (AR_SOFTC_T *) devt;
2075 return(arEndpoint2Ac(ar, ep ));
2076 }
2077
2078 /* This function does one time initialization for the lifetime of the device */
2079 int ar6000_init(struct net_device *dev)
2080 {
2081 AR_SOFTC_T *ar;
2082 A_STATUS status;
2083 A_INT32 timeleft;
2084 A_INT16 i;
2085
2086 if((ar = ar6k_priv(dev)) == NULL)
2087 {
2088 return(-EIO);
2089 }
2090
2091 if (enablerssicompensation) {
2092 read_rssi_compensation_param(ar);
2093 for (i=-95; i<=0; i++) {
2094 rssi_compensation_table[0-i] = rssi_compensation_calc(ar,i);
2095 }
2096 }
2097
2098 if (!bypasswmi)
2099 {
2100 #if 0 /* TBDXXX */
2101 if (ar->arVersion.host_ver != ar->arVersion.target_ver) {
2102 A_PRINTF("WARNING: Host version 0x%x does not match Target "
2103 " version 0x%x!\n",
2104 ar->arVersion.host_ver, ar->arVersion.target_ver);
2105 }
2106 #endif
2107
2108 /* Indicate that WMI is enabled (although not ready yet) */
2109 ar->arWmiEnabled = TRUE;
2110 if ((ar->arWmi = wmi_init((void *) ar)) == NULL)
2111 {
2112 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize WMI.\n", _ _func__));
2113 return(-EIO);
2114 }
2115
2116 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Got WMI @ 0x%08x.\n", __func__,
2117 (unsigned int) ar->arWmi));
2118 }
2119
2120 do {
2121 HTC_SERVICE_CONNECT_REQ connect;
2122
2123 /* the reason we have to wait for the target here is that the driver layer
2124 * has to init BMI in order to set the host block size,
2125 */
2126 dev_hold(dev);
2127 rtnl_unlock();
2128 status = HTCWaitTarget(ar->arHtcTarget);
2129 rtnl_lock();
2130 dev_put(dev);
2131
2132 if (A_FAILED(status)) {
2133 break;
2134 }
2135
2136 A_MEMZERO(&connect,sizeof(connect));
2137 /* meta data is unused for now */
2138 connect.pMetaData = NULL;
2139 connect.MetaDataLength = 0;
2140 /* these fields are the same for all service endpoints */
2141 connect.EpCallbacks.pContext = ar;
2142 connect.EpCallbacks.EpTxCompleteMultiple = ar6000_tx_complete;
2143 connect.EpCallbacks.EpRecv = ar6000_rx;
2144 connect.EpCallbacks.EpRecvRefill = ar6000_rx_refill;
2145 connect.EpCallbacks.EpSendFull = ar6000_tx_queue_full;
2146 /* set the max queue depth so that our ar6000_tx_queue_full handler gets called.
2147 * Linux has the peculiarity of not providing flow control between t he
2148 * NIC and the network stack. There is no API to indicate that a TX packet
2149 * was sent which could provide some back pressure to the network st ack.
2150 * Under linux you would have to wait till the network stack consume d all sk_buffs
2151 * before any back-flow kicked in. Which isn't very friendly.
2152 * So we have to manage this ourselves */
2153 connect.MaxSendQueueDepth = MAX_DEFAULT_SEND_QUEUE_DEPTH;
2154 connect.EpCallbacks.RecvRefillWaterMark = AR6000_MAX_RX_BUFFERS / 4; /* set to 25 % */
2155 if (0 == connect.EpCallbacks.RecvRefillWaterMark) {
2156 connect.EpCallbacks.RecvRefillWaterMark++;
2157 }
2158 /* connect to control service */
2159 connect.ServiceID = WMI_CONTROL_SVC;
2160 status = ar6000_connectservice(ar,
2161 &connect,
2162 "WMI CONTROL");
2163 if (A_FAILED(status)) {
2164 break;
2165 }
2166
2167 connect.LocalConnectionFlags |= HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_ PADDING;
2168 /* limit the HTC message size on the send path, although we can rece ive A-MSDU frames of
2169 * 4K, we will only send ethernet-sized (802.3) frames on the send p ath. */
2170 connect.MaxSendMsgSize = WMI_MAX_TX_DATA_FRAME_LENGTH;
2171
2172 /* to reduce the amount of committed memory for larger A_MSDU frames , use the recv-alloc threshold
2173 * mechanism for larger packets */
2174 connect.EpCallbacks.RecvAllocThreshold = AR6000_BUFFER_SIZE;
2175 connect.EpCallbacks.EpRecvAllocThresh = ar6000_alloc_amsdu_rxbuf;
2176
2177 /* for the remaining data services set the connection flag to reduce dribbling,
2178 * if configured to do so */
2179 if (reduce_credit_dribble) {
2180 connect.ConnectionFlags |= HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE;
2181 /* the credit dribble trigger threshold is (reduce_credit_dribble - 1) for a value
2182 * of 0-3 */
2183 connect.ConnectionFlags &= ~HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
2184 connect.ConnectionFlags |=
2185 ((A_UINT16)reduce_credit_dribble - 1) & HTC_CONNECT_FLAG S_THRESHOLD_LEVEL_MASK;
2186 }
2187 /* connect to best-effort service */
2188 connect.ServiceID = WMI_DATA_BE_SVC;
2189
2190 status = ar6000_connectservice(ar,
2191 &connect,
2192 "WMI DATA BE");
2193 if (A_FAILED(status)) {
2194 break;
2195 }
2196
2197 /* connect to back-ground
2198 * map this to WMI LOW_PRI */
2199 connect.ServiceID = WMI_DATA_BK_SVC;
2200 status = ar6000_connectservice(ar,
2201 &connect,
2202 "WMI DATA BK");
2203 if (A_FAILED(status)) {
2204 break;
2205 }
2206
2207 /* connect to Video service, map this to
2208 * to HI PRI */
2209 connect.ServiceID = WMI_DATA_VI_SVC;
2210 status = ar6000_connectservice(ar,
2211 &connect,
2212 "WMI DATA VI");
2213 if (A_FAILED(status)) {
2214 break;
2215 }
2216
2217 /* connect to VO service, this is currently not
2218 * mapped to a WMI priority stream due to historical reasons.
2219 * WMI originally defined 3 priorities over 3 mailboxes
2220 * We can change this when WMI is reworked so that priorities are no t
2221 * dependent on mailboxes */
2222 connect.ServiceID = WMI_DATA_VO_SVC;
2223 status = ar6000_connectservice(ar,
2224 &connect,
2225 "WMI DATA VO");
2226 if (A_FAILED(status)) {
2227 break;
2228 }
2229
2230 A_ASSERT(arAc2EndpointID(ar,WMM_AC_BE) != 0);
2231 A_ASSERT(arAc2EndpointID(ar,WMM_AC_BK) != 0);
2232 A_ASSERT(arAc2EndpointID(ar,WMM_AC_VI) != 0);
2233 A_ASSERT(arAc2EndpointID(ar,WMM_AC_VO) != 0);
2234
2235 /* setup access class priority mappings */
2236 ar->arAcStreamPriMap[WMM_AC_BK] = 0; /* lowest */
2237 ar->arAcStreamPriMap[WMM_AC_BE] = 1; /* */
2238 ar->arAcStreamPriMap[WMM_AC_VI] = 2; /* */
2239 ar->arAcStreamPriMap[WMM_AC_VO] = 3; /* highest */
2240
2241 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
2242 if (setuphci && (NULL != ar6kHciTransCallbacks.setupTransport)) {
2243 HCI_TRANSPORT_MISC_HANDLES hciHandles;
2244
2245 hciHandles.netDevice = ar->arNetDev;
2246 hciHandles.hifDevice = ar->arHifDevice;
2247 hciHandles.htcHandle = ar->arHtcTarget;
2248 status = (A_STATUS)(ar6kHciTransCallbacks.setupTransport(&hciHandles ));
2249 #else
2250 if (setuphci) {
2251 /* setup HCI */
2252 status = ar6000_setup_hci(ar);
2253 #endif
2254 }
2255
2256 } while (FALSE);
2257
2258 if (A_FAILED(status)) {
2259 return (-EIO);
2260 }
2261
2262 /*
2263 * give our connected endpoints some buffers
2264 */
2265
2266 ar6000_rx_refill(ar, ar->arControlEp);
2267 ar6000_rx_refill(ar, arAc2EndpointID(ar,WMM_AC_BE));
2268
2269 /*
2270 * We will post the receive buffers only for SPE or endpoint ping testing so we are
2271 * making it conditional on the 'bypasswmi' flag.
2272 */
2273 if (bypasswmi) {
2274 ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_BK));
2275 ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VI));
2276 ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VO));
2277 }
2278
2279 /* allocate some buffers that handle larger AMSDU frames */
2280 ar6000_refill_amsdu_rxbufs(ar,AR6000_MAX_AMSDU_RX_BUFFERS);
2281
2282 /* setup credit distribution */
2283 ar6000_setup_credit_dist(ar->arHtcTarget, &ar->arCreditStateInfo);
2284
2285 /* Since cookies are used for HTC transports, they should be */
2286 /* initialized prior to enabling HTC. */
2287 ar6000_cookie_init(ar);
2288
2289 /* start HTC */
2290 status = HTCStart(ar->arHtcTarget);
2291
2292 if (status != A_OK) {
2293 if (ar->arWmiEnabled == TRUE) {
2294 wmi_shutdown(ar->arWmi);
2295 ar->arWmiEnabled = FALSE;
2296 ar->arWmi = NULL;
2297 }
2298 ar6000_cookie_cleanup(ar);
2299 return -EIO;
2300 }
2301
2302 if (!bypasswmi) {
2303 /* Wait for Wmi event to be ready */
2304 dev_hold(dev);
2305 rtnl_unlock();
2306 timeleft = wait_event_interruptible_timeout(arEvent,
2307 (ar->arWmiReady == TRUE), wmitimeout * HZ);
2308 rtnl_lock();
2309 dev_put(dev);
2310
2311 if(!timeleft || signal_pending(current))
2312 {
2313 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI is not ready or wait was interru pted\n"));
2314 return -EIO;
2315 }
2316
2317 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() WMI is ready\n", __func__));
2318
2319 /* Communicate the wmi protocol verision to the target */
2320 if ((ar6000_set_host_app_area(ar)) != A_OK) {
2321 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the host app area\n")) ;
2322 }
2323
2324 /* configure the device for rx dot11 header rules 0,0 are the default va lues
2325 * therefore this command can be skipped if the inputs are 0,FALSE,FALSE .Required
2326 if checksum offload is needed. Set RxMetaVersion to 2*/
2327 if ((wmi_set_rx_frame_format_cmd(ar->arWmi,ar->rxMetaVersion, processDot 11Hdr, processDot11Hdr)) != A_OK) {
2328 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the rx frame format.\n "));
2329 }
2330 }
2331
2332 ar->arNumDataEndPts = 1;
2333
2334 if (bypasswmi) {
2335 /* for tests like endpoint ping, the MAC address needs to be non-zer o otherwise
2336 * the data path through a raw socket is disabled */
2337 dev->dev_addr[0] = 0x00;
2338 dev->dev_addr[1] = 0x01;
2339 dev->dev_addr[2] = 0x02;
2340 dev->dev_addr[3] = 0xAA;
2341 dev->dev_addr[4] = 0xBB;
2342 dev->dev_addr[5] = 0xCC;
2343 }
2344
2345 return(0);
2346 }
2347
2348
2349 void
2350 ar6000_bitrate_rx(void *devt, A_INT32 rateKbps)
2351 {
2352 AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
2353
2354 ar->arBitRate = rateKbps;
2355 wake_up(&arEvent);
2356 }
2357
2358 void
2359 ar6000_ratemask_rx(void *devt, A_UINT32 ratemask)
2360 {
2361 AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
2362
2363 ar->arRateMask = ratemask;
2364 wake_up(&arEvent);
2365 }
2366
2367 void
2368 ar6000_txPwr_rx(void *devt, A_UINT8 txPwr)
2369 {
2370 AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
2371
2372 ar->arTxPwr = txPwr;
2373 wake_up(&arEvent);
2374 }
2375
2376
2377 void
2378 ar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList)
2379 {
2380 AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
2381
2382 A_MEMCPY(ar->arChannelList, chanList, numChan * sizeof (A_UINT16));
2383 ar->arNumChannels = numChan;
2384
2385 wake_up(&arEvent);
2386 }
2387
2388 A_UINT8
2389 ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, A_UINT32 * map No)
2390 {
2391 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2392 A_UINT8 *datap;
2393 ATH_MAC_HDR *macHdr;
2394 A_UINT32 i, eptMap;
2395
2396 (*mapNo) = 0;
2397 datap = A_NETBUF_DATA(skb);
2398 macHdr = (ATH_MAC_HDR *)(datap + sizeof(WMI_DATA_HDR));
2399 if (IEEE80211_IS_MULTICAST(macHdr->dstMac)) {
2400 return ENDPOINT_2;
2401 }
2402
2403 eptMap = -1;
2404 for (i = 0; i < ar->arNodeNum; i ++) {
2405 if (IEEE80211_ADDR_EQ(macHdr->dstMac, ar->arNodeMap[i].macAddress)) {
2406 (*mapNo) = i + 1;
2407 ar->arNodeMap[i].txPending ++;
2408 return ar->arNodeMap[i].epId;
2409 }
2410
2411 if ((eptMap == -1) && !ar->arNodeMap[i].txPending) {
2412 eptMap = i;
2413 }
2414 }
2415
2416 if (eptMap == -1) {
2417 eptMap = ar->arNodeNum;
2418 ar->arNodeNum ++;
2419 A_ASSERT(ar->arNodeNum <= MAX_NODE_NUM);
2420 }
2421
2422 A_MEMCPY(ar->arNodeMap[eptMap].macAddress, macHdr->dstMac, IEEE80211_ADDR_LE N);
2423
2424 for (i = ENDPOINT_2; i <= ENDPOINT_5; i ++) {
2425 if (!ar->arTxPending[i]) {
2426 ar->arNodeMap[eptMap].epId = i;
2427 break;
2428 }
2429 // No free endpoint is available, start redistribution on the inuse endp oints.
2430 if (i == ENDPOINT_5) {
2431 ar->arNodeMap[eptMap].epId = ar->arNexEpId;
2432 ar->arNexEpId ++;
2433 if (ar->arNexEpId > ENDPOINT_5) {
2434 ar->arNexEpId = ENDPOINT_2;
2435 }
2436 }
2437 }
2438
2439 (*mapNo) = eptMap + 1;
2440 ar->arNodeMap[eptMap].txPending ++;
2441
2442 return ar->arNodeMap[eptMap].epId;
2443 }
2444
2445 #ifdef DEBUG
2446 static void ar6000_dump_skb(struct sk_buff *skb)
2447 {
2448 u_char *ch;
2449 for (ch = A_NETBUF_DATA(skb);
2450 (A_UINT32)ch < ((A_UINT32)A_NETBUF_DATA(skb) +
2451 A_NETBUF_LEN(skb)); ch++)
2452 {
2453 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("%2.2x ", *ch));
2454 }
2455 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("\n"));
2456 }
2457 #endif
2458
2459 #ifdef HTC_TEST_SEND_PKTS
2460 static void DoHTCSendPktsTest(AR_SOFTC_T *ar, int MapNo, HTC_ENDPOINT_ID eid, st ruct sk_buff *skb);
2461 #endif
2462
2463 static int
2464 ar6000_data_tx(struct sk_buff *skb, struct net_device *dev)
2465 {
2466 #define AC_NOT_MAPPED 99
2467 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2468 A_UINT8 ac = AC_NOT_MAPPED;
2469 HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED;
2470 A_UINT32 mapNo = 0;
2471 int len;
2472 struct ar_cookie *cookie;
2473 A_BOOL checkAdHocPsMapping = FALSE,bMoreData = FALSE;
2474 HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG;
2475 A_UINT8 dot11Hdr = processDot11Hdr;
2476 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
2477 skb->list = NULL;
2478 #endif
2479
2480 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_data_tx start - skb=0x%x, data=0x %x, len=0x%x\n",
2481 (A_UINT32)skb, (A_UINT32)A_NETBUF_DATA(skb),
2482 A_NETBUF_LEN(skb)));
2483
2484 /* If target is not associated */
2485 if( (!ar->arConnected && !bypasswmi)
2486 #ifdef CONFIG_HOST_TCMD_SUPPORT
2487 /* TCMD doesnt support any data, free the buf and return */
2488 || (ar->arTargetMode == AR6000_TCMD_MODE)
2489 #endif
2490 ) {
2491 A_NETBUF_FREE(skb);
2492 return 0;
2493 }
2494
2495 do {
2496
2497 if (ar->arWmiReady == FALSE && bypasswmi == 0) {
2498 break;
2499 }
2500
2501 #ifdef BLOCK_TX_PATH_FLAG
2502 if (blocktx) {
2503 break;
2504 }
2505 #endif /* BLOCK_TX_PATH_FLAG */
2506
2507 /* AP mode Power save processing */
2508 /* If the dst STA is in sleep state, queue the pkt in its PS queue */
2509
2510 if (ar->arNetworkType == AP_NETWORK) {
2511 ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
2512 sta_t *conn = NULL;
2513
2514 /* If the dstMac is a Multicast address & atleast one of the
2515 * associated STA is in PS mode, then queue the pkt to the
2516 * mcastq
2517 */
2518 if (IEEE80211_IS_MULTICAST(datap->dstMac)) {
2519 A_UINT8 ctr=0;
2520 A_BOOL qMcast=FALSE;
2521
2522
2523 for (ctr=0; ctr<AP_MAX_NUM_STA; ctr++) {
2524 if (STA_IS_PWR_SLEEP((&ar->sta_list[ctr]))) {
2525 qMcast = TRUE;
2526 }
2527 }
2528 if(qMcast) {
2529
2530 /* If this transmit is not because of a Dtim Expiry q it */
2531 if (ar->DTIMExpired == FALSE) {
2532 A_BOOL isMcastqEmpty = FALSE;
2533
2534 A_MUTEX_LOCK(&ar->mcastpsqLock);
2535 isMcastqEmpty = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
2536 A_NETBUF_ENQUEUE(&ar->mcastpsq, skb);
2537 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
2538
2539 /* If this is the first Mcast pkt getting queued
2540 * indicate to the target to set the BitmapControl LSB
2541 * of the TIM IE.
2542 */
2543 if (isMcastqEmpty) {
2544 wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 1);
2545 }
2546 return 0;
2547 } else {
2548 /* This transmit is because of Dtim expiry. Determine if
2549 * MoreData bit has to be set.
2550 */
2551 A_MUTEX_LOCK(&ar->mcastpsqLock);
2552 if(!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
2553 bMoreData = TRUE;
2554 }
2555 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
2556 }
2557 }
2558 } else {
2559 conn = ieee80211_find_conn(ar, datap->dstMac);
2560 if (conn) {
2561 if (STA_IS_PWR_SLEEP(conn)) {
2562 /* If this transmit is not because of a PsPoll q it*/
2563 if (!STA_IS_PS_POLLED(conn)) {
2564 A_BOOL isPsqEmpty = FALSE;
2565 /* Queue the frames if the STA is sleeping */
2566 A_MUTEX_LOCK(&conn->psqLock);
2567 isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
2568 A_NETBUF_ENQUEUE(&conn->psq, skb);
2569 A_MUTEX_UNLOCK(&conn->psqLock);
2570
2571 /* If this is the first pkt getting queued
2572 * for this STA, update the PVB for this STA
2573 */
2574 if (isPsqEmpty) {
2575 wmi_set_pvb_cmd(ar->arWmi, conn->aid, 1);
2576 }
2577
2578 return 0;
2579 } else {
2580 /* This tx is because of a PsPoll. Determine if
2581 * MoreData bit has to be set
2582 */
2583 A_MUTEX_LOCK(&conn->psqLock);
2584 if (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) {
2585 bMoreData = TRUE;
2586 }
2587 A_MUTEX_UNLOCK(&conn->psqLock);
2588 }
2589 }
2590 } else {
2591
2592 /* non existent STA. drop the frame */
2593 A_NETBUF_FREE(skb);
2594 return 0;
2595 }
2596 }
2597 }
2598
2599 if (ar->arWmiEnabled) {
2600 #ifdef CONFIG_CHECKSUM_OFFLOAD
2601 A_UINT8 csumStart=0;
2602 A_UINT8 csumDest=0;
2603 A_UINT8 csum=skb->ip_summed;
2604 if(csumOffload && (csum==CHECKSUM_PARTIAL)){
2605 csumStart=skb->csum_start-(skb->network_header-skb->head)+si zeof(ATH_LLC_SNAP_HDR);
2606 csumDest=skb->csum_offset+csumStart;
2607 }
2608 #endif
2609 if (A_NETBUF_HEADROOM(skb) < dev->hard_header_len - LINUX_HACK_FUDGE _FACTOR) {
2610 struct sk_buff *newbuf;
2611
2612 /*
2613 * We really should have gotten enough headroom but sometimes
2614 * we still get packets with not enough headroom. Copy the pack et.
2615 */
2616 len = A_NETBUF_LEN(skb);
2617 newbuf = A_NETBUF_ALLOC(len);
2618 if (newbuf == NULL) {
2619 break;
2620 }
2621 A_NETBUF_PUT(newbuf, len);
2622 A_MEMCPY(A_NETBUF_DATA(newbuf), A_NETBUF_DATA(skb), len);
2623 A_NETBUF_FREE(skb);
2624 skb = newbuf;
2625 /* fall through and assemble header */
2626 }
2627
2628 if (dot11Hdr) {
2629 if (wmi_dot11_hdr_add(ar->arWmi,skb,ar->arNetworkType) != A_OK) {
2630 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx-wmi_dot11_hdr _add failed\n"));
2631 break;
2632 }
2633 } else {
2634 if (wmi_dix_2_dot3(ar->arWmi, skb) != A_OK) {
2635 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_dix_2_d ot3 failed\n"));
2636 break;
2637 }
2638 }
2639 #ifdef CONFIG_CHECKSUM_OFFLOAD
2640 if(csumOffload && (csum ==CHECKSUM_PARTIAL)){
2641 WMI_TX_META_V2 metaV2;
2642 metaV2.csumStart =csumStart;
2643 metaV2.csumDest = csumDest;
2644 metaV2.csumFlags = 0x1;/*instruct target to calculate checksum*/
2645 if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, do t11Hdr,
2646 WMI_META_VERSION_2,&metaV2) != A_OK) {
2647 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hd r_add failed\n"));
2648 break;
2649 }
2650
2651 }
2652 else
2653 #endif
2654 {
2655 if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, do t11Hdr,0,NULL) != A_OK) {
2656 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hd r_add failed\n"));
2657 break;
2658 }
2659 }
2660
2661
2662 if ((ar->arNetworkType == ADHOC_NETWORK) &&
2663 ar->arIbssPsEnable && ar->arConnected) {
2664 /* flag to check adhoc mapping once we take the lock below: */
2665 checkAdHocPsMapping = TRUE;
2666
2667 } else {
2668 /* get the stream mapping */
2669 ac = wmi_implicit_create_pstream(ar->arWmi, skb, 0, ar->arWmmE nabled);
2670 }
2671
2672 } else {
2673 EPPING_HEADER *eppingHdr;
2674
2675 eppingHdr = A_NETBUF_DATA(skb);
2676
2677 if (IS_EPPING_PACKET(eppingHdr)) {
2678 /* the stream ID is mapped to an access class */
2679 ac = eppingHdr->StreamNo_h;
2680 /* some EPPING packets cannot be dropped no matter what acce ss class it was
2681 * sent on. We can change the packet tag to guarantee it wi ll not get dropped */
2682 if (IS_EPING_PACKET_NO_DROP(eppingHdr)) {
2683 htc_tag = AR6K_CONTROL_PKT_TAG;
2684 }
2685
2686 if (ac == HCI_TRANSPORT_STREAM_NUM) {
2687 /* pass this to HCI */
2688 #ifndef EXPORT_HCI_BRIDGE_INTERFACE
2689 if (A_SUCCESS(hci_test_send(ar,skb))) {
2690 return 0;
2691 }
2692 #endif
2693 /* set AC to discard this skb */
2694 ac = AC_NOT_MAPPED;
2695 }
2696
2697 } else {
2698 /* not a ping packet, drop it */
2699 ac = AC_NOT_MAPPED;
2700 }
2701 }
2702
2703 } while (FALSE);
2704
2705 /* did we succeed ? */
2706 if ((ac == AC_NOT_MAPPED) && !checkAdHocPsMapping) {
2707 /* cleanup and exit */
2708 A_NETBUF_FREE(skb);
2709 AR6000_STAT_INC(ar, tx_dropped);
2710 AR6000_STAT_INC(ar, tx_aborted_errors);
2711 return 0;
2712 }
2713
2714 cookie = NULL;
2715
2716 /* take the lock to protect driver data */
2717 AR6000_SPIN_LOCK(&ar->arLock, 0);
2718
2719 do {
2720
2721 if (checkAdHocPsMapping) {
2722 eid = ar6000_ibss_map_epid(skb, dev, &mapNo);
2723 }else {
2724 eid = arAc2EndpointID (ar, ac);
2725 }
2726 /* validate that the endpoint is connected */
2727 if (eid == 0 || eid == ENDPOINT_UNUSED ) {
2728 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" eid %d is NOT mapped!\n", eid));
2729 break;
2730 }
2731 /* allocate resource for this packet */
2732 cookie = ar6000_alloc_cookie(ar);
2733
2734 if (cookie != NULL) {
2735 /* update counts while the lock is held */
2736 ar->arTxPending[eid]++;
2737 ar->arTotalTxDataPending++;
2738 }
2739
2740 } while (FALSE);
2741
2742 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2743
2744 if (cookie != NULL) {
2745 cookie->arc_bp[0] = (A_UINT32)skb;
2746 cookie->arc_bp[1] = mapNo;
2747 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
2748 cookie,
2749 A_NETBUF_DATA(skb),
2750 A_NETBUF_LEN(skb),
2751 eid,
2752 htc_tag);
2753
2754 #ifdef DEBUG
2755 if (debugdriver >= 3) {
2756 ar6000_dump_skb(skb);
2757 }
2758 #endif
2759 #ifdef HTC_TEST_SEND_PKTS
2760 DoHTCSendPktsTest(ar,mapNo,eid,skb);
2761 #endif
2762 /* HTC interface is asynchronous, if this fails, cleanup will happen in
2763 * the ar6000_tx_complete callback */
2764 HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
2765 } else {
2766 /* no packet to send, cleanup */
2767 A_NETBUF_FREE(skb);
2768 AR6000_STAT_INC(ar, tx_dropped);
2769 AR6000_STAT_INC(ar, tx_aborted_errors);
2770 }
2771
2772 return 0;
2773 }
2774
2775 int
2776 ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev)
2777 {
2778 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2779 struct ar_cookie *cookie;
2780 HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED;
2781
2782 cookie = NULL;
2783 AR6000_SPIN_LOCK(&ar->arLock, 0);
2784
2785 /* For now we send ACL on BE endpoint: We can also have a dedicated EP * /
2786 eid = arAc2EndpointID (ar, 0);
2787 /* allocate resource for this packet */
2788 cookie = ar6000_alloc_cookie(ar);
2789
2790 if (cookie != NULL) {
2791 /* update counts while the lock is held */
2792 ar->arTxPending[eid]++;
2793 ar->arTotalTxDataPending++;
2794 }
2795
2796
2797 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2798
2799 if (cookie != NULL) {
2800 cookie->arc_bp[0] = (A_UINT32)skb;
2801 cookie->arc_bp[1] = 0;
2802 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
2803 cookie,
2804 A_NETBUF_DATA(skb),
2805 A_NETBUF_LEN(skb),
2806 eid,
2807 AR6K_DATA_PKT_TAG);
2808
2809 /* HTC interface is asynchronous, if this fails, cleanup will happen in
2810 * the ar6000_tx_complete callback */
2811 HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
2812 } else {
2813 /* no packet to send, cleanup */
2814 A_NETBUF_FREE(skb);
2815 AR6000_STAT_INC(ar, tx_dropped);
2816 AR6000_STAT_INC(ar, tx_aborted_errors);
2817 }
2818 return 0;
2819 }
2820
2821
2822 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
2823 static void
2824 tvsub(register struct timeval *out, register struct timeval *in)
2825 {
2826 if((out->tv_usec -= in->tv_usec) < 0) {
2827 out->tv_sec--;
2828 out->tv_usec += 1000000;
2829 }
2830 out->tv_sec -= in->tv_sec;
2831 }
2832
2833 void
2834 applyAPTCHeuristics(AR_SOFTC_T *ar)
2835 {
2836 A_UINT32 duration;
2837 A_UINT32 numbytes;
2838 A_UINT32 throughput;
2839 struct timeval ts;
2840 A_STATUS status;
2841
2842 AR6000_SPIN_LOCK(&ar->arLock, 0);
2843
2844 if ((enableAPTCHeuristics) && (!aptcTR.timerScheduled)) {
2845 do_gettimeofday(&ts);
2846 tvsub(&ts, &aptcTR.samplingTS);
2847 duration = ts.tv_sec * 1000 + ts.tv_usec / 1000; /* ms */
2848 numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
2849
2850 if (duration > APTC_TRAFFIC_SAMPLING_INTERVAL) {
2851 /* Initialize the time stamp and byte count */
2852 aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
2853 do_gettimeofday(&aptcTR.samplingTS);
2854
2855 /* Calculate and decide based on throughput thresholds */
2856 throughput = ((numbytes * 8) / duration);
2857 if (throughput > APTC_UPPER_THROUGHPUT_THRESHOLD) {
2858 /* Disable Sleep and schedule a timer */
2859 A_ASSERT(ar->arWmiReady == TRUE);
2860 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2861 status = wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER);
2862 AR6000_SPIN_LOCK(&ar->arLock, 0);
2863 A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
2864 aptcTR.timerScheduled = TRUE;
2865 }
2866 }
2867 }
2868
2869 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2870 }
2871 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
2872
2873 static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, HTC_PACKET *pPac ket)
2874 {
2875 AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
2876 HTC_SEND_FULL_ACTION action = HTC_SEND_FULL_KEEP;
2877 A_BOOL stopNet = FALSE;
2878 HTC_ENDPOINT_ID Endpoint = HTC_GET_ENDPOINT_FROM_PKT(pPacket);
2879
2880 do {
2881
2882 if (bypasswmi) {
2883 int accessClass;
2884
2885 if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) {
2886 /* don't drop special control packets */
2887 break;
2888 }
2889
2890 accessClass = arEndpoint2Ac(ar,Endpoint);
2891 /* for endpoint ping testing drop Best Effort and Background */
2892 if ((accessClass == WMM_AC_BE) || (accessClass == WMM_AC_BK)) {
2893 action = HTC_SEND_FULL_DROP;
2894 stopNet = FALSE;
2895 } else {
2896 /* keep but stop the netqueues */
2897 stopNet = TRUE;
2898 }
2899 break;
2900 }
2901
2902 if (Endpoint == ar->arControlEp) {
2903 /* under normal WMI if this is getting full, then something is r unning rampant
2904 * the host should not be exhausting the WMI queue with too many commands
2905 * the only exception to this is during testing using endpointpi ng */
2906 AR6000_SPIN_LOCK(&ar->arLock, 0);
2907 /* set flag to handle subsequent messages */
2908 ar->arWMIControlEpFull = TRUE;
2909 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2910 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI Control Endpoint is FULL!!! \n") );
2911 /* no need to stop the network */
2912 stopNet = FALSE;
2913 break;
2914 }
2915
2916 /* if we get here, we are dealing with data endpoints getting full */
2917
2918 if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) {
2919 /* don't drop control packets issued on ANY data endpoint */
2920 break;
2921 }
2922
2923 if (ar->arNetworkType == ADHOC_NETWORK) {
2924 /* in adhoc mode, we cannot differentiate traffic priorities so ther e is no need to
2925 * continue, however we should stop the network */
2926 stopNet = TRUE;
2927 break;
2928 }
2929 /* the last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for the hi ghest
2930 * active stream */
2931 if (ar->arAcStreamPriMap[arEndpoint2Ac(ar,Endpoint)] < ar->arHiAcStreamA ctivePri &&
2932 ar->arCookieCount <= MAX_HI_COOKIE_NUM) {
2933 /* this stream's priority is less than the highest active priori ty, we
2934 * give preference to the highest priority stream by directing
2935 * HTC to drop the packet that overflowed */
2936 action = HTC_SEND_FULL_DROP;
2937 /* since we are dropping packets, no need to stop the network */
2938 stopNet = FALSE;
2939 break;
2940 }
2941
2942 } while (FALSE);
2943
2944 if (stopNet) {
2945 AR6000_SPIN_LOCK(&ar->arLock, 0);
2946 ar->arNetQueueStopped = TRUE;
2947 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2948 /* one of the data endpoints queues is getting full..need to stop networ k stack
2949 * the queue will resume in ar6000_tx_complete() */
2950 netif_stop_queue(ar->arNetDev);
2951 }
2952
2953 return action;
2954 }
2955
2956
2957 static void
2958 ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue)
2959 {
2960 AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
2961 A_UINT32 mapNo = 0;
2962 A_STATUS status;
2963 struct ar_cookie * ar_cookie;
2964 HTC_ENDPOINT_ID eid;
2965 A_BOOL wakeEvent = FALSE;
2966 struct sk_buff_head skb_queue;
2967 HTC_PACKET *pPacket;
2968 struct sk_buff *pktSkb;
2969 A_BOOL flushing = FALSE;
2970
2971 skb_queue_head_init(&skb_queue);
2972
2973 /* lock the driver as we update internal state */
2974 AR6000_SPIN_LOCK(&ar->arLock, 0);
2975
2976 /* reap completed packets */
2977 while (!HTC_QUEUE_EMPTY(pPacketQueue)) {
2978
2979 pPacket = HTC_PACKET_DEQUEUE(pPacketQueue);
2980
2981 ar_cookie = (struct ar_cookie *)pPacket->pPktContext;
2982 A_ASSERT(ar_cookie);
2983
2984 status = pPacket->Status;
2985 pktSkb = (struct sk_buff *)ar_cookie->arc_bp[0];
2986 eid = pPacket->Endpoint;
2987 mapNo = ar_cookie->arc_bp[1];
2988
2989 A_ASSERT(pktSkb);
2990 A_ASSERT(pPacket->pBuffer == A_NETBUF_DATA(pktSkb));
2991
2992 /* add this to the list, use faster non-lock API */
2993 __skb_queue_tail(&skb_queue,pktSkb);
2994
2995 if (A_SUCCESS(status)) {
2996 A_ASSERT(pPacket->ActualLength == A_NETBUF_LEN(pktSkb));
2997 }
2998
2999 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_tx_complete skb=0x%x data=0x% x len=0x%x eid=%d ",
3000 (A_UINT32)pktSkb, (A_UINT32)pPacket->pBuffer,
3001 pPacket->ActualLength,
3002 eid));
3003
3004 ar->arTxPending[eid]--;
3005
3006 if ((eid != ar->arControlEp) || bypasswmi) {
3007 ar->arTotalTxDataPending--;
3008 }
3009
3010 if (eid == ar->arControlEp)
3011 {
3012 if (ar->arWMIControlEpFull) {
3013 /* since this packet completed, the WMI EP is no longer full */
3014 ar->arWMIControlEpFull = FALSE;
3015 }
3016
3017 if (ar->arTxPending[eid] == 0) {
3018 wakeEvent = TRUE;
3019 }
3020 }
3021
3022 if (A_FAILED(status)) {
3023 if (status == A_ECANCELED) {
3024 /* a packet was flushed */
3025 flushing = TRUE;
3026 }
3027 AR6000_STAT_INC(ar, tx_errors);
3028 if (status != A_NO_RESOURCE) {
3029 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() -TX ERROR, status: 0x%x\n", __func__,
3030 status));
3031 }
3032 } else {
3033 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("OK\n"));
3034 flushing = FALSE;
3035 AR6000_STAT_INC(ar, tx_packets);
3036 ar->arNetStats.tx_bytes += A_NETBUF_LEN(pktSkb);
3037 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
3038 aptcTR.bytesTransmitted += a_netbuf_to_len(pktSkb);
3039 applyAPTCHeuristics(ar);
3040 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
3041 }
3042
3043 // TODO this needs to be looked at
3044 if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable
3045 && (eid != ar->arControlEp) && mapNo)
3046 {
3047 mapNo --;
3048 ar->arNodeMap[mapNo].txPending --;
3049
3050 if (!ar->arNodeMap[mapNo].txPending && (mapNo == (ar->arNodeNum - 1) )) {
3051 A_UINT32 i;
3052 for (i = ar->arNodeNum; i > 0; i --) {
3053 if (!ar->arNodeMap[i - 1].txPending) {
3054 A_MEMZERO(&ar->arNodeMap[i - 1], sizeof(struct ar_node_m apping));
3055 ar->arNodeNum --;
3056 } else {
3057 break;
3058 }
3059 }
3060 }
3061 }
3062
3063 ar6000_free_cookie(ar, ar_cookie);
3064
3065 if (ar->arNetQueueStopped) {
3066 ar->arNetQueueStopped = FALSE;
3067 }
3068 }
3069
3070 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3071
3072 /* lock is released, we can freely call other kernel APIs */
3073
3074 /* free all skbs in our local list */
3075 while (!skb_queue_empty(&skb_queue)) {
3076 /* use non-lock version */
3077 pktSkb = __skb_dequeue(&skb_queue);
3078 A_NETBUF_FREE(pktSkb);
3079 }
3080
3081 if ((ar->arConnected == TRUE) || (bypasswmi)) {
3082 if (!flushing) {
3083 /* don't wake the queue if we are flushing, other wise it will j ust
3084 * keep queueing packets, which will keep failing */
3085 netif_wake_queue(ar->arNetDev);
3086 }
3087 }
3088
3089 if (wakeEvent) {
3090 wake_up(&arEvent);
3091 }
3092
3093 }
3094
3095 sta_t *
3096 ieee80211_find_conn(AR_SOFTC_T *ar, A_UINT8 *node_addr)
3097 {
3098 sta_t *conn = NULL;
3099 A_UINT8 i, max_conn;
3100
3101 switch(ar->arNetworkType) {
3102 case AP_NETWORK:
3103 max_conn = AP_MAX_NUM_STA;
3104 break;
3105 default:
3106 max_conn=0;
3107 break;
3108 }
3109
3110 for (i = 0; i < max_conn; i++) {
3111 if (IEEE80211_ADDR_EQ(node_addr, ar->sta_list[i].mac)) {
3112 conn = &ar->sta_list[i];
3113 break;
3114 }
3115 }
3116
3117 return conn;
3118 }
3119
3120 sta_t *ieee80211_find_conn_for_aid(AR_SOFTC_T *ar, A_UINT8 aid)
3121 {
3122 sta_t *conn = NULL;
3123 A_UINT8 ctr;
3124
3125 for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
3126 if (ar->sta_list[ctr].aid == aid) {
3127 conn = &ar->sta_list[ctr];
3128 break;
3129 }
3130 }
3131 return conn;
3132 }
3133
3134 /*
3135 * Receive event handler. This is called by HTC when a packet is received
3136 */
3137 int pktcount;
3138 static void
3139 ar6000_rx(void *Context, HTC_PACKET *pPacket)
3140 {
3141 AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
3142 struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext;
3143 int minHdrLen;
3144 A_UINT8 containsDot11Hdr = 0;
3145 A_STATUS status = pPacket->Status;
3146 HTC_ENDPOINT_ID ept = pPacket->Endpoint;
3147
3148 A_ASSERT((status != A_OK) ||
3149 (pPacket->pBuffer == (A_NETBUF_DATA(skb) + HTC_HEADER_LEN)));
3150
3151 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx ar=0x%x eid=%d, skb=0x%x, data =0x%x, len=0x%x status:%d",
3152 (A_UINT32)ar, ept, (A_UINT32)skb, (A_UINT32)pPacket->pBuffer ,
3153 pPacket->ActualLength, status));
3154 if (status != A_OK) {
3155 if (status != A_ECANCELED) {
3156 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("RX ERR (%d) \n",status));
3157 }
3158 }
3159
3160 /* take lock to protect buffer counts
3161 * and adaptive power throughput state */
3162 AR6000_SPIN_LOCK(&ar->arLock, 0);
3163
3164 if (A_SUCCESS(status)) {
3165 AR6000_STAT_INC(ar, rx_packets);
3166 ar->arNetStats.rx_bytes += pPacket->ActualLength;
3167 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
3168 aptcTR.bytesReceived += a_netbuf_to_len(skb);
3169 applyAPTCHeuristics(ar);
3170 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
3171
3172 A_NETBUF_PUT(skb, pPacket->ActualLength + HTC_HEADER_LEN);
3173 A_NETBUF_PULL(skb, HTC_HEADER_LEN);
3174
3175 #ifdef DEBUG
3176 if (debugdriver >= 2) {
3177 ar6000_dump_skb(skb);
3178 }
3179 #endif /* DEBUG */
3180 }
3181
3182 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3183
3184 skb->dev = ar->arNetDev;
3185 if (status != A_OK) {
3186 AR6000_STAT_INC(ar, rx_errors);
3187 A_NETBUF_FREE(skb);
3188 } else if (ar->arWmiEnabled == TRUE) {
3189 if (ept == ar->arControlEp) {
3190 /*
3191 * this is a wmi control msg
3192 */
3193 wmi_control_rx(ar->arWmi, skb);
3194 } else {
3195 WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb);
3196 A_UINT8 is_amsdu, tid, is_acl_data_frame;
3197 is_acl_data_frame = WMI_DATA_HDR_GET_DATA_TYPE(dhdr) == WMI_DATA _HDR_DATA_TYPE_ACL;
3198
3199 /*
3200 * this is a wmi data packet
3201 */
3202 // NWF
3203
3204 if (processDot11Hdr) {
3205 minHdrLen = sizeof(WMI_DATA_HDR) + sizeof(struct ieee80211_f rame) + sizeof(ATH_LLC_SNAP_HDR);
3206 } else {
3207 minHdrLen = sizeof (WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) +
3208 sizeof(ATH_LLC_SNAP_HDR);
3209 }
3210
3211 /* In the case of AP mode we may receive NULL data frames
3212 * that do not have LLC hdr. They are 16 bytes in size.
3213 * Allow these frames in the AP mode.
3214 * ACL data frames don't follow ethernet frame bounds for
3215 * min length
3216 */
3217 if (ar->arNetworkType != AP_NETWORK && !is_acl_data_frame &&
3218 ((pPacket->ActualLength < minHdrLen) ||
3219 (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)))
3220 {
3221 /*
3222 * packet is too short or too long
3223 */
3224 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("TOO SHORT or TOO LONG\n"));
3225 AR6000_STAT_INC(ar, rx_errors);
3226 AR6000_STAT_INC(ar, rx_length_errors);
3227 A_NETBUF_FREE(skb);
3228 } else {
3229 A_UINT16 seq_no;
3230 A_UINT8 meta_type;
3231
3232 #if 0
3233 /* Access RSSI values here */
3234 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("RSSI %d\n",
3235 ((WMI_DATA_HDR *) A_NETBUF_DATA(skb))->rssi));
3236 #endif
3237 /* Get the Power save state of the STA */
3238 if (ar->arNetworkType == AP_NETWORK) {
3239 sta_t *conn = NULL;
3240 A_UINT8 psState=0,prevPsState;
3241 ATH_MAC_HDR *datap=NULL;
3242 A_UINT16 offset;
3243
3244 meta_type = WMI_DATA_HDR_GET_META(dhdr);
3245
3246 psState = (((WMI_DATA_HDR *)A_NETBUF_DATA(skb))->info
3247 >> WMI_DATA_HDR_PS_SHIFT) & WMI_DATA_HDR_PS _MASK;
3248
3249 offset = sizeof(WMI_DATA_HDR);
3250
3251 switch (meta_type) {
3252 case 0:
3253 break;
3254 case WMI_META_VERSION_1:
3255 offset += sizeof(WMI_RX_META_V1);
3256 break;
3257 #ifdef CONFIG_CHECKSUM_OFFLOAD
3258 case WMI_META_VERSION_2:
3259 offset += sizeof(WMI_RX_META_V2);
3260 break;
3261 #endif
3262 default:
3263 break;
3264 }
3265
3266 datap = (ATH_MAC_HDR *)(A_NETBUF_DATA(skb)+offset);
3267 conn = ieee80211_find_conn(ar, datap->srcMac);
3268
3269 if (conn) {
3270 /* if there is a change in PS state of the STA,
3271 * take appropriate steps.
3272 * 1. If Sleep-->Awake, flush the psq for the STA
3273 * Clear the PVB for the STA.
3274 * 2. If Awake-->Sleep, Starting queueing frames
3275 * the STA.
3276 */
3277 prevPsState = STA_IS_PWR_SLEEP(conn);
3278 if (psState) {
3279 STA_SET_PWR_SLEEP(conn);
3280 } else {
3281 STA_CLR_PWR_SLEEP(conn);
3282 }
3283
3284 if (prevPsState ^ STA_IS_PWR_SLEEP(conn)) {
3285
3286 if (!STA_IS_PWR_SLEEP(conn)) {
3287
3288 A_MUTEX_LOCK(&conn->psqLock);
3289 while (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) {
3290 struct sk_buff *skb=NULL;
3291
3292 skb = A_NETBUF_DEQUEUE(&conn->psq);
3293 A_MUTEX_UNLOCK(&conn->psqLock);
3294 ar6000_data_tx(skb,ar->arNetDev);
3295 A_MUTEX_LOCK(&conn->psqLock);
3296 }
3297 A_MUTEX_UNLOCK(&conn->psqLock);
3298 /* Clear the PVB for this STA */
3299 wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
3300 }
3301 }
3302 } else {
3303 /* This frame is from a STA that is not associated*/
3304 A_ASSERT(FALSE);
3305 }
3306
3307 /* Drop NULL data frames here */
3308 if((pPacket->ActualLength < minHdrLen) ||
3309 (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_S IZE)) {
3310 A_NETBUF_FREE(skb);
3311 goto rx_done;
3312 }
3313 }
3314
3315 is_amsdu = WMI_DATA_HDR_IS_AMSDU(dhdr);
3316 tid = WMI_DATA_HDR_GET_UP(dhdr);
3317 seq_no = WMI_DATA_HDR_GET_SEQNO(dhdr);
3318 meta_type = WMI_DATA_HDR_GET_META(dhdr);
3319 containsDot11Hdr = WMI_DATA_HDR_GET_DOT11(dhdr);
3320
3321 wmi_data_hdr_remove(ar->arWmi, skb);
3322
3323 switch (meta_type) {
3324 case WMI_META_VERSION_1:
3325 {
3326 WMI_RX_META_V1 *pMeta = (WMI_RX_META_V1 *)A_NETB UF_DATA(skb);
3327 A_PRINTF("META %d %d %d %d %x\n", pMeta->status, pMeta->rix, pMeta->rssi, pMeta->channel, pMeta->flags);
3328 A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V1) );
3329 break;
3330 }
3331 #ifdef CONFIG_CHECKSUM_OFFLOAD
3332 case WMI_META_VERSION_2:
3333 {
3334 WMI_RX_META_V2 *pMeta = (WMI_RX_META_V2 *)A_NETB UF_DATA(skb);
3335 if(pMeta->csumFlags & 0x1){
3336 skb->ip_summed=CHECKSUM_COMP LETE;
3337 skb->csum=(pMeta->csum);
3338 }
3339 A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V2) );
3340 break;
3341 }
3342 #endif
3343 default:
3344 break;
3345 }
3346 /* NWF: print the 802.11 hdr bytes */
3347 if(containsDot11Hdr) {
3348 wmi_dot11_hdr_remove(ar->arWmi,skb);
3349 } else if(!is_amsdu && !is_acl_data_frame) {
3350 wmi_dot3_2_dix(skb);
3351 }
3352
3353 if (is_acl_data_frame) {
3354 A_NETBUF_PUSH(skb, sizeof(int));
3355 *((short *)A_NETBUF_DATA(skb)) = WMI_ACL_DATA_EVENTID;
3356 }
3357 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
3358 /*
3359 * extra push and memcpy, for eth_type_trans() of 2.4 kernel
3360 * will pull out hard_header_len bytes of the skb.
3361 */
3362 A_NETBUF_PUSH(skb, sizeof(WMI_DATA_HDR) + sizeof(ATH_LLC_SNA P_HDR) + HTC_HEADER_LEN);
3363 A_MEMCPY(A_NETBUF_DATA(skb), A_NETBUF_DATA(skb) + sizeof(WMI _DATA_HDR) +
3364 sizeof(ATH_LLC_SNAP_HDR) + HTC_HEADER_LEN, sizeof(A TH_MAC_HDR));
3365 #endif
3366 if ((ar->arNetDev->flags & IFF_UP) == IFF_UP) {
3367 if (ar->arNetworkType == AP_NETWORK) {
3368 struct sk_buff *skb1 = NULL;
3369 ATH_MAC_HDR *datap;
3370
3371 datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
3372 if (IEEE80211_IS_MULTICAST(datap->dstMac)) {
3373 /* Bcast/Mcast frames should be sent to the OS
3374 * stack as well as on the air.
3375 */
3376 skb1 = skb_copy(skb,GFP_ATOMIC);
3377 } else {
3378 /* Search for a connected STA with dstMac as
3379 * the Mac address. If found send the frame to
3380 * it on the air else send the frame up the
3381 * stack
3382 */
3383 sta_t *conn = NULL;
3384 conn = ieee80211_find_conn(ar, datap->dstMac);
3385
3386 if (conn && ar->intra_bss) {
3387 skb1 = skb;
3388 skb = NULL;
3389 } else if(conn && !ar->intra_bss) {
3390 A_NETBUF_FREE(skb);
3391 skb = NULL;
3392 }
3393 }
3394 if (skb1) {
3395 ar6000_data_tx(skb1, ar->arNetDev);
3396 }
3397 }
3398 }
3399 #ifdef ATH_AR6K_11N_SUPPORT
3400 aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no, is_amsdu, (void **)&skb);
3401 #endif
3402 ar6000_deliver_frames_to_nw_stack((void *) ar->arNetDev, (vo id *)skb);
3403 }
3404 }
3405 } else {
3406 ar6000_deliver_frames_to_nw_stack((void *)ar->arNetDev, (void *)skb);
3407 }
3408
3409 rx_done:
3410
3411 return;
3412 }
3413
3414 static void
3415 ar6000_deliver_frames_to_nw_stack(void *dev, void *osbuf)
3416 {
3417 struct sk_buff *skb = (struct sk_buff *)osbuf;
3418
3419 if(skb) {
3420 skb->dev = dev;
3421 if ((skb->dev->flags & IFF_UP) == IFF_UP) {
3422 skb->protocol = eth_type_trans(skb, skb->dev);
3423 netif_rx(skb);
3424 } else {
3425 A_NETBUF_FREE(skb);
3426 }
3427 }
3428 }
3429
3430 #if 0
3431 static void
3432 ar6000_deliver_frames_to_bt_stack(void *dev, void *osbuf)
3433 {
3434 struct sk_buff *skb = (struct sk_buff *)osbuf;
3435
3436 if(skb) {
3437 skb->dev = dev;
3438 if ((skb->dev->flags & IFF_UP) == IFF_UP) {
3439 skb->protocol = htons(ETH_P_CONTROL);
3440 netif_rx(skb);
3441 } else {
3442 A_NETBUF_FREE(skb);
3443 }
3444 }
3445 }
3446 #endif
3447
3448 static void
3449 ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint)
3450 {
3451 AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
3452 void *osBuf;
3453 int RxBuffers;
3454 int buffersToRefill;
3455 HTC_PACKET *pPacket;
3456 HTC_PACKET_QUEUE queue;
3457
3458 buffersToRefill = (int)AR6000_MAX_RX_BUFFERS -
3459 HTCGetNumRecvBuffers(ar->arHtcTarget, Endpoi nt);
3460
3461 if (buffersToRefill <= 0) {
3462 /* fast return, nothing to fill */
3463 return;
3464 }
3465
3466 INIT_HTC_PACKET_QUEUE(&queue);
3467
3468 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx_refill: providing htc with %d buffers at eid=%d\n",
3469 buffersToRefill, Endpoint));
3470
3471 for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) {
3472 osBuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE);
3473 if (NULL == osBuf) {
3474 break;
3475 }
3476 /* the HTC packet wrapper is at the head of the reserved area
3477 * in the skb */
3478 pPacket = (HTC_PACKET *)(A_NETBUF_HEAD(osBuf));
3479 /* set re-fill info */
3480 SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_ BUFFER_SIZE,Endpoint);
3481 /* add to queue */
3482 HTC_PACKET_ENQUEUE(&queue,pPacket);
3483 }
3484
3485 if (!HTC_QUEUE_EMPTY(&queue)) {
3486 /* add packets */
3487 HTCAddReceivePktMultiple(ar->arHtcTarget, &queue);
3488 }
3489
3490 }
3491
3492 /* clean up our amsdu buffer list */
3493 static void ar6000_cleanup_amsdu_rxbufs(AR_SOFTC_T *ar)
3494 {
3495 HTC_PACKET *pPacket;
3496 void *osBuf;
3497
3498 /* empty AMSDU buffer queue and free OS bufs */
3499 while (TRUE) {
3500
3501 AR6000_SPIN_LOCK(&ar->arLock, 0);
3502 pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue);
3503 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3504
3505 if (NULL == pPacket) {
3506 break;
3507 }
3508
3509 osBuf = pPacket->pPktContext;
3510 if (NULL == osBuf) {
3511 A_ASSERT(FALSE);
3512 break;
3513 }
3514
3515 A_NETBUF_FREE(osBuf);
3516 }
3517
3518 }
3519
3520
3521 /* refill the amsdu buffer list */
3522 static void ar6000_refill_amsdu_rxbufs(AR_SOFTC_T *ar, int Count)
3523 {
3524 HTC_PACKET *pPacket;
3525 void *osBuf;
3526
3527 while (Count > 0) {
3528 osBuf = A_NETBUF_ALLOC(AR6000_AMSDU_BUFFER_SIZE);
3529 if (NULL == osBuf) {
3530 break;
3531 }
3532 /* the HTC packet wrapper is at the head of the reserved area
3533 * in the skb */
3534 pPacket = (HTC_PACKET *)(A_NETBUF_HEAD(osBuf));
3535 /* set re-fill info */
3536 SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_ AMSDU_BUFFER_SIZE,0);
3537
3538 AR6000_SPIN_LOCK(&ar->arLock, 0);
3539 /* put it in the list */
3540 HTC_PACKET_ENQUEUE(&ar->amsdu_rx_buffer_queue,pPacket);
3541 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3542 Count--;
3543 }
3544
3545 }
3546
3547 /* callback to allocate a large receive buffer for a pending packet. This f unction is called when
3548 * an HTC packet arrives whose length exceeds a threshold value
3549 *
3550 * We use a pre-allocated list of buffers of maximum AMSDU size (4K). Under linux it is more optimal to
3551 * keep the allocation size the same to optimize cached-slab allocations.
3552 *
3553 * */
3554 static HTC_PACKET *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpo int, int Length)
3555 {
3556 HTC_PACKET *pPacket = NULL;
3557 AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
3558 int refillCount = 0;
3559
3560 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_alloc_amsdu_rxbuf: eid=%d, Length :%d\n",Endpoint,Length));
3561
3562 do {
3563
3564 if (Length <= AR6000_BUFFER_SIZE) {
3565 /* shouldn't be getting called on normal sized packets */
3566 A_ASSERT(FALSE);
3567 break;
3568 }
3569
3570 if (Length > AR6000_AMSDU_BUFFER_SIZE) {
3571 A_ASSERT(FALSE);
3572 break;
3573 }
3574
3575 AR6000_SPIN_LOCK(&ar->arLock, 0);
3576 /* allocate a packet from the list */
3577 pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue);
3578 /* see if we need to refill again */
3579 refillCount = AR6000_MAX_AMSDU_RX_BUFFERS - HTC_PACKET_QUEUE_DEPTH(&ar-> amsdu_rx_buffer_queue);
3580 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3581
3582 if (NULL == pPacket) {
3583 break;
3584 }
3585 /* set actual endpoint ID */
3586 pPacket->Endpoint = Endpoint;
3587
3588 } while (FALSE);
3589
3590 if (refillCount >= AR6000_AMSDU_REFILL_THRESHOLD) {
3591 ar6000_refill_amsdu_rxbufs(ar,refillCount);
3592 }
3593
3594 return pPacket;
3595 }
3596
3597
3598 static struct net_device_stats *
3599 ar6000_get_stats(struct net_device *dev)
3600 {
3601 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
3602 return &ar->arNetStats;
3603 }
3604
3605 static struct iw_statistics *
3606 ar6000_get_iwstats(struct net_device * dev)
3607 {
3608 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
3609 TARGET_STATS *pStats = &ar->arTargetStats;
3610 struct iw_statistics * pIwStats = &ar->arIwStats;
3611
3612 if (ar->bIsDestroyProgress || ar->arWmiReady == FALSE)
3613 {
3614 pIwStats->status = 0;
3615 pIwStats->qual.qual = 0;
3616 pIwStats->qual.level =0;
3617 pIwStats->qual.noise = 0;
3618 pIwStats->discard.code =0;
3619 pIwStats->discard.retries=0;
3620 pIwStats->miss.beacon =0;
3621 return pIwStats;
3622 }
3623 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
3624 /*
3625 * The in_atomic function is used to determine if the scheduling is
3626 * allowed in the current context or not. This was introduced in 2.6
3627 * From what I have read on the differences between 2.4 and 2.6, the
3628 * 2.4 kernel did not support preemption and so this check might not
3629 * be required for 2.4 kernels.
3630 */
3631 if (in_atomic())
3632 {
3633 wmi_get_stats_cmd(ar->arWmi);
3634
3635 pIwStats->status = 1 ;
3636 pIwStats->qual.qual = pStats->cs_aveBeacon_rssi - 161;
3637 pIwStats->qual.level =pStats->cs_aveBeacon_rssi; /* noise is -95 dBm */
3638 pIwStats->qual.noise = pStats->noise_floor_calibation;
3639 pIwStats->discard.code = pStats->rx_decrypt_err;
3640 pIwStats->discard.retries = pStats->tx_retry_cnt;
3641 pIwStats->miss.beacon = pStats->cs_bmiss_cnt;
3642 return pIwStats;
3643 }
3644 #endif /* LINUX_VERSION_CODE */
3645
3646 if (down_interruptible(&ar->arSem)) {
3647 pIwStats->status = 0;
3648 return pIwStats;
3649 }
3650
3651 if (ar->bIsDestroyProgress) {
3652 up(&ar->arSem);
3653 pIwStats->status = 0;
3654 return pIwStats;
3655 }
3656
3657 ar->statsUpdatePending = TRUE;
3658
3659 if(wmi_get_stats_cmd(ar->arWmi) != A_OK) {
3660 up(&ar->arSem);
3661 pIwStats->status = 0;
3662 return pIwStats;
3663 }
3664
3665 dev_hold(dev);
3666 rtnl_unlock();
3667 wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, w mitimeout * HZ);
3668 rtnl_lock();
3669 dev_put(dev);
3670
3671 if (signal_pending(current)) {
3672 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000 : WMI get stats timeout \n"));
3673 up(&ar->arSem);
3674 pIwStats->status = 0;
3675 return pIwStats;
3676 }
3677 pIwStats->status = 1 ;
3678 pIwStats->qual.qual = pStats->cs_aveBeacon_rssi - 161;
3679 pIwStats->qual.level =pStats->cs_aveBeacon_rssi; /* noise is -95 dBm */
3680 pIwStats->qual.noise = pStats->noise_floor_calibation;
3681 pIwStats->discard.code = pStats->rx_decrypt_err;
3682 pIwStats->discard.retries = pStats->tx_retry_cnt;
3683 pIwStats->miss.beacon = pStats->cs_bmiss_cnt;
3684 up(&ar->arSem);
3685 return pIwStats;
3686 }
3687
3688 void
3689 ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap, A_UINT32 vers)
3690 {
3691 AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
3692 struct net_device *dev = ar->arNetDev;
3693
3694 ar->arWmiReady = TRUE;
3695 wake_up(&arEvent);
3696 A_MEMCPY(dev->dev_addr, datap, AR6000_ETH_ADDR_LEN);
3697 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x :%2.2x\n",
3698 dev->dev_addr[0], dev->dev_addr[1],
3699 dev->dev_addr[2], dev->dev_addr[3],
3700 dev->dev_addr[4], dev->dev_addr[5]));
3701
3702 ar->arPhyCapability = phyCap;
3703 ar->arVersion.wlan_ver = vers;
3704
3705 #if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN
3706 wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURI NG_SCAN);
3707 #endif
3708 #if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP
3709 wmi_set_lpreamble_cmd(ar->arWmi, 0, WMI_DONOT_IGNORE_BARKER_IN_ERP);
3710 #endif
3711 }
3712
3713 A_UINT8
3714 add_new_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 aid, A_UINT8 *wpaie,
3715 A_UINT8 ielen, A_UINT8 keymgmt, A_UINT8 ucipher, A_UINT8 auth)
3716 {
3717 A_INT8 free_slot=-1, i;
3718
3719 for(i=0; i < AP_MAX_NUM_STA; i++) {
3720 if(A_MEMCMP(ar->sta_list[i].mac, mac, ATH_MAC_LEN)==0) {
3721 /* it is already available */
3722 return 0;
3723 }
3724
3725 if(!((1 << i) & ar->sta_list_index)) {
3726 free_slot = i;
3727 break;
3728 }
3729 }
3730
3731 if(free_slot >= 0) {
3732 A_MEMCPY(ar->sta_list[free_slot].mac, mac, ATH_MAC_LEN);
3733 A_MEMCPY(ar->sta_list[free_slot].wpa_ie, wpaie, ielen);
3734 ar->sta_list[free_slot].aid = aid;
3735 ar->sta_list[free_slot].keymgmt = keymgmt;
3736 ar->sta_list[free_slot].ucipher = ucipher;
3737 ar->sta_list[free_slot].auth = auth;
3738 ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
3739 ar->arAPStats.sta[aid-1].aid = aid;
3740 return 1;
3741 }
3742 return 0; /* not added */
3743 }
3744
3745 void
3746 ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_UINT8 *bssid,
3747 A_UINT16 listenInterval, A_UINT16 beaconInterval,
3748 NETWORK_TYPE networkType, A_UINT8 beaconIeLen,
3749 A_UINT8 assocReqLen, A_UINT8 assocRespLen,
3750 A_UINT8 *assocInfo)
3751 {
3752 union iwreq_data wrqu;
3753 int i, beacon_ie_pos, assoc_resp_ie_pos, assoc_req_ie_pos;
3754 static const char *tag1 = "ASSOCINFO(ReqIEs=";
3755 static const char *tag2 = "ASSOCRESPIE=";
3756 static const char *beaconIetag = "BEACONIE=";
3757 char buf[WMI_CONTROL_MSG_MAX_LEN * 2 + strlen(tag1) + 1];
3758 char *pos;
3759 A_UINT8 key_op_ctrl;
3760 unsigned long flags;
3761 struct ieee80211req_key *ik;
3762 CRYPTO_TYPE keyType = NONE_CRYPT;
3763
3764 if(ar->arNetworkType & AP_NETWORK) {
3765 struct net_device *dev = ar->arNetDev;
3766 if(A_MEMCMP(dev->dev_addr, bssid, ATH_MAC_LEN)==0) {
3767 ar->arACS = channel;
3768 ik = &ar->ap_mode_bkey;
3769
3770 switch(ar->arAuthMode) {
3771 case NONE_AUTH:
3772 if(ar->arPairwiseCrypto == WEP_CRYPT) {
3773 ar6000_install_static_wep_keys(ar);
3774 }
3775 #ifdef WAPI_ENABLE
3776 else if(ar->arPairwiseCrypto == WAPI_CRYPT) {
3777 ap_set_wapi_key(ar, ik);
3778 }
3779 #endif
3780 break;
3781 case WPA_PSK_AUTH:
3782 case WPA2_PSK_AUTH:
3783 case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
3784 switch (ik->ik_type) {
3785 case IEEE80211_CIPHER_TKIP:
3786 keyType = TKIP_CRYPT;
3787 break;
3788 case IEEE80211_CIPHER_AES_CCM:
3789 keyType = AES_CRYPT;
3790 break;
3791 default:
3792 goto skip_key;
3793 }
3794 wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, GROUP_USAGE,
3795 ik->ik_keylen, (A_UINT8 *)&ik->ik_keyrsc,
3796 ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
3797 SYNC_BOTH_WMIFLAG);
3798
3799 break;
3800 }
3801 skip_key:
3802 ar->arConnected = TRUE;
3803 return;
3804 }
3805
3806 A_PRINTF("NEW STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n "
3807 " AID=%d \n", bssid[0], bssid[1], bssid[2],
3808 bssid[3], bssid[4], bssid[5], channel);
3809 switch ((listenInterval>>8)&0xFF) {
3810 case OPEN_AUTH:
3811 A_PRINTF("AUTH: OPEN\n");
3812 break;
3813 case SHARED_AUTH:
3814 A_PRINTF("AUTH: SHARED\n");
3815 break;
3816 default:
3817 A_PRINTF("AUTH: Unknown\n");
3818 break;
3819 };
3820 switch (listenInterval&0xFF) {
3821 case WPA_PSK_AUTH:
3822 A_PRINTF("KeyMgmt: WPA-PSK\n");
3823 break;
3824 case WPA2_PSK_AUTH:
3825 A_PRINTF("KeyMgmt: WPA2-PSK\n");
3826 break;
3827 default:
3828 A_PRINTF("KeyMgmt: NONE\n");
3829 break;
3830 };
3831 switch (beaconInterval) {
3832 case AES_CRYPT:
3833 A_PRINTF("Cipher: AES\n");
3834 break;
3835 case TKIP_CRYPT:
3836 A_PRINTF("Cipher: TKIP\n");
3837 break;
3838 case WEP_CRYPT:
3839 A_PRINTF("Cipher: WEP\n");
3840 break;
3841 #ifdef WAPI_ENABLE
3842 case WAPI_CRYPT:
3843 A_PRINTF("Cipher: WAPI\n");
3844 break;
3845 #endif
3846 default:
3847 A_PRINTF("Cipher: NONE\n");
3848 break;
3849 };
3850
3851 add_new_sta(ar, bssid, channel /*aid*/,
3852 assocInfo /* WPA IE */, assocRespLen /* IE len */,
3853 listenInterval&0xFF /* Keymgmt */, beaconInterval /* cipher */,
3854 (listenInterval>>8)&0xFF /* auth alg */);
3855
3856 /* Send event to application */
3857 A_MEMZERO(&wrqu, sizeof(wrqu));
3858 A_MEMCPY(wrqu.addr.sa_data, bssid, ATH_MAC_LEN);
3859 wireless_send_event(ar->arNetDev, IWEVREGISTERED, &wrqu, NULL);
3860 /* In case the queue is stopped when we switch modes, this will
3861 * wake it up
3862 */
3863 netif_wake_queue(ar->arNetDev);
3864 return;
3865 }
3866
3867 #ifdef CONFIG_CFG80211
3868 ar6k_cfg80211_connect_event(ar, channel, bssid,
3869 listenInterval, beaconInterval,
3870 networkType, beaconIeLen,
3871 assocReqLen, assocRespLen,
3872 assocInfo);
3873 #endif /* CONFIG_CFG80211 */
3874
3875 A_MEMCPY(ar->arBssid, bssid, sizeof(ar->arBssid));
3876 ar->arBssChannel = channel;
3877
3878 A_PRINTF("AR6000 connected event on freq %d ", channel);
3879 A_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
3880 " listenInterval=%d, beaconInterval = %d, beaconIeLen = %d assocReqL en=%d"
3881 " assocRespLen =%d\n",
3882 bssid[0], bssid[1], bssid[2],
3883 bssid[3], bssid[4], bssid[5],
3884 listenInterval, beaconInterval,
3885 beaconIeLen, assocReqLen, assocRespLen);
3886 if (networkType & ADHOC_NETWORK) {
3887 if (networkType & ADHOC_CREATOR) {
3888 A_PRINTF("Network: Adhoc (Creator)\n");
3889 } else {
3890 A_PRINTF("Network: Adhoc (Joiner)\n");
3891 }
3892 } else {
3893 A_PRINTF("Network: Infrastructure\n");
3894 }
3895
3896 if (beaconIeLen && (sizeof(buf) > (9 + beaconIeLen * 2))) {
3897 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nBeaconIEs= "));
3898
3899 beacon_ie_pos = 0;
3900 A_MEMZERO(buf, sizeof(buf));
3901 sprintf(buf, "%s", beaconIetag);
3902 pos = buf + 9;
3903 for (i = beacon_ie_pos; i < beacon_ie_pos + beaconIeLen; i++) {
3904 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
3905 sprintf(pos, "%2.2x", assocInfo[i]);
3906 pos += 2;
3907 }
3908 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
3909
3910 A_MEMZERO(&wrqu, sizeof(wrqu));
3911 wrqu.data.length = strlen(buf);
3912 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
3913 }
3914
3915 if (assocRespLen && (sizeof(buf) > (12 + (assocRespLen * 2))))
3916 {
3917 assoc_resp_ie_pos = beaconIeLen + assocReqLen +
3918 sizeof(A_UINT16) + /* capinfo*/
3919 sizeof(A_UINT16) + /* status Code */
3920 sizeof(A_UINT16) ; /* associd */
3921 A_MEMZERO(buf, sizeof(buf));
3922 sprintf(buf, "%s", tag2);
3923 pos = buf + 12;
3924 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocRespIEs= "));
3925 /*
3926 * The Association Response Frame w.o. the WLAN header is delivered to
3927 * the host, so skip over to the IEs
3928 */
3929 for (i = assoc_resp_ie_pos; i < assoc_resp_ie_pos + assocRespLen - 6; i+ +)
3930 {
3931 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
3932 sprintf(pos, "%2.2x", assocInfo[i]);
3933 pos += 2;
3934 }
3935 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
3936
3937 A_MEMZERO(&wrqu, sizeof(wrqu));
3938 wrqu.data.length = strlen(buf);
3939 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
3940 }
3941
3942 if (assocReqLen && (sizeof(buf) > (17 + (assocReqLen * 2)))) {
3943 /*
3944 * assoc Request includes capability and listen interval. Skip these.
3945 */
3946 assoc_req_ie_pos = beaconIeLen +
3947 sizeof(A_UINT16) + /* capinfo*/
3948 sizeof(A_UINT16); /* listen interval */
3949
3950 A_MEMZERO(buf, sizeof(buf));
3951 sprintf(buf, "%s", tag1);
3952 pos = buf + 17;
3953 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("AssocReqIEs= "));
3954 for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen - 4; i++) {
3955 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
3956 sprintf(pos, "%2.2x", assocInfo[i]);
3957 pos += 2;;
3958 }
3959 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
3960
3961 A_MEMZERO(&wrqu, sizeof(wrqu));
3962 wrqu.data.length = strlen(buf);
3963 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
3964 }
3965
3966 #ifdef USER_KEYS
3967 if (ar->user_savedkeys_stat == USER_SAVEDKEYS_STAT_RUN &&
3968 ar->user_saved_keys.keyOk == TRUE)
3969 {
3970 key_op_ctrl = KEY_OP_VALID_MASK & ~KEY_OP_INIT_TSC;
3971
3972 if (ar->user_key_ctrl & AR6000_USER_SETKEYS_RSC_UNCHANGED) {
3973 key_op_ctrl &= ~KEY_OP_INIT_RSC;
3974 } else {
3975 key_op_ctrl |= KEY_OP_INIT_RSC;
3976 }
3977 ar6000_reinstall_keys(ar, key_op_ctrl);
3978 }
3979 #endif /* USER_KEYS */
3980
3981 netif_wake_queue(ar->arNetDev);
3982
3983 if ((networkType & ADHOC_NETWORK) &&
3984 (OPEN_AUTH == ar->arDot11AuthMode) &&
3985 (NONE_AUTH == ar->arAuthMode) &&
3986 (WEP_CRYPT == ar->arPairwiseCrypto))
3987 {
3988 if (!ar->arConnected) {
3989 wmi_addKey_cmd(ar->arWmi,
3990 ar->arDefTxKeyIndex,
3991 WEP_CRYPT,
3992 GROUP_USAGE | TX_USAGE,
3993 ar->arWepKeyList[ar->arDefTxKeyIndex].arKeyLen,
3994 NULL,
3995 ar->arWepKeyList[ar->arDefTxKeyIndex].arKey, KEY_OP_I NIT_VAL, NULL,
3996 NO_SYNC_WMIFLAG);
3997 }
3998 }
3999
4000 /* Update connect & link status atomically */
4001 spin_lock_irqsave(&ar->arLock, flags);
4002 ar->arConnected = TRUE;
4003 ar->arConnectPending = FALSE;
4004 netif_carrier_on(ar->arNetDev);
4005 spin_unlock_irqrestore(&ar->arLock, flags);
4006 /* reset the rx aggr state */
4007 aggr_reset_state(ar->aggr_cntxt);
4008 reconnect_flag = 0;
4009
4010 A_MEMZERO(&wrqu, sizeof(wrqu));
4011 A_MEMCPY(wrqu.addr.sa_data, bssid, IEEE80211_ADDR_LEN);
4012 wrqu.addr.sa_family = ARPHRD_ETHER;
4013 wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
4014 if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable) {
4015 A_MEMZERO(ar->arNodeMap, sizeof(ar->arNodeMap));
4016 ar->arNodeNum = 0;
4017 ar->arNexEpId = ENDPOINT_2;
4018 }
4019 if (!ar->arUserBssFilter) {
4020 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4021 }
4022
4023 }
4024
4025 void ar6000_set_numdataendpts(AR_SOFTC_T *ar, A_UINT32 num)
4026 {
4027 A_ASSERT(num <= (HTC_MAILBOX_NUM_MAX - 1));
4028 ar->arNumDataEndPts = num;
4029 }
4030
4031 void
4032 sta_cleanup(AR_SOFTC_T *ar, A_UINT8 i)
4033 {
4034 struct sk_buff *skb;
4035
4036 /* empty the queued pkts in the PS queue if any */
4037 A_MUTEX_LOCK(&ar->sta_list[i].psqLock);
4038 while (!A_NETBUF_QUEUE_EMPTY(&ar->sta_list[i].psq)) {
4039 skb = A_NETBUF_DEQUEUE(&ar->sta_list[i].psq);
4040 A_NETBUF_FREE(skb);
4041 }
4042 A_MUTEX_UNLOCK(&ar->sta_list[i].psqLock);
4043
4044 /* Zero out the state fields */
4045 A_MEMZERO(&ar->arAPStats.sta[ar->sta_list[i].aid-1], sizeof(WMI_PER_STA_STAT ));
4046 A_MEMZERO(&ar->sta_list[i].mac, ATH_MAC_LEN);
4047 A_MEMZERO(&ar->sta_list[i].wpa_ie, IEEE80211_MAX_IE);
4048 ar->sta_list[i].aid = 0;
4049 ar->sta_list[i].flags = 0;
4050
4051 ar->sta_list_index = ar->sta_list_index & ~(1 << i);
4052
4053 }
4054
4055 A_UINT8
4056 remove_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 reason)
4057 {
4058 A_UINT8 i, removed=0;
4059
4060 if(IS_MAC_NULL(mac)) {
4061 return removed;
4062 }
4063
4064 if(IS_MAC_BCAST(mac)) {
4065 A_PRINTF("DEL ALL STA\n");
4066 for(i=0; i < AP_MAX_NUM_STA; i++) {
4067 if(!IS_MAC_NULL(ar->sta_list[i].mac)) {
4068 sta_cleanup(ar, i);
4069 removed = 1;
4070 }
4071 }
4072 } else {
4073 for(i=0; i < AP_MAX_NUM_STA; i++) {
4074 if(A_MEMCMP(ar->sta_list[i].mac, mac, ATH_MAC_LEN)==0) {
4075 A_PRINTF("DEL STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
4076 " aid=%d REASON=%d\n", mac[0], mac[1], mac[2],
4077 mac[3], mac[4], mac[5], ar->sta_list[i].aid, reason);
4078
4079 sta_cleanup(ar, i);
4080 removed = 1;
4081 break;
4082 }
4083 }
4084 }
4085 return removed;
4086 }
4087
4088 void
4089 ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid,
4090 A_UINT8 assocRespLen, A_UINT8 *assocInfo, A_UINT16 proto colReasonStatus)
4091 {
4092 A_UINT8 i;
4093 unsigned long flags;
4094
4095 if(ar->arNetworkType & AP_NETWORK) {
4096 union iwreq_data wrqu;
4097 struct sk_buff *skb;
4098
4099 if(!remove_sta(ar, bssid, protocolReasonStatus)) {
4100 return;
4101 }
4102
4103 /* If there are no more associated STAs, empty the mcast PS q */
4104 if (ar->sta_list_index == 0) {
4105 A_MUTEX_LOCK(&ar->mcastpsqLock);
4106 while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
4107 skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
4108 A_NETBUF_FREE(skb);
4109 }
4110 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
4111
4112 /* Clear the LSB of the BitMapCtl field of the TIM IE */
4113 wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
4114 }
4115
4116 if(!IS_MAC_BCAST(bssid)) {
4117 /* Send event to application */
4118 A_MEMZERO(&wrqu, sizeof(wrqu));
4119 A_MEMCPY(wrqu.addr.sa_data, bssid, ATH_MAC_LEN);
4120 wireless_send_event(ar->arNetDev, IWEVEXPIRED, &wrqu, NULL);
4121 }
4122 return;
4123 }
4124
4125 #ifdef CONFIG_CFG80211
4126 ar6k_cfg80211_disconnect_event(ar, reason, bssid,
4127 assocRespLen, assocInfo,
4128 protocolReasonStatus);
4129 #endif /* CONFIG_CFG80211 */
4130
4131 if (NO_NETWORK_AVAIL != reason)
4132 {
4133 union iwreq_data wrqu;
4134 A_MEMZERO(&wrqu, sizeof(wrqu));
4135 wrqu.addr.sa_family = ARPHRD_ETHER;
4136
4137 /* Send disconnect event to supplicant */
4138 wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
4139 }
4140 /* it is necessary to clear the host-side rx aggregation state */
4141
4142 aggr_reset_state(ar->aggr_cntxt);
4143
4144 A_UNTIMEOUT(&ar->disconnect_timer);
4145
4146 A_PRINTF("AR6000 disconnected");
4147 if (bssid[0] || bssid[1] || bssid[2] || bssid[3] || bssid[4] || bssid[5]) {
4148 A_PRINTF(" from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
4149 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
4150 }
4151
4152 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nDisconnect Reason is %d", reason) );
4153 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nProtocol Reason/Status Code is %d ", protocolReasonStatus));
4154 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocResp Frame = %s",
4155 assocRespLen ? " " : "NULL"));
4156 for (i = 0; i < assocRespLen; i++) {
4157 if (!(i % 0x10)) {
4158 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4159 }
4160 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4161 }
4162 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4163 /*
4164 * If the event is due to disconnect cmd from the host, only they the target
4165 * would stop trying to connect. Under any other condition, target would
4166 * keep trying to connect.
4167 *
4168 */
4169 if( reason == DISCONNECT_CMD)
4170 {
4171 ar->arConnectPending = FALSE;
4172 if (!ar->arUserBssFilter) {
4173 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4174 }
4175 } else {
4176 ar->arConnectPending = TRUE;
4177 if (((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x11)) ||
4178 ((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x0) && (recon nect_flag == 1))) {
4179 ar->arConnected = TRUE;
4180 return;
4181 }
4182 }
4183
4184 if (reason == NO_NETWORK_AVAIL)
4185 {
4186 bss_t *pWmiSsidnode = NULL;
4187
4188 /* remove the current associated bssid node */
4189 wmi_free_node (ar->arWmi, bssid);
4190
4191 /*
4192 * In case any other same SSID nodes are present
4193 * remove it, since those nodes also not available now
4194 */
4195 do
4196 {
4197 /*
4198 * Find the nodes based on SSID and remove it
4199 * NOTE :: This case will not work out for Hidden-SSID
4200 */
4201 pWmiSsidnode = wmi_find_Ssidnode (ar->arWmi, ar->arSsid, ar->arSsidL en, FALSE, TRUE);
4202
4203 if (pWmiSsidnode)
4204 {
4205 wmi_free_node (ar->arWmi, pWmiSsidnode->ni_macaddr);
4206 }
4207
4208 }while (pWmiSsidnode);
4209
4210 #if 0
4211 /*
4212 * Issuing a disconnect cmd prevent the firmware from
4213 * continuing the scan and connect to the AP, if the AP
4214 * cannot be found in 10 seconds. The user has to issue
4215 * the iwconfig command again to connect to the AP.
4216 * This change came in CL#575412 (EV# 59469) has to
4217 * be fixed in a different way
4218 */
4219 ar6000_init_profile_info(ar);
4220 wmi_disconnect_cmd(ar->arWmi);
4221 #endif
4222 }
4223
4224 /* Update connect & link status atomically */
4225 spin_lock_irqsave(&ar->arLock, flags);
4226 ar->arConnected = FALSE;
4227 netif_carrier_off(ar->arNetDev);
4228 spin_unlock_irqrestore(&ar->arLock, flags);
4229
4230 if( (reason != CSERV_DISCONNECT) || (reconnect_flag != 1) ) {
4231 reconnect_flag = 0;
4232 }
4233
4234 #ifdef USER_KEYS
4235 if (reason != CSERV_DISCONNECT)
4236 {
4237 ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
4238 ar->user_key_ctrl = 0;
4239 }
4240 #endif /* USER_KEYS */
4241
4242 netif_stop_queue(ar->arNetDev);
4243 A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
4244 ar->arBssChannel = 0;
4245 ar->arBeaconInterval = 0;
4246
4247 ar6000_TxDataCleanup(ar);
4248 }
4249
4250 void
4251 ar6000_regDomain_event(AR_SOFTC_T *ar, A_UINT32 regCode)
4252 {
4253 A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode);
4254 ar->arRegCode = regCode;
4255 }
4256
4257 #ifdef ATH_AR6K_11N_SUPPORT
4258 void
4259 ar6000_aggr_rcv_addba_req_evt(AR_SOFTC_T *ar, WMI_ADDBA_REQ_EVENT *evt)
4260 {
4261 if(evt->status == 0) {
4262 aggr_recv_addba_req_evt(ar->aggr_cntxt, evt->tid, evt->st_seq_no, evt->w in_sz);
4263 }
4264 }
4265
4266 void
4267 ar6000_aggr_rcv_addba_resp_evt(AR_SOFTC_T *ar, WMI_ADDBA_RESP_EVENT *evt)
4268 {
4269 A_PRINTF("ADDBA RESP. tid %d status %d, sz %d\n", evt->tid, evt->status, evt ->amsdu_sz);
4270 if(evt->status == 0) {
4271 }
4272 }
4273
4274 void
4275 ar6000_aggr_rcv_delba_req_evt(AR_SOFTC_T *ar, WMI_DELBA_EVENT *evt)
4276 {
4277 aggr_recv_delba_req_evt(ar->aggr_cntxt, evt->tid);
4278 }
4279 #endif
4280
4281 void
4282 ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd)
4283 {
4284 void *osbuf = NULL;
4285 A_INT8 i;
4286 A_UINT8 size, *buf;
4287 A_STATUS ret = A_OK;
4288
4289 size = cmd->evt_buf_sz + 4;
4290 osbuf = A_NETBUF_ALLOC(size);
4291 if (osbuf == NULL) {
4292 ret = A_NO_MEMORY;
4293 A_PRINTF("Error in allocating netbuf \n");
4294 return;
4295 }
4296
4297 A_NETBUF_PUT(osbuf, size);
4298 buf = (A_UINT8 *)A_NETBUF_DATA(osbuf);
4299 /* First 2-bytes carry HCI event/ACL data type
4300 * the next 2 are free
4301 */
4302 *((short *)buf) = WMI_HCI_EVENT_EVENTID;
4303 buf += sizeof(int);
4304 A_MEMCPY(buf, cmd->buf, cmd->evt_buf_sz);
4305
4306 ar6000_deliver_frames_to_nw_stack(ar->arNetDev, osbuf);
4307 if(loghci) {
4308 A_PRINTF_LOG("HCI Event From PAL <-- \n");
4309 for(i = 0; i < cmd->evt_buf_sz; i++) {
4310 A_PRINTF_LOG("0x%02x ", cmd->buf[i]);
4311 if((i % 10) == 0) {
4312 A_PRINTF_LOG("\n");
4313 }
4314 }
4315 A_PRINTF_LOG("\n");
4316 A_PRINTF_LOG("==================================\n");
4317 }
4318 }
4319
4320 void
4321 ar6000_neighborReport_event(AR_SOFTC_T *ar, int numAps, WMI_NEIGHBOR_INFO *info)
4322 {
4323 #if WIRELESS_EXT >= 18
4324 struct iw_pmkid_cand *pmkcand;
4325 #else /* WIRELESS_EXT >= 18 */
4326 static const char *tag = "PRE-AUTH";
4327 char buf[128];
4328 #endif /* WIRELESS_EXT >= 18 */
4329
4330 union iwreq_data wrqu;
4331 int i;
4332
4333 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("AR6000 Neighbor Report Event\n"));
4334 for (i=0; i < numAps; info++, i++) {
4335 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2 x:%2.2x ",
4336 info->bssid[0], info->bssid[1], info->bssid[2],
4337 info->bssid[3], info->bssid[4], info->bssid[5]));
4338 if (info->bssFlags & WMI_PREAUTH_CAPABLE_BSS) {
4339 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("preauth-cap"));
4340 }
4341 if (info->bssFlags & WMI_PMKID_VALID_BSS) {
4342 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,(" pmkid-valid\n"));
4343 continue; /* we skip bss if the pmkid is already valid */
4344 }
4345 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("\n"));
4346 A_MEMZERO(&wrqu, sizeof(wrqu));
4347 #if WIRELESS_EXT >= 18
4348 pmkcand = A_MALLOC_NOWAIT(sizeof(struct iw_pmkid_cand));
4349 A_MEMZERO(pmkcand, sizeof(struct iw_pmkid_cand));
4350 pmkcand->index = i;
4351 pmkcand->flags = info->bssFlags;
4352 A_MEMCPY(pmkcand->bssid.sa_data, info->bssid, ATH_MAC_LEN);
4353 wrqu.data.length = sizeof(struct iw_pmkid_cand);
4354 wireless_send_event(ar->arNetDev, IWEVPMKIDCAND, &wrqu, (char *)pmkcand) ;
4355 A_FREE(pmkcand);
4356 #else /* WIRELESS_EXT >= 18 */
4357 snprintf(buf, sizeof(buf), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
4358 tag,
4359 info->bssid[0], info->bssid[1], info->bssid[2],
4360 info->bssid[3], info->bssid[4], info->bssid[5],
4361 i, info->bssFlags);
4362 wrqu.data.length = strlen(buf);
4363 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4364 #endif /* WIRELESS_EXT >= 18 */
4365 }
4366 }
4367
4368 void
4369 ar6000_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast)
4370 {
4371 static const char *tag = "MLME-MICHAELMICFAILURE.indication";
4372 char buf[128];
4373 union iwreq_data wrqu;
4374
4375 /*
4376 * For AP case, keyid will have aid of STA which sent pkt with
4377 * MIC error. Use this aid to get MAC & send it to hostapd.
4378 */
4379 if (ar->arNetworkType == AP_NETWORK) {
4380 sta_t *s = ieee80211_find_conn_for_aid(ar, keyid);
4381 if(!s){
4382 /* ?? Don't know why it happens - need to debug this scenario in FW */
4383 A_PRINTF("AP TKIP MIC error received from Invalid aid / STA not foun d =%d\n", keyid);
4384 return;
4385 }
4386 A_PRINTF("AP TKIP MIC error received from aid=%d\n", keyid);
4387 snprintf(buf,sizeof(buf), "%s addr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
4388 tag, s->mac[0],s->mac[1],s->mac[2],s->mac[3],s->mac[4],s->mac[5]);
4389 } else {
4390
4391 #ifdef CONFIG_CFG80211
4392 ar6k_cfg80211_tkip_micerr_event(ar, keyid, ismcast);
4393 #endif /* CONFIG_CFG80211 */
4394
4395 A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n",
4396 keyid, ismcast ? "multi": "uni");
4397 snprintf(buf, sizeof(buf), "%s(keyid=%d %sicast)", tag, keyid,
4398 ismcast ? "mult" : "un");
4399 }
4400
4401 memset(&wrqu, 0, sizeof(wrqu));
4402 wrqu.data.length = strlen(buf);
4403 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4404 }
4405
4406 void
4407 ar6000_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status)
4408 {
4409
4410 #ifdef CONFIG_CFG80211
4411 ar6k_cfg80211_scanComplete_event(ar, status);
4412 #endif /* CONFIG_CFG80211 */
4413
4414 if (!ar->arUserBssFilter) {
4415 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4416 }
4417 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,( "AR6000 scan complete: %d\n", status)) ;
4418 }
4419
4420 void
4421 ar6000_targetStats_event(AR_SOFTC_T *ar, A_UINT8 *ptr, A_UINT32 len)
4422 {
4423 A_UINT8 ac;
4424
4425 if(ar->arNetworkType == AP_NETWORK) {
4426 WMI_AP_MODE_STAT *p = (WMI_AP_MODE_STAT *)ptr;
4427 WMI_AP_MODE_STAT *ap = &ar->arAPStats;
4428
4429 if (len < sizeof(*p)) {
4430 return;
4431 }
4432
4433 for(ac=0;ac<AP_MAX_NUM_STA;ac++) {
4434 ap->sta[ac].tx_bytes += p->sta[ac].tx_bytes;
4435 ap->sta[ac].tx_pkts += p->sta[ac].tx_pkts;
4436 ap->sta[ac].tx_error += p->sta[ac].tx_error;
4437 ap->sta[ac].tx_discard += p->sta[ac].tx_discard;
4438 ap->sta[ac].rx_bytes += p->sta[ac].rx_bytes;
4439 ap->sta[ac].rx_pkts += p->sta[ac].rx_pkts;
4440 ap->sta[ac].rx_error += p->sta[ac].rx_error;
4441 ap->sta[ac].rx_discard += p->sta[ac].rx_discard;
4442 }
4443
4444 } else {
4445 WMI_TARGET_STATS *pTarget = (WMI_TARGET_STATS *)ptr;
4446 TARGET_STATS *pStats = &ar->arTargetStats;
4447
4448 if (len < sizeof(*pTarget)) {
4449 return;
4450 }
4451
4452 // Update the RSSI of the connected bss.
4453 if (ar->arConnected) {
4454 bss_t *pConnBss = NULL;
4455
4456 pConnBss = wmi_find_node(ar->arWmi,ar->arBssid);
4457 if (pConnBss)
4458 {
4459 pConnBss->ni_rssi = pTarget->cservStats.cs_aveBeacon_rssi;
4460 pConnBss->ni_snr = pTarget->cservStats.cs_aveBeacon_snr;
4461 wmi_node_return(ar->arWmi, pConnBss);
4462 }
4463 }
4464
4465 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 updating target stats\n"));
4466 pStats->tx_packets += pTarget->txrxStats.tx_stats.tx_packets;
4467 pStats->tx_bytes += pTarget->txrxStats.tx_stats.tx_bytes;
4468 pStats->tx_unicast_pkts += pTarget->txrxStats.tx_stats.tx_unicast_pk ts;
4469 pStats->tx_unicast_bytes += pTarget->txrxStats.tx_stats.tx_unicast_by tes;
4470 pStats->tx_multicast_pkts += pTarget->txrxStats.tx_stats.tx_multicast_ pkts;
4471 pStats->tx_multicast_bytes += pTarget->txrxStats.tx_stats.tx_multicast_ bytes;
4472 pStats->tx_broadcast_pkts += pTarget->txrxStats.tx_stats.tx_broadcast_ pkts;
4473 pStats->tx_broadcast_bytes += pTarget->txrxStats.tx_stats.tx_broadcast_ bytes;
4474 pStats->tx_rts_success_cnt += pTarget->txrxStats.tx_stats.tx_rts_succes s_cnt;
4475 for(ac = 0; ac < WMM_NUM_AC; ac++)
4476 pStats->tx_packet_per_ac[ac] += pTarget->txrxStats.tx_stats.tx_packe t_per_ac[ac];
4477 pStats->tx_errors += pTarget->txrxStats.tx_stats.tx_errors;
4478 pStats->tx_failed_cnt += pTarget->txrxStats.tx_stats.tx_failed_cnt ;
4479 pStats->tx_retry_cnt += pTarget->txrxStats.tx_stats.tx_retry_cnt;
4480 pStats->tx_mult_retry_cnt += pTarget->txrxStats.tx_stats.tx_mult_retry _cnt;
4481 pStats->tx_rts_fail_cnt += pTarget->txrxStats.tx_stats.tx_rts_fail_c nt;
4482 pStats->tx_unicast_rate = wmi_get_rate(pTarget->txrxStats.tx_stats. tx_unicast_rate);
4483
4484 pStats->rx_packets += pTarget->txrxStats.rx_stats.rx_packets;
4485 pStats->rx_bytes += pTarget->txrxStats.rx_stats.rx_bytes;
4486 pStats->rx_unicast_pkts += pTarget->txrxStats.rx_stats.rx_unicast_pk ts;
4487 pStats->rx_unicast_bytes += pTarget->txrxStats.rx_stats.rx_unicast_by tes;
4488 pStats->rx_multicast_pkts += pTarget->txrxStats.rx_stats.rx_multicast_ pkts;
4489 pStats->rx_multicast_bytes += pTarget->txrxStats.rx_stats.rx_multicast_ bytes;
4490 pStats->rx_broadcast_pkts += pTarget->txrxStats.rx_stats.rx_broadcast_ pkts;
4491 pStats->rx_broadcast_bytes += pTarget->txrxStats.rx_stats.rx_broadcast_ bytes;
4492 pStats->rx_fragment_pkt += pTarget->txrxStats.rx_stats.rx_fragment_p kt;
4493 pStats->rx_errors += pTarget->txrxStats.rx_stats.rx_errors;
4494 pStats->rx_crcerr += pTarget->txrxStats.rx_stats.rx_crcerr;
4495 pStats->rx_key_cache_miss += pTarget->txrxStats.rx_stats.rx_key_cache_ miss;
4496 pStats->rx_decrypt_err += pTarget->txrxStats.rx_stats.rx_decrypt_er r;
4497 pStats->rx_duplicate_frames += pTarget->txrxStats.rx_stats.rx_duplicate_ frames;
4498 pStats->rx_unicast_rate = wmi_get_rate(pTarget->txrxStats.rx_stats. rx_unicast_rate);
4499
4500
4501 pStats->tkip_local_mic_failure
4502 += pTarget->txrxStats.tkipCcmpStats.tkip_local_m ic_failure;
4503 pStats->tkip_counter_measures_invoked
4504 += pTarget->txrxStats.tkipCcmpStats.tkip_counter _measures_invoked;
4505 pStats->tkip_replays += pTarget->txrxStats.tkipCcmpStats.tkip_rep lays;
4506 pStats->tkip_format_errors += pTarget->txrxStats.tkipCcmpStats.tkip_for mat_errors;
4507 pStats->ccmp_format_errors += pTarget->txrxStats.tkipCcmpStats.ccmp_for mat_errors;
4508 pStats->ccmp_replays += pTarget->txrxStats.tkipCcmpStats.ccmp_rep lays;
4509
4510 pStats->power_save_failure_cnt += pTarget->pmStats.power_save_failure_cn t;
4511 pStats->noise_floor_calibation = pTarget->noise_floor_calibation;
4512
4513 pStats->cs_bmiss_cnt += pTarget->cservStats.cs_bmiss_cnt;
4514 pStats->cs_lowRssi_cnt += pTarget->cservStats.cs_lowRssi_cnt;
4515 pStats->cs_connect_cnt += pTarget->cservStats.cs_connect_cnt;
4516 pStats->cs_disconnect_cnt += pTarget->cservStats.cs_disconnect_cnt;
4517 pStats->cs_aveBeacon_snr = pTarget->cservStats.cs_aveBeacon_snr;
4518 pStats->cs_aveBeacon_rssi = pTarget->cservStats.cs_aveBeacon_rssi;
4519
4520 if (enablerssicompensation) {
4521 pStats->cs_aveBeacon_rssi =
4522 rssi_compensation_calc(ar, pStats->cs_aveBeacon_rssi);
4523 }
4524 pStats->cs_lastRoam_msec = pTarget->cservStats.cs_lastRoam_msec;
4525 pStats->cs_snr = pTarget->cservStats.cs_snr;
4526 pStats->cs_rssi = pTarget->cservStats.cs_rssi;
4527
4528 pStats->lq_val = pTarget->lqVal;
4529
4530 pStats->wow_num_pkts_dropped += pTarget->wowStats.wow_num_pkts_dropped;
4531 pStats->wow_num_host_pkt_wakeups += pTarget->wowStats.wow_num_host_pkt_w akeups;
4532 pStats->wow_num_host_event_wakeups += pTarget->wowStats.wow_num_host_eve nt_wakeups;
4533 pStats->wow_num_events_discarded += pTarget->wowStats.wow_num_events_dis carded;
4534 pStats->arp_received += pTarget->arpStats.arp_received;
4535 pStats->arp_matched += pTarget->arpStats.arp_matched;
4536 pStats->arp_replied += pTarget->arpStats.arp_replied;
4537
4538 if (ar->statsUpdatePending) {
4539 ar->statsUpdatePending = FALSE;
4540 wake_up(&arEvent);
4541 }
4542 }
4543 }
4544
4545 void
4546 ar6000_rssiThreshold_event(AR_SOFTC_T *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, A_INT16 rssi)
4547 {
4548 USER_RSSI_THOLD userRssiThold;
4549
4550 rssi = rssi + SIGNAL_QUALITY_NOISE_FLOOR;
4551
4552 if (enablerssicompensation) {
4553 rssi = rssi_compensation_calc(ar, rssi);
4554 }
4555
4556 /* Send an event to the app */
4557 userRssiThold.tag = ar->rssi_map[newThreshold].tag;
4558 userRssiThold.rssi = rssi;
4559 A_PRINTF("rssi Threshold range = %d tag = %d rssi = %d\n", newThreshold,
4560 userRssiThold.tag, userRssiThold.rssi);
4561
4562 ar6000_send_event_to_app(ar, WMI_RSSI_THRESHOLD_EVENTID,(A_UINT8 *)&userRssi Thold, sizeof(USER_RSSI_THOLD));
4563 }
4564
4565
4566 void
4567 ar6000_hbChallengeResp_event(AR_SOFTC_T *ar, A_UINT32 cookie, A_UINT32 source)
4568 {
4569 if (source == APP_HB_CHALLENGE) {
4570 /* Report it to the app in case it wants a positive acknowledgement */
4571 ar6000_send_event_to_app(ar, WMIX_HB_CHALLENGE_RESP_EVENTID,
4572 (A_UINT8 *)&cookie, sizeof(cookie));
4573 } else {
4574 /* This would ignore the replys that come in after their due time */
4575 if (cookie == ar->arHBChallengeResp.seqNum) {
4576 ar->arHBChallengeResp.outstanding = FALSE;
4577 }
4578 }
4579 }
4580
4581
4582 void
4583 ar6000_reportError_event(AR_SOFTC_T *ar, WMI_TARGET_ERROR_VAL errorVal)
4584 {
4585 char *errString[] = {
4586 [WMI_TARGET_PM_ERR_FAIL] "WMI_TARGET_PM_ERR_FAIL",
4587 [WMI_TARGET_KEY_NOT_FOUND] "WMI_TARGET_KEY_NOT_FOUND",
4588 [WMI_TARGET_DECRYPTION_ERR] "WMI_TARGET_DECRYPTION_ERR",
4589 [WMI_TARGET_BMISS] "WMI_TARGET_BMISS",
4590 [WMI_PSDISABLE_NODE_JOIN] "WMI_PSDISABLE_NODE_JOIN"
4591 };
4592
4593 A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal);
4594
4595 /* One error is reported at a time, and errorval is a bitmask */
4596 if(errorVal & (errorVal - 1))
4597 return;
4598
4599 A_PRINTF("AR6000 Error type = ");
4600 switch(errorVal)
4601 {
4602 case WMI_TARGET_PM_ERR_FAIL:
4603 case WMI_TARGET_KEY_NOT_FOUND:
4604 case WMI_TARGET_DECRYPTION_ERR:
4605 case WMI_TARGET_BMISS:
4606 case WMI_PSDISABLE_NODE_JOIN:
4607 A_PRINTF("%s\n", errString[errorVal]);
4608 break;
4609 default:
4610 A_PRINTF("INVALID\n");
4611 break;
4612 }
4613
4614 }
4615
4616
4617 void
4618 ar6000_cac_event(AR_SOFTC_T *ar, A_UINT8 ac, A_UINT8 cacIndication,
4619 A_UINT8 statusCode, A_UINT8 *tspecSuggestion)
4620 {
4621 WMM_TSPEC_IE *tspecIe;
4622
4623 /*
4624 * This is the TSPEC IE suggestion from AP.
4625 * Suggestion provided by AP under some error
4626 * cases, could be helpful for the host app.
4627 * Check documentation.
4628 */
4629 tspecIe = (WMM_TSPEC_IE *)tspecSuggestion;
4630
4631 /*
4632 * What do we do, if we get TSPEC rejection? One thought
4633 * that comes to mind is implictly delete the pstream...
4634 */
4635 A_PRINTF("AR6000 CAC notification. "
4636 "AC = %d, cacIndication = 0x%x, statusCode = 0x%x\n",
4637 ac, cacIndication, statusCode);
4638 }
4639
4640 void
4641 ar6000_channel_change_event(AR_SOFTC_T *ar, A_UINT16 oldChannel,
4642 A_UINT16 newChannel)
4643 {
4644 A_PRINTF("Channel Change notification\nOld Channel: %d, New Channel: %d\n",
4645 oldChannel, newChannel);
4646 }
4647
4648 #define AR6000_PRINT_BSSID(_pBss) do { \
4649 A_PRINTF("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",\
4650 (_pBss)[0],(_pBss)[1],(_pBss)[2],(_pBss)[3],\
4651 (_pBss)[4],(_pBss)[5]); \
4652 } while(0)
4653
4654 void
4655 ar6000_roam_tbl_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_TBL *pTbl)
4656 {
4657 A_UINT8 i;
4658
4659 A_PRINTF("ROAM TABLE NO OF ENTRIES is %d ROAM MODE is %d\n",
4660 pTbl->numEntries, pTbl->roamMode);
4661 for (i= 0; i < pTbl->numEntries; i++) {
4662 A_PRINTF("[%d]bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", i,
4663 pTbl->bssRoamInfo[i].bssid[0], pTbl->bssRoamInfo[i].bssid[1],
4664 pTbl->bssRoamInfo[i].bssid[2],
4665 pTbl->bssRoamInfo[i].bssid[3],
4666 pTbl->bssRoamInfo[i].bssid[4],
4667 pTbl->bssRoamInfo[i].bssid[5]);
4668 A_PRINTF("RSSI %d RSSIDT %d LAST RSSI %d UTIL %d ROAM_UTIL %d"
4669 " BIAS %d\n",
4670 pTbl->bssRoamInfo[i].rssi,
4671 pTbl->bssRoamInfo[i].rssidt,
4672 pTbl->bssRoamInfo[i].last_rssi,
4673 pTbl->bssRoamInfo[i].util,
4674 pTbl->bssRoamInfo[i].roam_util,
4675 pTbl->bssRoamInfo[i].bias);
4676 }
4677 }
4678
4679 void
4680 ar6000_wow_list_event(struct ar6_softc *ar, A_UINT8 num_filters, WMI_GET_WOW_LIS T_REPLY *wow_reply)
4681 {
4682 A_UINT8 i,j;
4683
4684 /*Each event now contains exactly one filter, see bug 26613*/
4685 A_PRINTF("WOW pattern %d of %d patterns\n", wow_reply->this_filter_num, wow_reply->num_filters);
4686 A_PRINTF("wow mode = %s host mode = %s\n",
4687 (wow_reply->wow_mode == 0? "disabled":"enabled"),
4688 (wow_reply->host_mode == 1 ? "awake":"asleep"));
4689
4690
4691 /*If there are no patterns, the reply will only contain generic
4692 WoW information. Pattern information will exist only if there are
4693 patterns present. Bug 26716*/
4694
4695 /* If this event contains pattern information, display it*/
4696 if (wow_reply->this_filter_num) {
4697 i=0;
4698 A_PRINTF("id=%d size=%d offset=%d\n",
4699 wow_reply->wow_filters[i].wow_filter_id,
4700 wow_reply->wow_filters[i].wow_filter_size,
4701 wow_reply->wow_filters[i].wow_filter_offset);
4702 A_PRINTF("wow pattern = ");
4703 for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
4704 A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_pattern[j]);
4705 }
4706
4707 A_PRINTF("\nwow mask = ");
4708 for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
4709 A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_mask[j]);
4710 }
4711 A_PRINTF("\n");
4712 }
4713 }
4714
4715 /*
4716 * Report the Roaming related data collected on the target
4717 */
4718 void
4719 ar6000_display_roam_time(WMI_TARGET_ROAM_TIME *p)
4720 {
4721 A_PRINTF("Disconnect Data : BSSID: ");
4722 AR6000_PRINT_BSSID(p->disassoc_bssid);
4723 A_PRINTF(" RSSI %d DISASSOC Time %d NO_TXRX_TIME %d\n",
4724 p->disassoc_bss_rssi,p->disassoc_time,
4725 p->no_txrx_time);
4726 A_PRINTF("Connect Data: BSSID: ");
4727 AR6000_PRINT_BSSID(p->assoc_bssid);
4728 A_PRINTF(" RSSI %d ASSOC Time %d TXRX_TIME %d\n",
4729 p->assoc_bss_rssi,p->assoc_time,
4730 p->allow_txrx_time);
4731 }
4732
4733 void
4734 ar6000_roam_data_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_DATA *p)
4735 {
4736 switch (p->roamDataType) {
4737 case ROAM_DATA_TIME:
4738 ar6000_display_roam_time(&p->u.roamTime);
4739 break;
4740 default:
4741 break;
4742 }
4743 }
4744
4745 void
4746 ar6000_bssInfo_event_rx(AR_SOFTC_T *ar, A_UINT8 *datap, int len)
4747 {
4748 struct sk_buff *skb;
4749 WMI_BSS_INFO_HDR *bih = (WMI_BSS_INFO_HDR *)datap;
4750
4751
4752 if (!ar->arMgmtFilter) {
4753 return;
4754 }
4755 if (((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_BEACON) &&
4756 (bih->frameType != BEACON_FTYPE)) ||
4757 ((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_PROBE_RESP) &&
4758 (bih->frameType != PROBERESP_FTYPE)))
4759 {
4760 return;
4761 }
4762
4763 if ((skb = A_NETBUF_ALLOC_RAW(len)) != NULL) {
4764
4765 A_NETBUF_PUT(skb, len);
4766 A_MEMCPY(A_NETBUF_DATA(skb), datap, len);
4767 skb->dev = ar->arNetDev;
4768 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
4769 A_MEMCPY(skb_mac_header(skb), A_NETBUF_DATA(skb), 6);
4770 #else
4771 skb->mac.raw = A_NETBUF_DATA(skb);
4772 #endif
4773 skb->ip_summed = CHECKSUM_NONE;
4774 skb->pkt_type = PACKET_OTHERHOST;
4775 skb->protocol = __constant_htons(0x0019);
4776 netif_rx(skb);
4777 }
4778 }
4779
4780 A_UINT32 wmiSendCmdNum;
4781
4782 A_STATUS
4783 ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid)
4784 {
4785 AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
4786 A_STATUS status = A_OK;
4787 struct ar_cookie *cookie = NULL;
4788 int i;
4789
4790 /* take lock to protect ar6000_alloc_cookie() */
4791 AR6000_SPIN_LOCK(&ar->arLock, 0);
4792
4793 do {
4794
4795 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar_contrstatus = ol_tx: skb=0x%x, le n=0x%x eid =%d\n",
4796 (A_UINT32)osbuf, A_NETBUF_LEN(osbuf), eid));
4797
4798 if (ar->arWMIControlEpFull && (eid == ar->arControlEp)) {
4799 /* control endpoint is full, don't allocate resources, we
4800 * are just going to drop this packet */
4801 cookie = NULL;
4802 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" WMI Control EP full, dropping packe t : 0x%X, len:%d \n",
4803 (A_UINT32)osbuf, A_NETBUF_LEN(osbuf)));
4804 } else {
4805 cookie = ar6000_alloc_cookie(ar);
4806 }
4807
4808 if (cookie == NULL) {
4809 status = A_NO_MEMORY;
4810 break;
4811 }
4812
4813 if(logWmiRawMsgs) {
4814 A_PRINTF("WMI cmd send, msgNo %d :", wmiSendCmdNum);
4815 for(i = 0; i < a_netbuf_to_len(osbuf); i++)
4816 A_PRINTF("%x ", ((A_UINT8 *)a_netbuf_to_data(osbuf))[i]);
4817 A_PRINTF("\n");
4818 }
4819
4820 wmiSendCmdNum++;
4821
4822 } while (FALSE);
4823
4824 if (cookie != NULL) {
4825 /* got a structure to send it out on */
4826 ar->arTxPending[eid]++;
4827
4828 if (eid != ar->arControlEp) {
4829 ar->arTotalTxDataPending++;
4830 }
4831 }
4832
4833 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
4834
4835 if (cookie != NULL) {
4836 cookie->arc_bp[0] = (A_UINT32)osbuf;
4837 cookie->arc_bp[1] = 0;
4838 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
4839 cookie,
4840 A_NETBUF_DATA(osbuf),
4841 A_NETBUF_LEN(osbuf),
4842 eid,
4843 AR6K_CONTROL_PKT_TAG);
4844 /* this interface is asynchronous, if there is an error, cleanup wil l happen in the
4845 * TX completion callback */
4846 HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
4847 status = A_OK;
4848 }
4849
4850 return status;
4851 }
4852
4853 /* indicate tx activity or inactivity on a WMI stream */
4854 void ar6000_indicate_tx_activity(void *devt, A_UINT8 TrafficClass, A_BOOL Active )
4855 {
4856 AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
4857 HTC_ENDPOINT_ID eid ;
4858 int i;
4859
4860 if (ar->arWmiEnabled) {
4861 eid = arAc2EndpointID(ar, TrafficClass);
4862
4863 AR6000_SPIN_LOCK(&ar->arLock, 0);
4864
4865 ar->arAcStreamActive[TrafficClass] = Active;
4866
4867 if (Active) {
4868 /* when a stream goes active, keep track of the active stream with t he highest priority */
4869
4870 if (ar->arAcStreamPriMap[TrafficClass] > ar->arHiAcStreamActivePri) {
4871 /* set the new highest active priority */
4872 ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[TrafficClass];
4873 }
4874
4875 } else {
4876 /* when a stream goes inactive, we may have to search for the next a ctive stream
4877 * that is the highest priority */
4878
4879 if (ar->arHiAcStreamActivePri == ar->arAcStreamPriMap[TrafficClass]) {
4880
4881 /* the highest priority stream just went inactive */
4882
4883 /* reset and search for the "next" highest "active" priority stream */
4884 ar->arHiAcStreamActivePri = 0;
4885 for (i = 0; i < WMM_NUM_AC; i++) {
4886 if (ar->arAcStreamActive[i]) {
4887 if (ar->arAcStreamPriMap[i] > ar->arHiAcStreamActivePri) {
4888 /* set the new highest active priority */
4889 ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[i];
4890 }
4891 }
4892 }
4893 }
4894 }
4895
4896 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
4897
4898 } else {
4899 /* for mbox ping testing, the traffic class is mapped directly as a stream ID,
4900 * see handling of AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE in ioctl.c */
4901 eid = (HTC_ENDPOINT_ID)TrafficClass;
4902 }
4903
4904 /* notify HTC, this may cause credit distribution changes */
4905
4906 HTCIndicateActivityChange(ar->arHtcTarget,
4907 eid,
4908 Active);
4909
4910 }
4911
4912 void
4913 ar6000_btcoex_config_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len)
4914 {
4915
4916 WMI_BTCOEX_CONFIG_EVENT *pBtcoexConfig = (WMI_BTCOEX_CONFIG_EVENT *)ptr;
4917 WMI_BTCOEX_CONFIG_EVENT *pArbtcoexConfig =&ar->arBtcoexConfig;
4918
4919 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n"));
4920
4921 A_PRINTF("received config event\n");
4922 pArbtcoexConfig->btProfileType = pBtcoexConfig->btProfileType;
4923 pArbtcoexConfig->linkId = pBtcoexConfig->linkId;
4924
4925 switch (pBtcoexConfig->btProfileType) {
4926 case WMI_BTCOEX_BT_PROFILE_SCO:
4927 A_MEMCPY(&pArbtcoexConfig->info.scoConfigCmd, &pBtcoexCo nfig->info.scoConfigCmd,
4928 sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
4929 break;
4930 case WMI_BTCOEX_BT_PROFILE_A2DP:
4931 A_MEMCPY(&pArbtcoexConfig->info.a2dpConfigCmd, &pBtcoexC onfig->info.a2dpConfigCmd,
4932 sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
4933 break;
4934 case WMI_BTCOEX_BT_PROFILE_ACLCOEX:
4935 A_MEMCPY(&pArbtcoexConfig->info.aclcoexConfig, &pBtcoexConfi g->info.aclcoexConfig,
4936 sizeof(W MI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
4937 break;
4938 case WMI_BTCOEX_BT_PROFILE_INQUIRY_PAGE:
4939 A_MEMCPY(&pArbtcoexConfig->info.btinquiryPageConfigCmd, &pBtc oexConfig->info.btinquiryPageConfigCmd,
4940 sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
4941 break;
4942 }
4943 if (ar->statsUpdatePending) {
4944 ar->statsUpdatePending = FALSE;
4945 wake_up(&arEvent);
4946 }
4947 }
4948
4949 void
4950 ar6000_btcoex_stats_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len)
4951 {
4952 WMI_BTCOEX_STATS_EVENT *pBtcoexStats = (WMI_BTCOEX_STATS_EVENT *)ptr;
4953
4954 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n"));
4955
4956 A_MEMCPY(&ar->arBtcoexStats, pBtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT ));
4957
4958 if (ar->statsUpdatePending) {
4959 ar->statsUpdatePending = FALSE;
4960 wake_up(&arEvent);
4961 }
4962
4963 }
4964 module_init(ar6000_init_module);
4965 module_exit(ar6000_cleanup_module);
4966
4967 /* Init cookie queue */
4968 static void
4969 ar6000_cookie_init(AR_SOFTC_T *ar)
4970 {
4971 A_UINT32 i;
4972
4973 ar->arCookieList = NULL;
4974 ar->arCookieCount = 0;
4975
4976 A_MEMZERO(s_ar_cookie_mem, sizeof(s_ar_cookie_mem));
4977
4978 for (i = 0; i < MAX_COOKIE_NUM; i++) {
4979 ar6000_free_cookie(ar, &s_ar_cookie_mem[i]);
4980 }
4981 }
4982
4983 /* cleanup cookie queue */
4984 static void
4985 ar6000_cookie_cleanup(AR_SOFTC_T *ar)
4986 {
4987 /* It is gone .... */
4988 ar->arCookieList = NULL;
4989 ar->arCookieCount = 0;
4990 }
4991
4992 /* Init cookie queue */
4993 static void
4994 ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie)
4995 {
4996 /* Insert first */
4997 A_ASSERT(ar != NULL);
4998 A_ASSERT(cookie != NULL);
4999
5000 cookie->arc_list_next = ar->arCookieList;
5001 ar->arCookieList = cookie;
5002 ar->arCookieCount++;
5003 }
5004
5005 /* cleanup cookie queue */
5006 static struct ar_cookie *
5007 ar6000_alloc_cookie(AR_SOFTC_T *ar)
5008 {
5009 struct ar_cookie *cookie;
5010
5011 cookie = ar->arCookieList;
5012 if(cookie != NULL)
5013 {
5014 ar->arCookieList = cookie->arc_list_next;
5015 ar->arCookieCount--;
5016 }
5017
5018 return cookie;
5019 }
5020
5021 #ifdef SEND_EVENT_TO_APP
5022 /*
5023 * This function is used to send event which come from taget to
5024 * the application. The buf which send to application is include
5025 * the event ID and event content.
5026 */
5027 #define EVENT_ID_LEN 2
5028 void ar6000_send_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId,
5029 A_UINT8 *datap, int len)
5030 {
5031
5032 #if (WIRELESS_EXT >= 15)
5033
5034 /* note: IWEVCUSTOM only exists in wireless extensions after version 15 */
5035
5036 char *buf;
5037 A_UINT16 size;
5038 union iwreq_data wrqu;
5039
5040 size = len + EVENT_ID_LEN;
5041
5042 if (size > IW_CUSTOM_MAX) {
5043 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI event ID : 0x%4.4X, len = %d too big for IWEVCUSTOM (max=%d) \n",
5044 eventId, size, IW_CUSTOM_MAX));
5045 return;
5046 }
5047
5048 buf = A_MALLOC_NOWAIT(size);
5049 if (NULL == buf){
5050 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: failed to allocate %d bytes\n", __fu nc__, size));
5051 return;
5052 }
5053
5054 A_MEMZERO(buf, size);
5055 A_MEMCPY(buf, &eventId, EVENT_ID_LEN);
5056 A_MEMCPY(buf+EVENT_ID_LEN, datap, len);
5057
5058 //AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("event ID = %d,len = %d\n",*(A_UINT16*)buf , size));
5059 A_MEMZERO(&wrqu, sizeof(wrqu));
5060 wrqu.data.length = size;
5061 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
5062
5063 A_FREE(buf);
5064 #endif
5065
5066
5067 }
5068
5069 /*
5070 * This function is used to send events larger than 256 bytes
5071 * to the application. The buf which is sent to application
5072 * includes the event ID and event content.
5073 */
5074 void ar6000_send_generic_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId,
5075 A_UINT8 *datap, int len)
5076 {
5077
5078 #if (WIRELESS_EXT >= 18)
5079
5080 /* IWEVGENIE exists in wireless extensions version 18 onwards */
5081
5082 char *buf;
5083 A_UINT16 size;
5084 union iwreq_data wrqu;
5085
5086 size = len + EVENT_ID_LEN;
5087
5088 if (size > IW_GENERIC_IE_MAX) {
5089 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI event ID : 0x%4.4X, len = %d too big for IWEVGENIE (max=%d) \n",
5090 eventId, size, IW_GENERIC_IE_MAX));
5091 return;
5092 }
5093
5094 buf = A_MALLOC_NOWAIT(size);
5095 if (NULL == buf){
5096 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: failed to allocate %d bytes\n", __fu nc__, size));
5097 return;
5098 }
5099
5100 A_MEMZERO(buf, size);
5101 A_MEMCPY(buf, &eventId, EVENT_ID_LEN);
5102 A_MEMCPY(buf+EVENT_ID_LEN, datap, len);
5103
5104 A_MEMZERO(&wrqu, sizeof(wrqu));
5105 wrqu.data.length = size;
5106 wireless_send_event(ar->arNetDev, IWEVGENIE, &wrqu, buf);
5107
5108 A_FREE(buf);
5109
5110 #endif /* (WIRELESS_EXT >= 18) */
5111
5112 }
5113 #endif /* SEND_EVENT_TO_APP */
5114
5115
5116 void
5117 ar6000_tx_retry_err_event(void *devt)
5118 {
5119 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Tx retries reach maximum!\n"));
5120 }
5121
5122 void
5123 ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, A_UI NT8 snr)
5124 {
5125 WMI_SNR_THRESHOLD_EVENT event;
5126 AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
5127
5128 event.range = newThreshold;
5129 event.snr = snr;
5130
5131 ar6000_send_event_to_app(ar, WMI_SNR_THRESHOLD_EVENTID, (A_UINT8 *)&event,
5132 sizeof(WMI_SNR_THRESHOLD_EVENT));
5133 }
5134
5135 void
5136 ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL newThreshold, A_UINT 8 lq)
5137 {
5138 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("lq threshold range %d, lq %d\n", newThresho ld, lq));
5139 }
5140
5141
5142
5143 A_UINT32
5144 a_copy_to_user(void *to, const void *from, A_UINT32 n)
5145 {
5146 return(copy_to_user(to, from, n));
5147 }
5148
5149 A_UINT32
5150 a_copy_from_user(void *to, const void *from, A_UINT32 n)
5151 {
5152 return(copy_from_user(to, from, n));
5153 }
5154
5155
5156 A_STATUS
5157 ar6000_get_driver_cfg(struct net_device *dev,
5158 A_UINT16 cfgParam,
5159 void *result)
5160 {
5161
5162 A_STATUS ret = 0;
5163
5164 switch(cfgParam)
5165 {
5166 case AR6000_DRIVER_CFG_GET_WLANNODECACHING:
5167 *((A_UINT32 *)result) = wlanNodeCaching;
5168 break;
5169 case AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS:
5170 *((A_UINT32 *)result) = logWmiRawMsgs;
5171 break;
5172 default:
5173 ret = EINVAL;
5174 break;
5175 }
5176
5177 return ret;
5178 }
5179
5180 void
5181 ar6000_keepalive_rx(void *devt, A_UINT8 configured)
5182 {
5183 AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
5184
5185 ar->arKeepaliveConfigured = configured;
5186 wake_up(&arEvent);
5187 }
5188
5189 void
5190 ar6000_pmkid_list_event(void *devt, A_UINT8 numPMKID, WMI_PMKID *pmkidList,
5191 A_UINT8 *bssidList)
5192 {
5193 A_UINT8 i, j;
5194
5195 A_PRINTF("Number of Cached PMKIDs is %d\n", numPMKID);
5196
5197 for (i = 0; i < numPMKID; i++) {
5198 A_PRINTF("\nBSSID %d ", i);
5199 for (j = 0; j < ATH_MAC_LEN; j++) {
5200 A_PRINTF("%2.2x", bssidList[j]);
5201 }
5202 bssidList += (ATH_MAC_LEN + WMI_PMKID_LEN);
5203 A_PRINTF("\nPMKID %d ", i);
5204 for (j = 0; j < WMI_PMKID_LEN; j++) {
5205 A_PRINTF("%2.2x", pmkidList->pmkid[j]);
5206 }
5207 pmkidList = (WMI_PMKID *)((A_UINT8 *)pmkidList + ATH_MAC_LEN +
5208 WMI_PMKID_LEN);
5209 }
5210 }
5211
5212 void ar6000_pspoll_event(AR_SOFTC_T *ar,A_UINT8 aid)
5213 {
5214 sta_t *conn=NULL;
5215 A_BOOL isPsqEmpty = FALSE;
5216
5217 conn = ieee80211_find_conn_for_aid(ar, aid);
5218
5219 /* If the PS q for this STA is not empty, dequeue and send a pkt from
5220 * the head of the q. Also update the More data bit in the WMI_DATA_HDR
5221 * if there are more pkts for this STA in the PS q. If there are no more
5222 * pkts for this STA, update the PVB for this STA.
5223 */
5224 A_MUTEX_LOCK(&conn->psqLock);
5225 isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
5226 A_MUTEX_UNLOCK(&conn->psqLock);
5227
5228 if (isPsqEmpty) {
5229 /* TODO:No buffered pkts for this STA. Send out a NULL data frame */
5230 } else {
5231 struct sk_buff *skb = NULL;
5232
5233 A_MUTEX_LOCK(&conn->psqLock);
5234 skb = A_NETBUF_DEQUEUE(&conn->psq);
5235 A_MUTEX_UNLOCK(&conn->psqLock);
5236 /* Set the STA flag to PSPolled, so that the frame will go out */
5237 STA_SET_PS_POLLED(conn);
5238 ar6000_data_tx(skb, ar->arNetDev);
5239 STA_CLR_PS_POLLED(conn);
5240
5241 /* Clear the PVB for this STA if the queue has become empty */
5242 A_MUTEX_LOCK(&conn->psqLock);
5243 isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
5244 A_MUTEX_UNLOCK(&conn->psqLock);
5245
5246 if (isPsqEmpty) {
5247 wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
5248 }
5249 }
5250 }
5251
5252 void ar6000_dtimexpiry_event(AR_SOFTC_T *ar)
5253 {
5254 A_BOOL isMcastQueued = FALSE;
5255 struct sk_buff *skb = NULL;
5256
5257 /* If there are no associated STAs, ignore the DTIM expiry event.
5258 * There can be potential race conditions where the last associated
5259 * STA may disconnect & before the host could clear the 'Indicate DTIM'
5260 * request to the firmware, the firmware would have just indicated a DTIM
5261 * expiry event. The race is between 'clear DTIM expiry cmd' going
5262 * from the host to the firmware & the DTIM expiry event happening from
5263 * the firmware to the host.
5264 */
5265 if (ar->sta_list_index == 0) {
5266 return;
5267 }
5268
5269 A_MUTEX_LOCK(&ar->mcastpsqLock);
5270 isMcastQueued = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
5271 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5272
5273 A_ASSERT(isMcastQueued == FALSE);
5274
5275 /* Flush the mcast psq to the target */
5276 /* Set the STA flag to DTIMExpired, so that the frame will go out */
5277 ar->DTIMExpired = TRUE;
5278
5279 A_MUTEX_LOCK(&ar->mcastpsqLock);
5280 while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
5281 skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
5282 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5283
5284 ar6000_data_tx(skb, ar->arNetDev);
5285
5286 A_MUTEX_LOCK(&ar->mcastpsqLock);
5287 }
5288 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5289
5290 /* Reset the DTIMExpired flag back to 0 */
5291 ar->DTIMExpired = FALSE;
5292
5293 /* Clear the LSB of the BitMapCtl field of the TIM IE */
5294 wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
5295 }
5296
5297 void
5298 read_rssi_compensation_param(AR_SOFTC_T *ar)
5299 {
5300 HIF_DEVICE *device= ar->arHifDevice;
5301 A_UINT32 rssicomp;
5302 A_UINT32 param;
5303
5304 if (BMIReadMemory(device,
5305 HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data),
5306 (A_UCHAR *)&rssicomp,
5307 4)!= A_OK)
5308 {
5309 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadMemory for reading board data ad dress failed \n"));
5310 return;
5311 }
5312
5313 rssicomp += 0x40;
5314 if (BMIReadSOCRegister(device, rssicomp, &param)!= A_OK) {
5315 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
5316 return ;
5317 }
5318 rssi_compensation_param.a_enable = (A_INT16) (param & 0xffff);
5319 rssi_compensation_param.a_param_a = (A_INT16) (param >> 16);
5320
5321 rssicomp += 4;
5322 if (BMIReadSOCRegister(device, rssicomp, &param)!= A_OK) {
5323 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
5324 return ;
5325 }
5326 rssi_compensation_param.a_param_b = (A_INT16) (param & 0xffff);
5327 rssi_compensation_param.bg_enable = (A_INT16) (param >> 16);
5328
5329 rssicomp += 4;
5330 if (BMIReadSOCRegister(device, rssicomp, &param)!= A_OK) {
5331 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
5332 return ;
5333 }
5334 rssi_compensation_param.bg_param_a = (A_INT16) (param & 0xffff);
5335 rssi_compensation_param.bg_param_b = (A_INT16) (param >> 16);
5336
5337 if (rssi_compensation_param.bg_enable != 0x1)
5338 rssi_compensation_param.bg_enable = 0;
5339
5340 if (rssi_compensation_param.a_enable != 0x1)
5341 rssi_compensation_param.a_enable = 0;
5342
5343 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("compensation flag = %d a = %d b = %d\n",\
5344 rssi_compensation_param.bg_enable,
5345 rssi_compensation_param.bg_param_a,
5346 rssi_compensation_param.bg_param_b));
5347
5348 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("compensation flag = %d a = %d b = %d\n",\
5349 rssi_compensation_param.a_enable,
5350 rssi_compensation_param.a_param_a,
5351 rssi_compensation_param.a_param_b));
5352
5353 return ;
5354 }
5355
5356 A_INT32
5357 rssi_compensation_calc_tcmd(A_UINT32 freq, A_INT32 rssi, A_UINT32 totalPkt)
5358 {
5359
5360 if (freq > 5000)
5361 {
5362 if (rssi_compensation_param.a_enable)
5363 {
5364 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5365 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d, to talPkt = %d\n", rssi,totalPkt));
5366 rssi = rssi * rssi_compensation_param.a_param_a + totalPkt * rssi_co mpensation_param.a_param_b;
5367 rssi = (rssi-50) /100;
5368 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", r ssi));
5369 }
5370 }
5371 else
5372 {
5373 if (rssi_compensation_param.bg_enable)
5374 {
5375 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5376 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d, to talPkt = %d\n", rssi,totalPkt));
5377 rssi = rssi * rssi_compensation_param.bg_param_a + totalPkt * rssi_c ompensation_param.bg_param_b;
5378 rssi = (rssi-50) /100;
5379 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", r ssi));
5380 }
5381 }
5382
5383 return rssi;
5384 }
5385
5386 A_INT16
5387 rssi_compensation_calc(AR_SOFTC_T *ar, A_INT16 rssi)
5388 {
5389 if (ar->arBssChannel > 5000)
5390 {
5391 if (rssi_compensation_param.a_enable)
5392 {
5393 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5394 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d\n", rssi));
5395 rssi = rssi * rssi_compensation_param.a_param_a + rssi_compensation_ param.a_param_b;
5396 rssi = (rssi-50) /100;
5397 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", r ssi));
5398 }
5399 }
5400 else
5401 {
5402 if (rssi_compensation_param.bg_enable)
5403 {
5404 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5405 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d\n", rssi));
5406 rssi = rssi * rssi_compensation_param.bg_param_a + rssi_compensation _param.bg_param_b;
5407 rssi = (rssi-50) /100;
5408 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", r ssi));
5409 }
5410 }
5411
5412 return rssi;
5413 }
5414
5415 A_INT16
5416 rssi_compensation_reverse_calc(AR_SOFTC_T *ar, A_INT16 rssi, A_BOOL Above)
5417 {
5418 A_INT16 i;
5419
5420 if (ar->arBssChannel > 5000)
5421 {
5422 if (rssi_compensation_param.a_enable)
5423 {
5424 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5425 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation = %d \n", rssi));
5426 rssi = rssi * 100;
5427 rssi = (rssi - rssi_compensation_param.a_param_b) / rssi_compensatio n_param.a_param_a;
5428 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n ", rssi));
5429 }
5430 }
5431 else
5432 {
5433 if (rssi_compensation_param.bg_enable)
5434 {
5435 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5436 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation = %d \n", rssi));
5437
5438 if (Above) {
5439 for (i=95; i>=0; i--) {
5440 if (rssi <= rssi_compensation_table[i]) {
5441 rssi = 0 - i;
5442 break;
5443 }
5444 }
5445 } else {
5446 for (i=0; i<=95; i++) {
5447 if (rssi >= rssi_compensation_table[i]) {
5448 rssi = 0 - i;
5449 break;
5450 }
5451 }
5452 }
5453 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n ", rssi));
5454 }
5455 }
5456
5457 return rssi;
5458 }
5459
5460 #ifdef WAPI_ENABLE
5461 void ap_wapi_rekey_event(AR_SOFTC_T *ar, A_UINT8 type, A_UINT8 *mac)
5462 {
5463 union iwreq_data wrqu;
5464 A_UINT8 buf[20];
5465
5466 A_MEMZERO(buf, sizeof(buf));
5467
5468 strcpy(buf, "WAPI_REKEY");
5469 buf[10] = type;
5470 A_MEMCPY(&buf[11], mac, ATH_MAC_LEN);
5471
5472 A_MEMZERO(&wrqu, sizeof(wrqu));
5473 wrqu.data.length = 10+1+ATH_MAC_LEN;
5474 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
5475
5476 A_PRINTF("WAPI REKEY - %d - %02x:%02x\n", type, mac[4], mac[5]);
5477 }
5478 #endif
5479
5480 #ifdef USER_KEYS
5481 static A_STATUS
5482
5483 ar6000_reinstall_keys(AR_SOFTC_T *ar, A_UINT8 key_op_ctrl)
5484 {
5485 A_STATUS status = A_OK;
5486 struct ieee80211req_key *uik = &ar->user_saved_keys.ucast_ik;
5487 struct ieee80211req_key *bik = &ar->user_saved_keys.bcast_ik;
5488 CRYPTO_TYPE keyType = ar->user_saved_keys.keyType;
5489
5490 if (IEEE80211_CIPHER_CCKM_KRK != uik->ik_type) {
5491 if (NONE_CRYPT == keyType) {
5492 goto _reinstall_keys_out;
5493 }
5494
5495 if (uik->ik_keylen) {
5496 status = wmi_addKey_cmd(ar->arWmi, uik->ik_keyix,
5497 ar->user_saved_keys.keyType, PAIRWISE_USAGE,
5498 uik->ik_keylen, (A_UINT8 *)&uik->ik_keyrsc,
5499 uik->ik_keydata, key_op_ctrl, uik->ik_macaddr, SYNC_BEFORE_W MIFLAG);
5500 }
5501
5502 } else {
5503 status = wmi_add_krk_cmd(ar->arWmi, uik->ik_keydata);
5504 }
5505
5506 if (IEEE80211_CIPHER_CCKM_KRK != bik->ik_type) {
5507 if (NONE_CRYPT == keyType) {
5508 goto _reinstall_keys_out;
5509 }
5510
5511 if (bik->ik_keylen) {
5512 status = wmi_addKey_cmd(ar->arWmi, bik->ik_keyix,
5513 ar->user_saved_keys.keyType, GROUP_USAGE,
5514 bik->ik_keylen, (A_UINT8 *)&bik->ik_keyrsc,
5515 bik->ik_keydata, key_op_ctrl, bik->ik_macaddr, NO_SYNC_WMIFL AG);
5516 }
5517 } else {
5518 status = wmi_add_krk_cmd(ar->arWmi, bik->ik_keydata);
5519 }
5520
5521 _reinstall_keys_out:
5522 ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
5523 ar->user_key_ctrl = 0;
5524
5525 return status;
5526 }
5527 #endif /* USER_KEYS */
5528
5529
5530 void
5531 ar6000_dset_open_req(
5532 void *context,
5533 A_UINT32 id,
5534 A_UINT32 targHandle,
5535 A_UINT32 targReplyFn,
5536 A_UINT32 targReplyArg)
5537 {
5538 }
5539
5540 void
5541 ar6000_dset_close(
5542 void *context,
5543 A_UINT32 access_cookie)
5544 {
5545 return;
5546 }
5547
5548 void
5549 ar6000_dset_data_req(
5550 void *context,
5551 A_UINT32 accessCookie,
5552 A_UINT32 offset,
5553 A_UINT32 length,
5554 A_UINT32 targBuf,
5555 A_UINT32 targReplyFn,
5556 A_UINT32 targReplyArg)
5557 {
5558 }
5559
5560 int
5561 ar6000_ap_mode_profile_commit(struct ar6_softc *ar)
5562 {
5563 WMI_CONNECT_CMD p;
5564 unsigned long flags;
5565
5566 /* No change in AP's profile configuration */
5567 if(ar->ap_profile_flag==0) {
5568 A_PRINTF("COMMIT: No change in profile!!!\n");
5569 return -ENODATA;
5570 }
5571
5572 if(!ar->arSsidLen) {
5573 A_PRINTF("SSID not set!!!\n");
5574 return -ECHRNG;
5575 }
5576
5577 switch(ar->arAuthMode) {
5578 case NONE_AUTH:
5579 if((ar->arPairwiseCrypto != NONE_CRYPT) &&
5580 #ifdef WAPI_ENABLE
5581 (ar->arPairwiseCrypto != WAPI_CRYPT) &&
5582 #endif
5583 (ar->arPairwiseCrypto != WEP_CRYPT)) {
5584 A_PRINTF("Cipher not supported in AP mode Open auth\n");
5585 return -EOPNOTSUPP;
5586 }
5587 break;
5588 case WPA_PSK_AUTH:
5589 case WPA2_PSK_AUTH:
5590 case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
5591 break;
5592 default:
5593 A_PRINTF("This key mgmt type not supported in AP mode\n");
5594 return -EOPNOTSUPP;
5595 }
5596
5597 /* Update the arNetworkType */
5598 ar->arNetworkType = ar->arNextMode;
5599
5600 A_MEMZERO(&p,sizeof(p));
5601 p.ssidLength = ar->arSsidLen;
5602 A_MEMCPY(p.ssid,ar->arSsid,p.ssidLength);
5603 p.channel = ar->arChannelHint;
5604 p.networkType = ar->arNetworkType;
5605
5606 p.dot11AuthMode = ar->arDot11AuthMode;
5607 p.authMode = ar->arAuthMode;
5608 p.pairwiseCryptoType = ar->arPairwiseCrypto;
5609 p.pairwiseCryptoLen = ar->arPairwiseCryptoLen;
5610 p.groupCryptoType = ar->arGroupCrypto;
5611 p.groupCryptoLen = ar->arGroupCryptoLen;
5612 p.ctrl_flags = ar->arConnectCtrlFlags;
5613
5614 ar->arConnected = FALSE;
5615
5616 wmi_ap_profile_commit(ar->arWmi, &p);
5617 spin_lock_irqsave(&ar->arLock, flags);
5618 ar->arConnected = TRUE;
5619 netif_carrier_on(ar->arNetDev);
5620 spin_unlock_irqrestore(&ar->arLock, flags);
5621 ar->ap_profile_flag = 0;
5622 return 0;
5623 }
5624
5625 A_STATUS
5626 ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie )
5627 {
5628 sta_t *conn = NULL;
5629 conn = ieee80211_find_conn(ar, wpaie->wpa_macaddr);
5630
5631 A_MEMZERO(wpaie->wpa_ie, IEEE80211_MAX_IE);
5632 A_MEMZERO(wpaie->rsn_ie, IEEE80211_MAX_IE);
5633
5634 if(conn) {
5635 A_MEMCPY(wpaie->wpa_ie, conn->wpa_ie, IEEE80211_MAX_IE);
5636 }
5637
5638 return 0;
5639 }
5640
5641 A_STATUS
5642 is_iwioctl_allowed(A_UINT8 mode, A_UINT16 cmd)
5643 {
5644 if(cmd >= SIOCSIWCOMMIT && cmd <= SIOCGIWPOWER) {
5645 cmd -= SIOCSIWCOMMIT;
5646 if(sioctl_filter[cmd] == 0xFF) return A_OK;
5647 if(sioctl_filter[cmd] & mode) return A_OK;
5648 } else if(cmd >= SIOCIWFIRSTPRIV && cmd <= (SIOCIWFIRSTPRIV+30)) {
5649 cmd -= SIOCIWFIRSTPRIV;
5650 if(pioctl_filter[cmd] == 0xFF) return A_OK;
5651 if(pioctl_filter[cmd] & mode) return A_OK;
5652 } else {
5653 return A_ERROR;
5654 }
5655 return A_ENOTSUP;
5656 }
5657
5658 A_STATUS
5659 is_xioctl_allowed(A_UINT8 mode, int cmd)
5660 {
5661 if(sizeof(xioctl_filter)-1 < cmd) {
5662 A_PRINTF("Filter for this cmd=%d not defined\n",cmd);
5663 return 0;
5664 }
5665 if(xioctl_filter[cmd] == 0xFF) return A_OK;
5666 if(xioctl_filter[cmd] & mode) return A_OK;
5667 return A_ERROR;
5668 }
5669
5670 #ifdef WAPI_ENABLE
5671 int
5672 ap_set_wapi_key(struct ar6_softc *ar, void *ikey)
5673 {
5674 struct ieee80211req_key *ik = (struct ieee80211req_key *)ikey;
5675 KEY_USAGE keyUsage = 0;
5676 A_STATUS status;
5677
5678 if (A_MEMCMP(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN) == 0) {
5679 keyUsage = GROUP_USAGE;
5680 } else {
5681 keyUsage = PAIRWISE_USAGE;
5682 }
5683 A_PRINTF("WAPI_KEY: Type:%d ix:%d mac:%02x:%02x len:%d\n",
5684 keyUsage, ik->ik_keyix, ik->ik_macaddr[4], ik->ik_macaddr[5],
5685 ik->ik_keylen);
5686
5687 status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, WAPI_CRYPT, keyUsage,
5688 ik->ik_keylen, (A_UINT8 *)&ik->ik_keyrsc,
5689 ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
5690 SYNC_BOTH_WMIFLAG);
5691
5692 if (A_OK != status) {
5693 return -EIO;
5694 }
5695 return 0;
5696 }
5697 #endif
5698
5699 void ar6000_peer_event(
5700 void *context,
5701 A_UINT8 eventCode,
5702 A_UINT8 *macAddr)
5703 {
5704 A_UINT8 pos;
5705
5706 for (pos=0;pos<6;pos++)
5707 printk("%02x: ",*(macAddr+pos));
5708 printk("\n");
5709 }
5710
5711 #ifdef HTC_TEST_SEND_PKTS
5712 #define HTC_TEST_DUPLICATE 8
5713 static void DoHTCSendPktsTest(AR_SOFTC_T *ar, int MapNo, HTC_ENDPOINT_ID eid, st ruct sk_buff *dupskb)
5714 {
5715 struct ar_cookie *cookie;
5716 struct ar_cookie *cookieArray[HTC_TEST_DUPLICATE];
5717 struct sk_buff *new_skb;
5718 int i;
5719 int pkts = 0;
5720 HTC_PACKET_QUEUE pktQueue;
5721 EPPING_HEADER *eppingHdr;
5722
5723 eppingHdr = A_NETBUF_DATA(dupskb);
5724
5725 if (eppingHdr->Cmd_h == EPPING_CMD_NO_ECHO) {
5726 /* skip test if this is already a tx perf test */
5727 return;
5728 }
5729
5730 for (i = 0; i < HTC_TEST_DUPLICATE; i++,pkts++) {
5731 AR6000_SPIN_LOCK(&ar->arLock, 0);
5732 cookie = ar6000_alloc_cookie(ar);
5733 if (cookie != NULL) {
5734 ar->arTxPending[eid]++;
5735 ar->arTotalTxDataPending++;
5736 }
5737
5738 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
5739
5740 if (NULL == cookie) {
5741 break;
5742 }
5743
5744 new_skb = A_NETBUF_ALLOC(A_NETBUF_LEN(dupskb));
5745
5746 if (new_skb == NULL) {
5747 AR6000_SPIN_LOCK(&ar->arLock, 0);
5748 ar6000_free_cookie(ar,cookie);
5749 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
5750 break;
5751 }
5752
5753 A_NETBUF_PUT_DATA(new_skb, A_NETBUF_DATA(dupskb), A_NETBUF_LEN(dupskb));
5754 cookie->arc_bp[0] = (A_UINT32)new_skb;
5755 cookie->arc_bp[1] = MapNo;
5756 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
5757 cookie,
5758 A_NETBUF_DATA(new_skb),
5759 A_NETBUF_LEN(new_skb),
5760 eid,
5761 AR6K_DATA_PKT_TAG);
5762
5763 cookieArray[i] = cookie;
5764
5765 {
5766 EPPING_HEADER *pHdr = (EPPING_HEADER *)A_NETBUF_DATA(new_skb);
5767 pHdr->Cmd_h = EPPING_CMD_NO_ECHO; /* do not echo the packet */
5768 }
5769 }
5770
5771 if (pkts == 0) {
5772 return;
5773 }
5774
5775 INIT_HTC_PACKET_QUEUE(&pktQueue);
5776
5777 for (i = 0; i < pkts; i++) {
5778 HTC_PACKET_ENQUEUE(&pktQueue,&cookieArray[i]->HtcPkt);
5779 }
5780
5781 HTCSendPktsMultiple(ar->arHtcTarget, &pktQueue);
5782
5783 }
5784
5785 #endif
5786
5787 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
5788 EXPORT_SYMBOL(setupbtdev);
5789 #endif
OLDNEW
« no previous file with comments | « chromeos/drivers/ath6kl/miscdrv/miscdrv.h ('k') | chromeos/drivers/ath6kl/os/linux/ar6000_raw_if.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698