21504f221dd6554a1a0bbd14a222fd4c3046789b
[kernel.git] / drivers / ar6000 / ar6000 / ar6000_drv.c
1 /*
2  *
3  * Copyright (c) 2004-2007 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 static const char athId[] __attribute__ ((unused)) = "$Id: //depot/sw/releases/olca2.0-GPL/host/os/linux/ar6000_drv.c#2 $";
25
26 #include "ar6000_drv.h"
27 #include "htc.h"
28
29 MODULE_LICENSE("GPL and additional rights");
30
31 #ifndef REORG_APTC_HEURISTICS
32 #undef ADAPTIVE_POWER_THROUGHPUT_CONTROL
33 #endif /* REORG_APTC_HEURISTICS */
34
35 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
36 #define APTC_TRAFFIC_SAMPLING_INTERVAL     100  /* msec */
37 #define APTC_UPPER_THROUGHPUT_THRESHOLD    3000 /* Kbps */
38 #define APTC_LOWER_THROUGHPUT_THRESHOLD    2000 /* Kbps */
39
40 typedef struct aptc_traffic_record {
41     A_BOOL timerScheduled;
42     struct timeval samplingTS;
43     unsigned long bytesReceived;
44     unsigned long bytesTransmitted;
45 } APTC_TRAFFIC_RECORD;
46
47 A_TIMER aptcTimer;
48 APTC_TRAFFIC_RECORD aptcTR;
49 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
50
51 int bmienable = 0;
52 unsigned int bypasswmi = 0;
53 unsigned int debuglevel = 0;
54 int tspecCompliance = 1;
55 unsigned int busspeedlow = 0;
56 unsigned int onebitmode = 0;
57 unsigned int skipflash = 0;
58 unsigned int wmitimeout = 2;
59 unsigned int wlanNodeCaching = 1;
60 unsigned int enableuartprint = 0;
61 unsigned int logWmiRawMsgs = 0;
62 unsigned int enabletimerwar = 0;
63 unsigned int mbox_yield_limit = 99;
64 int reduce_credit_dribble = 1 + HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF;
65 int allow_trace_signal = 0;
66 #ifdef CONFIG_HOST_TCMD_SUPPORT
67 unsigned int testmode =0;
68 #endif
69
70 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
71 module_param(bmienable, int, 0644);
72 module_param(bypasswmi, int, 0644);
73 module_param(debuglevel, int, 0644);
74 module_param(tspecCompliance, int, 0644);
75 module_param(onebitmode, int, 0644);
76 module_param(busspeedlow, int, 0644);
77 module_param(skipflash, int, 0644);
78 module_param(wmitimeout, int, 0644);
79 module_param(wlanNodeCaching, int, 0644);
80 module_param(logWmiRawMsgs, int, 0644);
81 module_param(enableuartprint, int, 0644);
82 module_param(enabletimerwar, int, 0644);
83 module_param(mbox_yield_limit, int, 0644);
84 module_param(reduce_credit_dribble, int, 0644);
85 module_param(allow_trace_signal, int, 0644);
86 #ifdef CONFIG_HOST_TCMD_SUPPORT
87 module_param(testmode, int, 0644);
88 #endif
89 #else
90
91 #define __user
92 /* for linux 2.4 and lower */
93 MODULE_PARM(bmienable,"i");
94 MODULE_PARM(bypasswmi,"i");
95 MODULE_PARM(debuglevel, "i");
96 MODULE_PARM(onebitmode,"i");
97 MODULE_PARM(busspeedlow, "i");
98 MODULE_PARM(skipflash, "i");
99 MODULE_PARM(wmitimeout, "i");
100 MODULE_PARM(wlanNodeCaching, "i");
101 MODULE_PARM(enableuartprint,"i");
102 MODULE_PARM(logWmiRawMsgs, "i");
103 MODULE_PARM(enabletimerwar,"i");
104 MODULE_PARM(mbox_yield_limit,"i");
105 MODULE_PARM(reduce_credit_dribble,"i");
106 MODULE_PARM(allow_trace_signal,"i");
107 #ifdef CONFIG_HOST_TCMD_SUPPORT
108 MODULE_PARM(testmode, "i");
109 #endif
110 #endif
111
112 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
113 /* in 2.6.10 and later this is now a pointer to a uint */
114 unsigned int _mboxnum = HTC_MAILBOX_NUM_MAX;
115 #define mboxnum &_mboxnum
116 #else
117 unsigned int mboxnum = HTC_MAILBOX_NUM_MAX;
118 #endif
119
120 #ifdef CONFIG_AR6000_WLAN_RESET
121 unsigned int resetok = 1;
122 #else
123 unsigned int resetok = 0;
124 #endif
125
126 #ifdef DEBUG
127 A_UINT32 g_dbg_flags = DBG_DEFAULTS;
128 unsigned int debugflags = 0;
129 int debugdriver = 1;
130 unsigned int debughtc = 128;
131 unsigned int debugbmi = 1;
132 unsigned int debughif = 2;
133 unsigned int txcreditsavailable[HTC_MAILBOX_NUM_MAX] = {0};
134 unsigned int txcreditsconsumed[HTC_MAILBOX_NUM_MAX] = {0};
135 unsigned int txcreditintrenable[HTC_MAILBOX_NUM_MAX] = {0};
136 unsigned int txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX] = {0};
137
138 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
139 module_param(debugflags, int, 0644);
140 module_param(debugdriver, int, 0644);
141 module_param(debughtc, int, 0644);
142 module_param(debugbmi, int, 0644);
143 module_param(debughif, int, 0644);
144 module_param(resetok, int, 0644);
145 module_param_array(txcreditsavailable, int, mboxnum, 0644);
146 module_param_array(txcreditsconsumed, int, mboxnum, 0644);
147 module_param_array(txcreditintrenable, int, mboxnum, 0644);
148 module_param_array(txcreditintrenableaggregate, int, mboxnum, 0644);
149 #else
150 /* linux 2.4 and lower */
151 MODULE_PARM(debugflags,"i");
152 MODULE_PARM(debugdriver, "i");
153 MODULE_PARM(debughtc, "i");
154 MODULE_PARM(debugbmi, "i");
155 MODULE_PARM(debughif, "i");
156 MODULE_PARM(resetok, "i");
157 MODULE_PARM(txcreditsavailable, "0-3i");
158 MODULE_PARM(txcreditsconsumed, "0-3i");
159 MODULE_PARM(txcreditintrenable, "0-3i");
160 MODULE_PARM(txcreditintrenableaggregate, "0-3i");
161 #endif
162
163 #endif /* DEBUG */
164
165 unsigned int tx_attempt[HTC_MAILBOX_NUM_MAX] = {0};
166 unsigned int tx_post[HTC_MAILBOX_NUM_MAX] = {0};
167 unsigned int tx_complete[HTC_MAILBOX_NUM_MAX] = {0};
168 unsigned int hifBusRequestNumMax = 40;
169 unsigned int war23838_disabled = 0;
170 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
171 unsigned int enableAPTCHeuristics = 1;
172 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
173 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
174 module_param_array(tx_attempt, int, mboxnum, 0644);
175 module_param_array(tx_post, int, mboxnum, 0644);
176 module_param_array(tx_complete, int, mboxnum, 0644);
177 module_param(hifBusRequestNumMax, int, 0644);
178 module_param(war23838_disabled, int, 0644);
179 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
180 module_param(enableAPTCHeuristics, int, 0644);
181 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
182 #else
183 MODULE_PARM(tx_attempt, "0-3i");
184 MODULE_PARM(tx_post, "0-3i");
185 MODULE_PARM(tx_complete, "0-3i");
186 MODULE_PARM(hifBusRequestNumMax, "i");
187 MODULE_PARM(war23838_disabled, "i");
188 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
189 MODULE_PARM(enableAPTCHeuristics, "i");
190 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
191 #endif
192
193 #ifdef BLOCK_TX_PATH_FLAG
194 int blocktx = 0;
195 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
196 module_param(blocktx, int, 0644);
197 #else
198 MODULE_PARM(blocktx, "i");
199 #endif
200 #endif /* BLOCK_TX_PATH_FLAG */
201
202 // TODO move to arsoft_c
203 USER_RSSI_THOLD rssi_map[12];
204
205 int reconnect_flag = 0;
206
207 DECLARE_WAIT_QUEUE_HEAD(ar6000_scan_queue);
208
209 /* Function declarations */
210 static int ar6000_init_module(void);
211 static void ar6000_cleanup_module(void);
212
213 int ar6000_init(struct net_device *dev);
214 static int ar6000_open(struct net_device *dev);
215 static int ar6000_close(struct net_device *dev);
216 static void ar6000_init_control_info(AR_SOFTC_T *ar);
217 static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev);
218
219 static void ar6000_destroy(struct net_device *dev, unsigned int unregister);
220 static void ar6000_detect_error(unsigned long ptr);
221 static struct net_device_stats *ar6000_get_stats(struct net_device *dev);
222 static struct iw_statistics *ar6000_get_iwstats(struct net_device * dev);
223
224 /*
225  * HTC service connection handlers
226  */
227 static void ar6000_avail_ev(HTC_HANDLE HTCHandle);
228
229 static void ar6000_unavail_ev(void *Instance);
230
231 static void ar6000_target_failure(void *Instance, A_STATUS Status);
232
233 static void ar6000_rx(void *Context, HTC_PACKET *pPacket);
234
235 static void ar6000_rx_refill(void *Context,HTC_ENDPOINT_ID Endpoint);
236
237 static void ar6000_tx_complete(void *Context, HTC_PACKET *pPacket);
238
239 static void ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint);
240
241 static void ar6000_tx_queue_avail(void *Context, HTC_ENDPOINT_ID Endpoint);
242
243 /*
244  * Static variables
245  */
246
247 static struct net_device *ar6000_devices[MAX_AR6000];
248 extern struct iw_handler_def ath_iw_handler_def;
249 DECLARE_WAIT_QUEUE_HEAD(arEvent);
250 static void ar6000_cookie_init(AR_SOFTC_T *ar);
251 static void ar6000_cookie_cleanup(AR_SOFTC_T *ar);
252 static void ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie);
253 static struct ar_cookie *ar6000_alloc_cookie(AR_SOFTC_T *ar);
254 static void ar6000_TxDataCleanup(AR_SOFTC_T *ar);
255
256 #ifdef USER_KEYS
257 static A_STATUS ar6000_reinstall_keys(AR_SOFTC_T *ar,A_UINT8 key_op_ctrl);
258 #endif
259
260
261 static struct ar_cookie s_ar_cookie_mem[MAX_COOKIE_NUM];
262
263 #define HOST_INTEREST_ITEM_ADDRESS(ar, item)    \
264 ((ar->arTargetType == TARGET_TYPE_AR6001) ?     \
265    AR6001_HOST_INTEREST_ITEM_ADDRESS(item) :    \
266    AR6002_HOST_INTEREST_ITEM_ADDRESS(item))
267
268
269 /* Debug log support */
270
271 /*
272  * Flag to govern whether the debug logs should be parsed in the kernel
273  * or reported to the application.
274  */
275 #ifdef DEBUG
276 #define REPORT_DEBUG_LOGS_TO_APP
277 #endif
278
279 A_STATUS
280 ar6000_set_host_app_area(AR_SOFTC_T *ar)
281 {
282     A_UINT32 address, data;
283     struct host_app_area_s host_app_area;
284
285     /* Fetch the address of the host_app_area_s instance in the host interest area */
286     address = HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest);
287     if (ar6000_ReadRegDiag(ar->arHifDevice, &address, &data) != A_OK) {
288         return A_ERROR;
289     }
290     address = data;
291     host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION;
292     if (ar6000_WriteDataDiag(ar->arHifDevice, address,
293                              (A_UCHAR *)&host_app_area,
294                              sizeof(struct host_app_area_s)) != A_OK)
295     {
296         return A_ERROR;
297     }
298
299     return A_OK;
300 }
301
302 A_UINT32
303 dbglog_get_debug_hdr_ptr(AR_SOFTC_T *ar)
304 {
305     A_UINT32 param;
306     A_UINT32 address;
307     A_STATUS status;
308
309     address = HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbglog_hdr);
310     if ((status = ar6000_ReadDataDiag(ar->arHifDevice, address,
311                                       (A_UCHAR *)&param, 4)) != A_OK)
312     {
313         param = 0;
314     }
315
316     return param;
317 }
318
319 /*
320  * The dbglog module has been initialized. Its ok to access the relevant
321  * data stuctures over the diagnostic window.
322  */
323 void
324 ar6000_dbglog_init_done(AR_SOFTC_T *ar)
325 {
326     ar->dbglog_init_done = TRUE;
327 }
328
329 A_UINT32
330 dbglog_get_debug_fragment(A_INT8 *datap, A_UINT32 len, A_UINT32 limit)
331 {
332     A_INT32 *buffer;
333     A_UINT32 count;
334     A_UINT32 numargs;
335     A_UINT32 length;
336     A_UINT32 fraglen;
337
338     count = fraglen = 0;
339     buffer = (A_INT32 *)datap;
340     length = (limit >> 2);
341
342     if (len <= limit) {
343         fraglen = len;
344     } else {
345         while (count < length) {
346             numargs = DBGLOG_GET_NUMARGS(buffer[count]);
347             fraglen = (count << 2);
348             count += numargs + 1;
349         }
350     }
351
352     return fraglen;
353 }
354
355 void
356 dbglog_parse_debug_logs(A_INT8 *datap, A_UINT32 len)
357 {
358     A_INT32 *buffer;
359     A_UINT32 count;
360     A_UINT32 timestamp;
361     A_UINT32 debugid;
362     A_UINT32 moduleid;
363     A_UINT32 numargs;
364     A_UINT32 length;
365
366     count = 0;
367     buffer = (A_INT32 *)datap;
368     length = (len >> 2);
369     while (count < length) {
370         debugid = DBGLOG_GET_DBGID(buffer[count]);
371         moduleid = DBGLOG_GET_MODULEID(buffer[count]);
372         numargs = DBGLOG_GET_NUMARGS(buffer[count]);
373         timestamp = DBGLOG_GET_TIMESTAMP(buffer[count]);
374         switch (numargs) {
375             case 0:
376             AR_DEBUG_PRINTF("%d %d (%d)\n", moduleid, debugid, timestamp);
377             break;
378
379             case 1:
380             AR_DEBUG_PRINTF("%d %d (%d): 0x%x\n", moduleid, debugid,
381                             timestamp, buffer[count+1]);
382             break;
383
384             case 2:
385             AR_DEBUG_PRINTF("%d %d (%d): 0x%x, 0x%x\n", moduleid, debugid,
386                             timestamp, buffer[count+1], buffer[count+2]);
387             break;
388
389             default:
390             AR_DEBUG_PRINTF("Invalid args: %d\n", numargs);
391         }
392         count += numargs + 1;
393     }
394 }
395
396 int
397 ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar)
398 {
399     struct dbglog_hdr_s debug_hdr;
400     struct dbglog_buf_s debug_buf;
401     A_UINT32 address;
402     A_UINT32 length;
403     A_UINT32 dropped;
404     A_UINT32 firstbuf;
405     A_UINT32 debug_hdr_ptr;
406
407     if (!ar->dbglog_init_done) return A_ERROR;
408
409 #ifndef CONFIG_AR6000_WLAN_DEBUG
410     return 0;
411 #endif
412
413     AR6000_SPIN_LOCK(&ar->arLock, 0);
414
415     if (ar->dbgLogFetchInProgress) {
416         AR6000_SPIN_UNLOCK(&ar->arLock, 0);
417         return A_EBUSY;
418     }
419
420         /* block out others */
421     ar->dbgLogFetchInProgress = TRUE;
422
423     AR6000_SPIN_UNLOCK(&ar->arLock, 0);
424
425     debug_hdr_ptr = dbglog_get_debug_hdr_ptr(ar);
426     printk("debug_hdr_ptr: 0x%x\n", debug_hdr_ptr);
427
428     /* Get the contents of the ring buffer */
429     if (debug_hdr_ptr) {
430         address = debug_hdr_ptr;
431         length = sizeof(struct dbglog_hdr_s);
432         ar6000_ReadDataDiag(ar->arHifDevice, address,
433                             (A_UCHAR *)&debug_hdr, length);
434         address = (A_UINT32)debug_hdr.dbuf;
435         firstbuf = address;
436         dropped = debug_hdr.dropped;
437         length = sizeof(struct dbglog_buf_s);
438         ar6000_ReadDataDiag(ar->arHifDevice, address,
439                             (A_UCHAR *)&debug_buf, length);
440
441         do {
442             address = (A_UINT32)debug_buf.buffer;
443             length = debug_buf.length;
444             if ((length) && (debug_buf.length <= debug_buf.bufsize)) {
445                 /* Rewind the index if it is about to overrun the buffer */
446                 if (ar->log_cnt > (DBGLOG_HOST_LOG_BUFFER_SIZE - length)) {
447                     ar->log_cnt = 0;
448                 }
449                 if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address,
450                                     (A_UCHAR *)&ar->log_buffer[ar->log_cnt], length))
451                 {
452                     break;
453                 }
454                 ar6000_dbglog_event(ar, dropped, &ar->log_buffer[ar->log_cnt], length);
455                 ar->log_cnt += length;
456             } else {
457                 AR_DEBUG_PRINTF("Length: %d (Total size: %d)\n",
458                                 debug_buf.length, debug_buf.bufsize);
459             }
460
461             address = (A_UINT32)debug_buf.next;
462             length = sizeof(struct dbglog_buf_s);
463             if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address,
464                                 (A_UCHAR *)&debug_buf, length))
465             {
466                 break;
467             }
468
469         } while (address != firstbuf);
470     }
471
472     ar->dbgLogFetchInProgress = FALSE;
473
474     return A_OK;
475 }
476
477 void
478 ar6000_dbglog_event(AR_SOFTC_T *ar, A_UINT32 dropped,
479                     A_INT8 *buffer, A_UINT32 length)
480 {
481 #ifdef REPORT_DEBUG_LOGS_TO_APP
482     #define MAX_WIRELESS_EVENT_SIZE 252
483     /*
484      * Break it up into chunks of MAX_WIRELESS_EVENT_SIZE bytes of messages.
485      * There seems to be a limitation on the length of message that could be
486      * transmitted to the user app via this mechanism.
487      */
488     A_UINT32 send, sent;
489
490     sent = 0;
491     send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
492                                      MAX_WIRELESS_EVENT_SIZE);
493     while (send) {
494         ar6000_send_event_to_app(ar, WMIX_DBGLOG_EVENTID, &buffer[sent], send);
495         sent += send;
496         send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
497                                          MAX_WIRELESS_EVENT_SIZE);
498     }
499 #else
500     AR_DEBUG_PRINTF("Dropped logs: 0x%x\nDebug info length: %d\n",
501                     dropped, length);
502
503     /* Interpret the debug logs */
504     dbglog_parse_debug_logs(buffer, length);
505 #endif /* REPORT_DEBUG_LOGS_TO_APP */
506 }
507
508
509
510 static int __init
511 ar6000_init_module(void)
512 {
513     static int probed = 0;
514     A_STATUS status;
515     HTC_INIT_INFO initInfo;
516
517     A_MEMZERO(&initInfo,sizeof(initInfo));
518     initInfo.AddInstance = ar6000_avail_ev;
519     initInfo.DeleteInstance = ar6000_unavail_ev;
520     initInfo.TargetFailure = ar6000_target_failure;
521
522
523 #ifdef DEBUG
524     /* Set the debug flags if specified at load time */
525     if(debugflags != 0)
526     {
527         g_dbg_flags = debugflags;
528     }
529 #endif
530
531     if (probed) {
532         return -ENODEV;
533     }
534     probed++;
535
536 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
537     memset(&aptcTR, 0, sizeof(APTC_TRAFFIC_RECORD));
538 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
539
540 #ifdef CONFIG_HOST_GPIO_SUPPORT
541     ar6000_gpio_init();
542 #endif /* CONFIG_HOST_GPIO_SUPPORT */
543
544     status = HTCInit(&initInfo);
545     if(status != A_OK)
546         return -ENODEV;
547
548     return 0;
549 }
550
551 static void __exit
552 ar6000_cleanup_module(void)
553 {
554     int i = 0;
555     struct net_device *ar6000_netdev;
556
557 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
558     /* Delete the Adaptive Power Control timer */
559     if (timer_pending(&aptcTimer)) {
560         del_timer_sync(&aptcTimer);
561     }
562 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
563
564     for (i=0; i < MAX_AR6000; i++) {
565         if (ar6000_devices[i] != NULL) {
566             ar6000_netdev = ar6000_devices[i];
567             ar6000_devices[i] = NULL;
568             ar6000_destroy(ar6000_netdev, 1);
569         }
570     }
571
572         /* shutting down HTC will cause the HIF layer to detach from the
573          * underlying bus driver which will cause the subsequent deletion of
574          * all HIF and HTC instances */
575     HTCShutDown();
576
577     AR_DEBUG_PRINTF("ar6000_cleanup: success\n");
578 }
579
580 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
581 void
582 aptcTimerHandler(unsigned long arg)
583 {
584     A_UINT32 numbytes;
585     A_UINT32 throughput;
586     AR_SOFTC_T *ar;
587     A_STATUS status;
588
589     ar = (AR_SOFTC_T *)arg;
590     A_ASSERT(ar != NULL);
591     A_ASSERT(!timer_pending(&aptcTimer));
592
593     AR6000_SPIN_LOCK(&ar->arLock, 0);
594
595     /* Get the number of bytes transferred */
596     numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
597     aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
598
599     /* Calculate and decide based on throughput thresholds */
600     throughput = ((numbytes * 8)/APTC_TRAFFIC_SAMPLING_INTERVAL); /* Kbps */
601     if (throughput < APTC_LOWER_THROUGHPUT_THRESHOLD) {
602         /* Enable Sleep and delete the timer */
603         A_ASSERT(ar->arWmiReady == TRUE);
604         AR6000_SPIN_UNLOCK(&ar->arLock, 0);
605         status = wmi_powermode_cmd(ar->arWmi, REC_POWER);
606         AR6000_SPIN_LOCK(&ar->arLock, 0);
607         A_ASSERT(status == A_OK);
608         aptcTR.timerScheduled = FALSE;
609     } else {
610         A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
611     }
612
613     AR6000_SPIN_UNLOCK(&ar->arLock, 0);
614 }
615 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
616
617
618
619 /* set HTC block size, assume BMI is already initialized */
620 A_STATUS ar6000_SetHTCBlockSize(AR_SOFTC_T *ar)
621 {
622     A_STATUS status;
623     A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX];
624
625     do {
626             /* get the block sizes */
627         status = HIFConfigureDevice(ar->arHifDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
628                                     blocksizes, sizeof(blocksizes));
629
630         if (A_FAILED(status)) {
631             AR_DEBUG_PRINTF("Failed to get block size info from HIF layer...\n");
632             break;
633         }
634             /* note: we actually get the block size for mailbox 1, for SDIO the block
635              * size on mailbox 0 is artificially set to 1 */
636             /* must be a power of 2 */
637         A_ASSERT((blocksizes[1] & (blocksizes[1] - 1)) == 0);
638
639             /* set the host interest area for the block size */
640         status = BMIWriteMemory(ar->arHifDevice,
641                                 HOST_INTEREST_ITEM_ADDRESS(ar, hi_mbox_io_block_sz),
642                                 (A_UCHAR *)&blocksizes[1],
643                                 4);
644
645         if (A_FAILED(status)) {
646             AR_DEBUG_PRINTF("BMIWriteMemory for IO block size failed \n");
647             break;
648         }
649
650         AR_DEBUG_PRINTF("Block Size Set: %d (target address:0x%X)\n",
651                 blocksizes[1], HOST_INTEREST_ITEM_ADDRESS(ar, hi_mbox_io_block_sz));
652
653             /* set the host interest area for the mbox ISR yield limit */
654         status = BMIWriteMemory(ar->arHifDevice,
655                                 HOST_INTEREST_ITEM_ADDRESS(ar, hi_mbox_isr_yield_limit),
656                                 (A_UCHAR *)&mbox_yield_limit,
657                                 4);
658
659         if (A_FAILED(status)) {
660             AR_DEBUG_PRINTF("BMIWriteMemory for yield limit failed \n");
661             break;
662         }
663
664     } while (FALSE);
665
666     return status;
667 }
668
669 static void free_raw_buffers(AR_SOFTC_T *ar)
670 {
671     int i, j;
672
673     for (i = 0; i != HTC_RAW_STREAM_NUM_MAX; i++) {
674         for (j = 0; j != RAW_HTC_READ_BUFFERS_NUM; j++)
675             kfree(ar->raw_htc_read_buffer[i][j]);
676         for (j = 0; j != RAW_HTC_WRITE_BUFFERS_NUM; j++)
677             kfree(ar->raw_htc_write_buffer[i][j]);
678     }
679 }
680
681 static int alloc_raw_buffers(AR_SOFTC_T *ar)
682 {
683     int i, j;
684     raw_htc_buffer *b;
685
686     for (i = 0; i != HTC_RAW_STREAM_NUM_MAX; i++) {
687         for (j = 0; j != RAW_HTC_READ_BUFFERS_NUM; j++) {
688             b = kzalloc(sizeof(*b), GFP_KERNEL);
689             if (!b)
690                 return -ENOMEM;
691             ar->raw_htc_read_buffer[i][j] = b;
692         }
693         for (j = 0; j != RAW_HTC_WRITE_BUFFERS_NUM; j++) {
694             b = kzalloc(sizeof(*b), GFP_KERNEL);
695             if (!b)
696                 return -ENOMEM;
697             ar->raw_htc_write_buffer[i][j] = b;
698         }
699     }
700     return 0;
701 }
702
703 /*
704  * HTC Event handlers
705  */
706 static void
707 ar6000_avail_ev(HTC_HANDLE HTCHandle)
708 {
709     int i;
710     struct net_device *dev;
711     AR_SOFTC_T *ar;
712     int device_index = 0;
713
714     AR_DEBUG_PRINTF("ar6000_available\n");
715
716     for (i=0; i < MAX_AR6000; i++) {
717         if (ar6000_devices[i] == NULL) {
718             break;
719         }
720     }
721
722     if (i == MAX_AR6000) {
723         AR_DEBUG_PRINTF("ar6000_available: max devices reached\n");
724         return;
725     }
726
727     /* Save this. It gives a bit better readability especially since */
728     /* we use another local "i" variable below.                      */
729     device_index = i;
730
731     A_ASSERT(HTCHandle != NULL);
732
733     dev = alloc_etherdev(sizeof(AR_SOFTC_T));
734     if (dev == NULL) {
735         AR_DEBUG_PRINTF("ar6000_available: can't alloc etherdev\n");
736         return;
737     }
738
739     ether_setup(dev);
740
741     if (netdev_priv(dev) == NULL) {
742         printk(KERN_CRIT "ar6000_available: Could not allocate memory\n");
743         return;
744     }
745
746     A_MEMZERO(netdev_priv(dev), sizeof(AR_SOFTC_T));
747
748     ar                       = (AR_SOFTC_T *)netdev_priv(dev);
749     ar->arNetDev             = dev;
750     ar->arHtcTarget          = HTCHandle;
751     ar->arHifDevice          = HTCGetHifDevice(HTCHandle);
752     ar->arWlanState          = WLAN_ENABLED;
753     ar->arRadioSwitch        = WLAN_ENABLED;
754     ar->arDeviceIndex        = device_index;
755
756     A_INIT_TIMER(&ar->arHBChallengeResp.timer, ar6000_detect_error, dev);
757     ar->arHBChallengeResp.seqNum = 0;
758     ar->arHBChallengeResp.outstanding = FALSE;
759     ar->arHBChallengeResp.missCnt = 0;
760     ar->arHBChallengeResp.frequency = AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT;
761     ar->arHBChallengeResp.missThres = AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT;
762
763     ar6000_init_control_info(ar);
764     init_waitqueue_head(&arEvent);
765     sema_init(&ar->arSem, 1);
766
767     if (alloc_raw_buffers(ar)) {
768         free_raw_buffers(ar);
769         /*
770          * @@@ Clean up our own mess, but for anything else, cheerfully mimick
771          * the beautiful error non-handling of the rest of this function.
772          */
773         return;
774     }
775
776 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
777     A_INIT_TIMER(&aptcTimer, aptcTimerHandler, ar);
778 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
779
780     /*
781      * If requested, perform some magic which requires no cooperation from
782      * the Target.  It causes the Target to ignore flash and execute to the
783      * OS from ROM.
784      *
785      * This is intended to support recovery from a corrupted flash on Targets
786      * that support flash.
787      */
788     if (skipflash)
789     {
790         ar6000_reset_device_skipflash(ar->arHifDevice);
791             }
792
793     BMIInit();
794     {
795         struct bmi_target_info targ_info;
796
797         if (BMIGetTargetInfo(ar->arHifDevice, &targ_info) != A_OK) {
798             return;
799         }
800
801         ar->arVersion.target_ver = targ_info.target_ver;
802         ar->arTargetType = targ_info.target_type;
803     }
804
805     if (enableuartprint) {
806         A_UINT32 param;
807         param = 1;
808         if (BMIWriteMemory(ar->arHifDevice,
809                            HOST_INTEREST_ITEM_ADDRESS(ar, hi_serial_enable),
810                            (A_UCHAR *)&param,
811                            4)!= A_OK)
812         {
813              AR_DEBUG_PRINTF("BMIWriteMemory for enableuartprint failed \n");
814              return ;
815         }
816         AR_DEBUG_PRINTF("Serial console prints enabled\n");
817     }
818 #ifdef CONFIG_HOST_TCMD_SUPPORT
819     if(testmode) {
820         ar->arTargetMode = AR6000_TCMD_MODE;
821     }else {
822         ar->arTargetMode = AR6000_WLAN_MODE;
823     }
824 #endif
825     if (enabletimerwar) {
826         A_UINT32 param;
827
828         if (BMIReadMemory(ar->arHifDevice,
829             HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
830             (A_UCHAR *)&param,
831             4)!= A_OK)
832         {
833             AR_DEBUG_PRINTF("BMIReadMemory for enabletimerwar failed \n");
834             return;
835         }
836
837         param |= HI_OPTION_TIMER_WAR;
838
839         if (BMIWriteMemory(ar->arHifDevice,
840             HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
841             (A_UCHAR *)&param,
842             4) != A_OK)
843         {
844             AR_DEBUG_PRINTF("BMIWriteMemory for enabletimerwar failed \n");
845             return;
846         }
847         AR_DEBUG_PRINTF("Timer WAR enabled\n");
848     }
849
850
851         /* since BMIInit is called in the driver layer, we have to set the block
852          * size here for the target */
853
854     if (A_FAILED(ar6000_SetHTCBlockSize(ar))) {
855         return;
856     }
857
858     spin_lock_init(&ar->arLock);
859
860     /* Don't install the init function if BMI is requested */
861     if(!bmienable)
862     {
863         dev->init = ar6000_init;
864     } else {
865         AR_DEBUG_PRINTF(" BMI enabled \n");
866     }
867
868     dev->open = &ar6000_open;
869     dev->stop = &ar6000_close;
870     dev->hard_start_xmit = &ar6000_data_tx;
871     dev->get_stats = &ar6000_get_stats;
872
873     /* dev->tx_timeout = ar6000_tx_timeout; */
874     dev->do_ioctl = &ar6000_ioctl;
875     dev->watchdog_timeo = AR6000_TX_TIMEOUT;
876     ar6000_ioctl_iwsetup(&ath_iw_handler_def);
877     dev->wireless_handlers = &ath_iw_handler_def;
878     ath_iw_handler_def.get_wireless_stats = ar6000_get_iwstats; /*Displayed via proc fs */
879
880     /*
881      * We need the OS to provide us with more headroom in order to
882      * perform dix to 802.3, WMI header encap, and the HTC header
883      */
884     dev->hard_header_len = ETH_HLEN + sizeof(ATH_LLC_SNAP_HDR) +
885         sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN;
886
887     /* This runs the init function */
888     SET_NETDEV_DEV(dev, HIFGetOSDevice(ar->arHifDevice));
889     if (register_netdev(dev)) {
890         AR_DEBUG_PRINTF("ar6000_avail: register_netdev failed\n");
891         ar6000_destroy(dev, 0);
892         return;
893     }
894
895     HTCSetInstance(ar->arHtcTarget, ar);
896
897     /* We only register the device in the global list if we succeed. */
898     /* If the device is in the global list, it will be destroyed     */
899     /* when the module is unloaded.                                  */
900     ar6000_devices[device_index] = dev;
901
902     AR_DEBUG_PRINTF("ar6000_avail: name=%s htcTarget=0x%x, dev=0x%x (%d), ar=0x%x\n",
903                     dev->name, (A_UINT32)HTCHandle, (A_UINT32)dev, device_index,
904                     (A_UINT32)ar);
905 }
906
907 static void ar6000_target_failure(void *Instance, A_STATUS Status)
908 {
909     AR_SOFTC_T *ar = (AR_SOFTC_T *)Instance;
910     WMI_TARGET_ERROR_REPORT_EVENT errEvent;
911     static A_BOOL sip = FALSE;
912
913     if (Status != A_OK) {
914         if (timer_pending(&ar->arHBChallengeResp.timer)) {
915             A_UNTIMEOUT(&ar->arHBChallengeResp.timer);
916         }
917
918         /* try dumping target assertion information (if any) */
919         ar6000_dump_target_assert_info(ar->arHifDevice,ar->arTargetType);
920
921         /*
922          * Fetch the logs from the target via the diagnostic
923          * window.
924          */
925         ar6000_dbglog_get_debug_logs(ar);
926
927         /* Report the error only once */
928         if (!sip) {
929             sip = TRUE;
930             errEvent.errorVal = WMI_TARGET_COM_ERR |
931                                 WMI_TARGET_FATAL_ERR;
932 #ifdef SEND_EVENT_TO_APP
933             ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID,
934                                      (A_UINT8 *)&errEvent,
935                                      sizeof(WMI_TARGET_ERROR_REPORT_EVENT));
936 #endif
937         }
938     }
939 }
940
941 static void
942 ar6000_unavail_ev(void *Instance)
943 {
944     AR_SOFTC_T *ar = (AR_SOFTC_T *)Instance;
945         /* NULL out it's entry in the global list */
946     ar6000_devices[ar->arDeviceIndex] = NULL;
947     ar6000_destroy(ar->arNetDev, 1);
948 }
949
950 /*
951  * We need to differentiate between the surprise and planned removal of the
952  * device because of the following consideration:
953  * - In case of surprise removal, the hcd already frees up the pending
954  *   for the device and hence there is no need to unregister the function
955  *   driver inorder to get these requests. For planned removal, the function
956  *   driver has to explictly unregister itself to have the hcd return all the
957  *   pending requests before the data structures for the devices are freed up.
958  *   Note that as per the current implementation, the function driver will
959  *   end up releasing all the devices since there is no API to selectively
960  *   release a particular device.
961  * - Certain commands issued to the target can be skipped for surprise
962  *   removal since they will anyway not go through.
963  */
964 static void
965 ar6000_destroy(struct net_device *dev, unsigned int unregister)
966 {
967     AR_SOFTC_T *ar;
968
969     AR_DEBUG_PRINTF("+ar6000_destroy \n");
970
971     if((dev == NULL) || ((ar = netdev_priv(dev)) == NULL))
972     {
973         AR_DEBUG_PRINTF("%s(): Failed to get device structure.\n", __func__);
974         return;
975     }
976
977     /* Stop the transmit queues */
978     netif_stop_queue(dev);
979
980     /* Disable the target and the interrupts associated with it */
981     if (ar->arWmiReady == TRUE)
982     {
983         if (!bypasswmi)
984         {
985             if (ar->arConnected == TRUE || ar->arConnectPending == TRUE)
986             {
987                 AR_DEBUG_PRINTF("%s(): Disconnect\n", __func__);
988                 AR6000_SPIN_LOCK(&ar->arLock, 0);
989                 ar6000_init_profile_info(ar);
990                 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
991                 wmi_disconnect_cmd(ar->arWmi);
992             }
993
994             ar6000_dbglog_get_debug_logs(ar);
995             ar->arWmiReady  = FALSE;
996             ar->arConnected = FALSE;
997             ar->arConnectPending = FALSE;
998             wmi_shutdown(ar->arWmi);
999             ar->arWmiEnabled = FALSE;
1000             ar->arWmi = NULL;
1001             ar->arWlanState = WLAN_ENABLED;
1002 #ifdef USER_KEYS
1003             ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
1004             ar->user_key_ctrl      = 0;
1005 #endif
1006         }
1007
1008          AR_DEBUG_PRINTF("%s(): WMI stopped\n", __func__);
1009     }
1010     else
1011     {
1012         AR_DEBUG_PRINTF("%s(): WMI not ready 0x%08x 0x%08x\n",
1013             __func__, (unsigned int) ar, (unsigned int) ar->arWmi);
1014
1015         /* Shut down WMI if we have started it */
1016         if(ar->arWmiEnabled == TRUE)
1017         {
1018             AR_DEBUG_PRINTF("%s(): Shut down WMI\n", __func__);
1019             wmi_shutdown(ar->arWmi);
1020             ar->arWmiEnabled = FALSE;
1021             ar->arWmi = NULL;
1022         }
1023     }
1024
1025     /* stop HTC */
1026     HTCStop(ar->arHtcTarget);
1027
1028     /* set the instance to NULL so we do not get called back on remove incase we
1029      * we're explicity destroyed by module unload */
1030     HTCSetInstance(ar->arHtcTarget, NULL);
1031
1032     if (resetok) {
1033         /* try to reset the device if we can
1034          * The driver may have been configure NOT to reset the target during
1035          * a debug session */
1036         AR_DEBUG_PRINTF(" Attempting to reset target on instance destroy.... \n");
1037         ar6000_reset_device(ar->arHifDevice, ar->arTargetType);
1038     } else {
1039         AR_DEBUG_PRINTF(" Host does not want target reset. \n");
1040     }
1041
1042        /* Done with cookies */
1043     ar6000_cookie_cleanup(ar);
1044
1045     /* Cleanup BMI */
1046     BMIInit();
1047
1048     /* Clear the tx counters */
1049     memset(tx_attempt, 0, sizeof(tx_attempt));
1050     memset(tx_post, 0, sizeof(tx_post));
1051     memset(tx_complete, 0, sizeof(tx_complete));
1052
1053
1054     /* Free up the device data structure */
1055     if (unregister)
1056             unregister_netdev(dev);
1057
1058     free_raw_buffers(ar);
1059
1060 #ifndef free_netdev
1061     kfree(dev);
1062 #else
1063     free_netdev(dev);
1064 #endif
1065
1066     AR_DEBUG_PRINTF("-ar6000_destroy \n");
1067 }
1068
1069 static void ar6000_detect_error(unsigned long ptr)
1070 {
1071     struct net_device *dev = (struct net_device *)ptr;
1072     AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev);
1073     WMI_TARGET_ERROR_REPORT_EVENT errEvent;
1074
1075     AR6000_SPIN_LOCK(&ar->arLock, 0);
1076
1077     if (ar->arHBChallengeResp.outstanding) {
1078         ar->arHBChallengeResp.missCnt++;
1079     } else {
1080         ar->arHBChallengeResp.missCnt = 0;
1081     }
1082
1083     if (ar->arHBChallengeResp.missCnt > ar->arHBChallengeResp.missThres) {
1084         /* Send Error Detect event to the application layer and do not reschedule the error detection module timer */
1085         ar->arHBChallengeResp.missCnt = 0;
1086         ar->arHBChallengeResp.seqNum = 0;
1087         errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR;
1088         AR6000_SPIN_UNLOCK(&ar->arLock, 0);
1089 #ifdef SEND_EVENT_TO_APP
1090         ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID,
1091                                  (A_UINT8 *)&errEvent,
1092                                  sizeof(WMI_TARGET_ERROR_REPORT_EVENT));
1093 #endif
1094         return;
1095     }
1096
1097     /* Generate the sequence number for the next challenge */
1098     ar->arHBChallengeResp.seqNum++;
1099     ar->arHBChallengeResp.outstanding = TRUE;
1100
1101     AR6000_SPIN_UNLOCK(&ar->arLock, 0);
1102
1103     /* Send the challenge on the control channel */
1104     if (wmi_get_challenge_resp_cmd(ar->arWmi, ar->arHBChallengeResp.seqNum, DRV_HB_CHALLENGE) != A_OK) {
1105         AR_DEBUG_PRINTF("Unable to send heart beat challenge\n");
1106     }
1107
1108
1109     /* Reschedule the timer for the next challenge */
1110     A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0);
1111 }
1112
1113 void ar6000_init_profile_info(AR_SOFTC_T *ar)
1114 {
1115     ar->arSsidLen            = 0;
1116     A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1117     ar->arNetworkType        = INFRA_NETWORK;
1118     ar->arDot11AuthMode      = OPEN_AUTH;
1119     ar->arAuthMode           = NONE_AUTH;
1120     ar->arPairwiseCrypto     = NONE_CRYPT;
1121     ar->arPairwiseCryptoLen  = 0;
1122     ar->arGroupCrypto        = NONE_CRYPT;
1123     ar->arGroupCryptoLen     = 0;
1124     A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
1125     A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
1126     A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
1127     ar->arBssChannel = 0;
1128 }
1129
1130 static void
1131 ar6000_init_control_info(AR_SOFTC_T *ar)
1132 {
1133     ar->arWmiEnabled         = FALSE;
1134     ar6000_init_profile_info(ar);
1135     ar->arDefTxKeyIndex      = 0;
1136     A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
1137     ar->arChannelHint        = 0;
1138     ar->arListenInterval     = MAX_LISTEN_INTERVAL;
1139     ar->arVersion.host_ver   = AR6K_SW_VERSION;
1140     ar->arRssi               = 0;
1141     ar->arTxPwr              = 0;
1142     ar->arTxPwrSet           = FALSE;
1143     ar->arSkipScan           = 0;
1144     ar->arBeaconInterval     = 0;
1145     ar->arBitRate            = 0;
1146     ar->arMaxRetries         = 0;
1147     ar->arWmmEnabled         = TRUE;
1148 }
1149
1150 static int
1151 ar6000_open(struct net_device *dev)
1152 {
1153     /* Wake up the queues */
1154     netif_start_queue(dev);
1155
1156     return 0;
1157 }
1158
1159 static int
1160 ar6000_close(struct net_device *dev)
1161 {
1162     netif_stop_queue(dev);
1163
1164     return 0;
1165 }
1166
1167 /* connect to a service */
1168 static A_STATUS ar6000_connectservice(AR_SOFTC_T               *ar,
1169                                       HTC_SERVICE_CONNECT_REQ  *pConnect,
1170                                       WMI_PRI_STREAM_ID        WmiStreamID,
1171                                       char                     *pDesc)
1172 {
1173     A_STATUS                 status;
1174     HTC_SERVICE_CONNECT_RESP response;
1175
1176     do {
1177
1178         A_MEMZERO(&response,sizeof(response));
1179
1180         status = HTCConnectService(ar->arHtcTarget,
1181                                    pConnect,
1182                                    &response);
1183
1184         if (A_FAILED(status)) {
1185             AR_DEBUG_PRINTF(" Failed to connect to %s service status:%d \n", pDesc, status);
1186             break;
1187         }
1188
1189         if (WmiStreamID == WMI_NOT_MAPPED) {
1190                 /* done */
1191             break;
1192         }
1193
1194             /* set endpoint mapping for the WMI stream in the driver layer */
1195         arSetWMIStream2EndpointIDMap(ar,WmiStreamID,response.Endpoint);
1196
1197     } while (FALSE);
1198
1199     return status;
1200 }
1201
1202 static void ar6000_TxDataCleanup(AR_SOFTC_T *ar)
1203 {
1204         /* flush all the data (non-control) streams
1205          * we only flush packets that are tagged as data, we leave any control packets that
1206          * were in the TX queues alone */
1207     HTCFlushEndpoint(ar->arHtcTarget,
1208                      arWMIStream2EndpointID(ar,WMI_BEST_EFFORT_PRI),
1209                      AR6K_DATA_PKT_TAG);
1210     HTCFlushEndpoint(ar->arHtcTarget,
1211                      arWMIStream2EndpointID(ar,WMI_LOW_PRI),
1212                      AR6K_DATA_PKT_TAG);
1213     HTCFlushEndpoint(ar->arHtcTarget,
1214                      arWMIStream2EndpointID(ar,WMI_HIGH_PRI),
1215                      AR6K_DATA_PKT_TAG);
1216     HTCFlushEndpoint(ar->arHtcTarget,
1217                      arWMIStream2EndpointID(ar,WMI_HIGHEST_PRI),
1218                      AR6K_DATA_PKT_TAG);
1219 }
1220
1221 /* This function does one time initialization for the lifetime of the device */
1222 int ar6000_init(struct net_device *dev)
1223 {
1224     AR_SOFTC_T *ar;
1225     A_STATUS    status;
1226     A_INT32     timeleft;
1227
1228     if((ar = netdev_priv(dev)) == NULL)
1229     {
1230         return(-EIO);
1231     }
1232
1233     /* Do we need to finish the BMI phase */
1234     if(BMIDone(ar->arHifDevice) != A_OK)
1235     {
1236         return -EIO;
1237     }
1238
1239     if (!bypasswmi)
1240     {
1241 #if 0 /* TBDXXX */
1242         if (ar->arVersion.host_ver != ar->arVersion.target_ver) {
1243             A_PRINTF("WARNING: Host version 0x%x does not match Target "
1244                     " version 0x%x!\n",
1245                     ar->arVersion.host_ver, ar->arVersion.target_ver);
1246         }
1247 #endif
1248
1249         /* Indicate that WMI is enabled (although not ready yet) */
1250         ar->arWmiEnabled = TRUE;
1251         if ((ar->arWmi = wmi_init((void *) ar)) == NULL)
1252         {
1253             AR_DEBUG_PRINTF("%s() Failed to initialize WMI.\n", __func__);
1254             return(-EIO);
1255         }
1256
1257         AR_DEBUG_PRINTF("%s() Got WMI @ 0x%08x.\n", __func__,
1258             (unsigned int) ar->arWmi);
1259     }
1260
1261     do {
1262         HTC_SERVICE_CONNECT_REQ connect;
1263
1264             /* the reason we have to wait for the target here is that the driver layer
1265              * has to init BMI in order to set the host block size,
1266              */
1267         status = HTCWaitTarget(ar->arHtcTarget);
1268
1269         if (A_FAILED(status)) {
1270             break;
1271         }
1272
1273         A_MEMZERO(&connect,sizeof(connect));
1274             /* meta data is unused for now */
1275         connect.pMetaData = NULL;
1276         connect.MetaDataLength = 0;
1277             /* these fields are the same for all service endpoints */
1278         connect.EpCallbacks.pContext = ar;
1279         connect.EpCallbacks.EpTxComplete = ar6000_tx_complete;
1280         connect.EpCallbacks.EpRecv = ar6000_rx;
1281         connect.EpCallbacks.EpRecvRefill = ar6000_rx_refill;
1282         connect.EpCallbacks.EpSendFull = ar6000_tx_queue_full;
1283         connect.EpCallbacks.EpSendAvail = ar6000_tx_queue_avail;
1284             /* set the max queue depth so that our ar6000_tx_queue_full handler gets called.
1285              * Linux has the peculiarity of not providing flow control between the
1286              * NIC and the network stack. There is no API to indicate that a TX packet
1287              * was sent which could provide some back pressure to the network stack.
1288              * Under linux you would have to wait till the network stack consumed all sk_buffs
1289              * before any back-flow kicked in. Which isn't very friendly.
1290              * So we have to manage this ourselves */
1291         connect.MaxSendQueueDepth = 32;
1292
1293             /* connect to control service */
1294         connect.ServiceID = WMI_CONTROL_SVC;
1295         status = ar6000_connectservice(ar,
1296                                        &connect,
1297                                        WMI_CONTROL_PRI,
1298                                        "WMI CONTROL");
1299         if (A_FAILED(status)) {
1300             break;
1301         }
1302
1303             /* for the remaining data services set the connection flag to reduce dribbling,
1304              * if configured to do so */
1305         if (reduce_credit_dribble) {
1306             connect.ConnectionFlags |= HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE;
1307             /* the credit dribble trigger threshold is (reduce_credit_dribble - 1) for a value
1308              * of 0-3 */
1309             connect.ConnectionFlags &= ~HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
1310             connect.ConnectionFlags |=
1311                         ((A_UINT16)reduce_credit_dribble - 1) & HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
1312         }
1313             /* connect to best-effort service */
1314         connect.ServiceID = WMI_DATA_BE_SVC;
1315
1316         status = ar6000_connectservice(ar,
1317                                        &connect,
1318                                        WMI_BEST_EFFORT_PRI,
1319                                        "WMI DATA BE");
1320         if (A_FAILED(status)) {
1321             break;
1322         }
1323
1324             /* connect to back-ground
1325              * map this to WMI LOW_PRI */
1326         connect.ServiceID = WMI_DATA_BK_SVC;
1327         status = ar6000_connectservice(ar,
1328                                        &connect,
1329                                        WMI_LOW_PRI,
1330                                        "WMI DATA BK");
1331         if (A_FAILED(status)) {
1332             break;
1333         }
1334
1335             /* connect to Video service, map this to
1336              * to HI PRI */
1337         connect.ServiceID = WMI_DATA_VI_SVC;
1338         status = ar6000_connectservice(ar,
1339                                        &connect,
1340                                        WMI_HIGH_PRI,
1341                                        "WMI DATA VI");
1342         if (A_FAILED(status)) {
1343             break;
1344         }
1345
1346             /* connect to VO service, this is currently not
1347              * mapped to a WMI priority stream due to historical reasons.
1348              * WMI originally defined 3 priorities over 3 mailboxes
1349              * We can change this when WMI is reworked so that priorities are not
1350              * dependent on mailboxes */
1351         connect.ServiceID = WMI_DATA_VO_SVC;
1352         status = ar6000_connectservice(ar,
1353                                        &connect,
1354                                        WMI_HIGHEST_PRI,
1355                                        "WMI DATA VO");
1356         if (A_FAILED(status)) {
1357             break;
1358         }
1359
1360         A_ASSERT(arWMIStream2EndpointID(ar,WMI_CONTROL_PRI) != 0);
1361         A_ASSERT(arWMIStream2EndpointID(ar,WMI_BEST_EFFORT_PRI) != 0);
1362         A_ASSERT(arWMIStream2EndpointID(ar,WMI_LOW_PRI) != 0);
1363         A_ASSERT(arWMIStream2EndpointID(ar,WMI_HIGH_PRI) != 0);
1364         A_ASSERT(arWMIStream2EndpointID(ar,WMI_HIGHEST_PRI) != 0);
1365     } while (FALSE);
1366
1367     if (A_FAILED(status)) {
1368         return (-EIO);
1369     }
1370
1371     /*
1372      * give our connected endpoints some buffers
1373      */
1374     ar6000_rx_refill(ar, arWMIStream2EndpointID(ar,WMI_CONTROL_PRI));
1375
1376     ar6000_rx_refill(ar, arWMIStream2EndpointID(ar,WMI_BEST_EFFORT_PRI));
1377
1378     /*
1379      * We will post the receive buffers only for SPE testing and so we are
1380      * making it conditional on the 'bypasswmi' flag.
1381      */
1382     if (bypasswmi) {
1383         ar6000_rx_refill(ar,arWMIStream2EndpointID(ar,WMI_LOW_PRI));
1384         ar6000_rx_refill(ar,arWMIStream2EndpointID(ar,WMI_HIGH_PRI));
1385     }
1386
1387         /* setup credit distribution */
1388     ar6000_setup_credit_dist(ar->arHtcTarget, &ar->arCreditStateInfo);
1389
1390     /* Since cookies are used for HTC transports, they should be */
1391     /* initialized prior to enabling HTC.                        */
1392     ar6000_cookie_init(ar);
1393
1394     /* start HTC */
1395     status = HTCStart(ar->arHtcTarget);
1396
1397     if (status != A_OK) {
1398         if (ar->arWmiEnabled == TRUE) {
1399             wmi_shutdown(ar->arWmi);
1400             ar->arWmiEnabled = FALSE;
1401             ar->arWmi = NULL;
1402         }
1403         ar6000_cookie_cleanup(ar);
1404         return -EIO;
1405     }
1406
1407     if (!bypasswmi) {
1408         /* Wait for Wmi event to be ready */
1409         timeleft = wait_event_interruptible_timeout(arEvent,
1410             (ar->arWmiReady == TRUE), wmitimeout * HZ);
1411
1412         if(!timeleft || signal_pending(current))
1413         {
1414             AR_DEBUG_PRINTF("WMI is not ready or wait was interrupted\n");
1415 #if defined(DWSIM) /* TBDXXX */
1416             AR_DEBUG_PRINTF(".....but proceed anyway.\n");
1417 #else
1418             return -EIO;
1419 #endif
1420         }
1421
1422         AR_DEBUG_PRINTF("%s() WMI is ready\n", __func__);
1423
1424         /* Communicate the wmi protocol verision to the target */
1425         if ((ar6000_set_host_app_area(ar)) != A_OK) {
1426             AR_DEBUG_PRINTF("Unable to set the host app area\n");
1427         }
1428     }
1429
1430     ar->arNumDataEndPts = 1;
1431
1432     return(0);
1433 }
1434
1435
1436 void
1437 ar6000_bitrate_rx(void *devt, A_INT32 rateKbps)
1438 {
1439     AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
1440
1441     ar->arBitRate = rateKbps;
1442     wake_up(&arEvent);
1443 }
1444
1445 void
1446 ar6000_ratemask_rx(void *devt, A_UINT16 ratemask)
1447 {
1448     AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
1449
1450     ar->arRateMask = ratemask;
1451     wake_up(&arEvent);
1452 }
1453
1454 void
1455 ar6000_txPwr_rx(void *devt, A_UINT8 txPwr)
1456 {
1457     AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
1458
1459     ar->arTxPwr = txPwr;
1460     wake_up(&arEvent);
1461 }
1462
1463
1464 void
1465 ar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList)
1466 {
1467     AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
1468
1469     A_MEMCPY(ar->arChannelList, chanList, numChan * sizeof (A_UINT16));
1470     ar->arNumChannels = numChan;
1471
1472     wake_up(&arEvent);
1473 }
1474
1475 A_UINT8
1476 ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, A_UINT32 * mapNo)
1477 {
1478     AR_SOFTC_T      *ar = (AR_SOFTC_T *)netdev_priv(dev);
1479     A_UINT8         *datap;
1480     ATH_MAC_HDR     *macHdr;
1481     A_UINT32         i, eptMap;
1482
1483     (*mapNo) = 0;
1484     datap = A_NETBUF_DATA(skb);
1485     macHdr = (ATH_MAC_HDR *)(datap + sizeof(WMI_DATA_HDR));
1486     if (IEEE80211_IS_MULTICAST(macHdr->dstMac)) {
1487         return ENDPOINT_2;
1488     }
1489
1490     eptMap = -1;
1491     for (i = 0; i < ar->arNodeNum; i ++) {
1492         if (IEEE80211_ADDR_EQ(macHdr->dstMac, ar->arNodeMap[i].macAddress)) {
1493             (*mapNo) = i + 1;
1494             ar->arNodeMap[i].txPending ++;
1495             return ar->arNodeMap[i].epId;
1496         }
1497
1498         if ((eptMap == -1) && !ar->arNodeMap[i].txPending) {
1499             eptMap = i;
1500         }
1501     }
1502
1503     if (eptMap == -1) {
1504         eptMap = ar->arNodeNum;
1505         ar->arNodeNum ++;
1506         A_ASSERT(ar->arNodeNum <= MAX_NODE_NUM);
1507     }
1508
1509     A_MEMCPY(ar->arNodeMap[eptMap].macAddress, macHdr->dstMac, IEEE80211_ADDR_LEN);
1510
1511     for (i = ENDPOINT_2; i <= ENDPOINT_5; i ++) {
1512         if (!ar->arTxPending[i]) {
1513             ar->arNodeMap[eptMap].epId = i;
1514             break;
1515         }
1516         // No free endpoint is available, start redistribution on the inuse endpoints.
1517         if (i == ENDPOINT_5) {
1518             ar->arNodeMap[eptMap].epId = ar->arNexEpId;
1519             ar->arNexEpId ++;
1520             if (ar->arNexEpId > ENDPOINT_5) {
1521                 ar->arNexEpId = ENDPOINT_2;
1522             }
1523         }
1524     }
1525
1526     (*mapNo) = eptMap + 1;
1527     ar->arNodeMap[eptMap].txPending ++;
1528
1529     return ar->arNodeMap[eptMap].epId;
1530 }
1531
1532 #ifdef DEBUG
1533 static void ar6000_dump_skb(struct sk_buff *skb)
1534 {
1535    u_char *ch;
1536    for (ch = A_NETBUF_DATA(skb);
1537         (A_UINT32)ch < ((A_UINT32)A_NETBUF_DATA(skb) +
1538         A_NETBUF_LEN(skb)); ch++)
1539     {
1540          AR_DEBUG_PRINTF("%2.2x ", *ch);
1541     }
1542     AR_DEBUG_PRINTF("\n");
1543 }
1544 #endif
1545
1546 static int
1547 ar6000_data_tx(struct sk_buff *skb, struct net_device *dev)
1548 {
1549     AR_SOFTC_T        *ar = (AR_SOFTC_T *)netdev_priv(dev);
1550     WMI_PRI_STREAM_ID streamID = WMI_NOT_MAPPED;
1551     A_UINT32          mapNo = 0;
1552     int               len;
1553     struct ar_cookie *cookie;
1554     A_BOOL            checkAdHocPsMapping = FALSE;
1555
1556 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
1557     skb->list = NULL;
1558 #endif
1559
1560     AR_DEBUG2_PRINTF("ar6000_data_tx start - skb=0x%x, data=0x%x, len=0x%x\n",
1561                      (A_UINT32)skb, (A_UINT32)A_NETBUF_DATA(skb),
1562                      A_NETBUF_LEN(skb));
1563 #ifdef CONFIG_HOST_TCMD_SUPPORT
1564      /* TCMD doesnt support any data, free the buf and return */
1565     if(ar->arTargetMode == AR6000_TCMD_MODE) {
1566         A_NETBUF_FREE(skb);
1567         return 0;
1568     }
1569 #endif
1570     do {
1571
1572         if (ar->arWmiReady == FALSE && bypasswmi == 0) {
1573             break;
1574         }
1575
1576 #ifdef BLOCK_TX_PATH_FLAG
1577         if (blocktx) {
1578             break;
1579         }
1580 #endif /* BLOCK_TX_PATH_FLAG */
1581
1582         if (ar->arWmiEnabled) {
1583             if (A_NETBUF_HEADROOM(skb) < dev->hard_header_len) {
1584                 struct sk_buff  *newbuf;
1585                 /*
1586                  * We really should have gotten enough headroom but sometimes
1587                  * we still get packets with not enough headroom.  Copy the packet.
1588                  */
1589                 len = A_NETBUF_LEN(skb);
1590                 newbuf = A_NETBUF_ALLOC(len);
1591                 if (newbuf == NULL) {
1592                     break;
1593                 }
1594                 A_NETBUF_PUT(newbuf, len);
1595                 A_MEMCPY(A_NETBUF_DATA(newbuf), A_NETBUF_DATA(skb), len);
1596                 A_NETBUF_FREE(skb);
1597                 skb = newbuf;
1598                 /* fall through and assemble header */
1599             }
1600
1601             if (wmi_dix_2_dot3(ar->arWmi, skb) != A_OK) {
1602                 AR_DEBUG_PRINTF("ar6000_data_tx - wmi_dix_2_dot3 failed\n");
1603                 break;
1604             }
1605
1606             if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE) != A_OK) {
1607                 AR_DEBUG_PRINTF("ar6000_data_tx - wmi_data_hdr_add failed\n");
1608                 break;
1609             }
1610
1611             if ((ar->arNetworkType == ADHOC_NETWORK) &&
1612                 ar->arIbssPsEnable && ar->arConnected) {
1613                     /* flag to check adhoc mapping once we take the lock below: */
1614                 checkAdHocPsMapping = TRUE;
1615
1616             } else {
1617                     /* get the stream mapping */
1618                 if (ar->arWmmEnabled) {
1619                     streamID = wmi_get_stream_id(ar->arWmi,
1620                                     wmi_implicit_create_pstream(ar->arWmi, skb, UPLINK_TRAFFIC, UNDEFINED_PRI));
1621                 } else {
1622                     streamID = WMI_BEST_EFFORT_PRI;
1623                 }
1624             }
1625
1626         } else {
1627             struct iphdr    *ipHdr;
1628             /*
1629              * the endpoint is directly based on the TOS field in the IP
1630              * header **** only for testing ******
1631              */
1632             ipHdr = A_NETBUF_DATA(skb) + sizeof(ATH_MAC_HDR);
1633                 /* here we map the TOS field to an endpoint number, this is for
1634                  * the endpointping test application */
1635             streamID = IP_TOS_TO_WMI_PRI(ipHdr->tos);
1636         }
1637
1638     } while (FALSE);
1639
1640         /* did we succeed ? */
1641     if ((streamID == WMI_NOT_MAPPED) && !checkAdHocPsMapping) {
1642             /* cleanup and exit */
1643         A_NETBUF_FREE(skb);
1644         AR6000_STAT_INC(ar, tx_dropped);
1645         AR6000_STAT_INC(ar, tx_aborted_errors);
1646         return 0;
1647     }
1648
1649     cookie = NULL;
1650
1651         /* take the lock to protect driver data */
1652     AR6000_SPIN_LOCK(&ar->arLock, 0);
1653
1654     do {
1655
1656         if (checkAdHocPsMapping) {
1657             streamID = ar6000_ibss_map_epid(skb, dev, &mapNo);
1658         }
1659
1660         A_ASSERT(streamID != WMI_NOT_MAPPED);
1661
1662             /* validate that the endpoint is connected */
1663         if (arWMIStream2EndpointID(ar,streamID) == 0) {
1664             AR_DEBUG_PRINTF("Stream %d is NOT mapped!\n",streamID);
1665             break;
1666         }
1667             /* allocate resource for this packet */
1668         cookie = ar6000_alloc_cookie(ar);
1669
1670         if (cookie != NULL) {
1671                 /* update counts while the lock is held */
1672             ar->arTxPending[streamID]++;
1673             ar->arTotalTxDataPending++;
1674         }
1675
1676     } while (FALSE);
1677
1678     AR6000_SPIN_UNLOCK(&ar->arLock, 0);
1679
1680     if (cookie != NULL) {
1681         cookie->arc_bp[0] = (A_UINT32)skb;
1682         cookie->arc_bp[1] = mapNo;
1683         SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
1684                                cookie,
1685                                A_NETBUF_DATA(skb),
1686                                A_NETBUF_LEN(skb),
1687                                arWMIStream2EndpointID(ar,streamID),
1688                                AR6K_DATA_PKT_TAG);
1689
1690 #ifdef DEBUG
1691         if (debugdriver >= 3) {
1692             ar6000_dump_skb(skb);
1693         }
1694 #endif
1695             /* HTC interface is asynchronous, if this fails, cleanup will happen in
1696              * the ar6000_tx_complete callback */
1697         HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
1698     } else {
1699             /* no packet to send, cleanup */
1700         A_NETBUF_FREE(skb);
1701         AR6000_STAT_INC(ar, tx_dropped);
1702         AR6000_STAT_INC(ar, tx_aborted_errors);
1703     }
1704
1705     return 0;
1706 }
1707
1708 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1709 static void
1710 tvsub(register struct timeval *out, register struct timeval *in)
1711 {
1712     if((out->tv_usec -= in->tv_usec) < 0) {
1713         out->tv_sec--;
1714         out->tv_usec += 1000000;
1715     }
1716     out->tv_sec -= in->tv_sec;
1717 }
1718
1719 void
1720 applyAPTCHeuristics(AR_SOFTC_T *ar)
1721 {
1722     A_UINT32 duration;
1723     A_UINT32 numbytes;
1724     A_UINT32 throughput;
1725     struct timeval ts;
1726     A_STATUS status;
1727
1728     AR6000_SPIN_LOCK(&ar->arLock, 0);
1729
1730     if ((enableAPTCHeuristics) && (!aptcTR.timerScheduled)) {
1731         do_gettimeofday(&ts);
1732         tvsub(&ts, &aptcTR.samplingTS);
1733         duration = ts.tv_sec * 1000 + ts.tv_usec / 1000; /* ms */
1734         numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
1735
1736         if (duration > APTC_TRAFFIC_SAMPLING_INTERVAL) {
1737             /* Initialize the time stamp and byte count */
1738             aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
1739             do_gettimeofday(&aptcTR.samplingTS);
1740
1741             /* Calculate and decide based on throughput thresholds */
1742             throughput = ((numbytes * 8) / duration);
1743             if (throughput > APTC_UPPER_THROUGHPUT_THRESHOLD) {
1744                 /* Disable Sleep and schedule a timer */
1745                 A_ASSERT(ar->arWmiReady == TRUE);
1746                 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
1747                 status = wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER);
1748                 AR6000_SPIN_LOCK(&ar->arLock, 0);
1749                 A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
1750                 aptcTR.timerScheduled = TRUE;
1751             }
1752         }
1753     }
1754
1755     AR6000_SPIN_UNLOCK(&ar->arLock, 0);
1756 }
1757 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1758
1759 static void
1760 ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint)
1761 {
1762     AR_SOFTC_T *ar = (AR_SOFTC_T *) Context;
1763
1764     if (Endpoint == arWMIStream2EndpointID(ar,WMI_CONTROL_PRI)) {
1765         if (!bypasswmi) {
1766                 /* under normal WMI if this is getting full, then something is running rampant
1767                  * the host should not be exhausting the WMI queue with too many commands
1768                  * the only exception to this is during testing using endpointping */
1769
1770             AR6000_SPIN_LOCK(&ar->arLock, 0);
1771                 /* set flag to handle subsequent messages */
1772             ar->arWMIControlEpFull = TRUE;
1773             AR6000_SPIN_UNLOCK(&ar->arLock, 0);
1774             AR_DEBUG_PRINTF("WMI Control Endpoint is FULL!!! \n");
1775         }
1776     } else {
1777         /* one of the data endpoints queues is getting full..need to stop network stack
1778          * the queue will resume after credits received */
1779         netif_stop_queue(ar->arNetDev);
1780     }
1781 }
1782
1783 static void
1784 ar6000_tx_queue_avail(void *Context, HTC_ENDPOINT_ID Endpoint)
1785 {
1786     AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
1787
1788     if (Endpoint == arWMIStream2EndpointID(ar,WMI_CONTROL_PRI)) {
1789         /* FIXME: what do for it?  */
1790     } else {
1791         /* Wake up interface, rescheduling prevented.  */
1792         if (ar->arConnected == TRUE || bypasswmi)
1793             netif_wake_queue(ar->arNetDev);
1794     }
1795 }
1796
1797 static void
1798 ar6000_tx_complete(void *Context, HTC_PACKET *pPacket)
1799 {
1800     AR_SOFTC_T     *ar = (AR_SOFTC_T *)Context;
1801     void           *cookie = (void *)pPacket->pPktContext;
1802     struct sk_buff *skb = NULL;
1803     A_UINT32        mapNo = 0;
1804     A_STATUS        status;
1805     struct ar_cookie * ar_cookie;
1806     WMI_PRI_STREAM_ID streamID;
1807     A_BOOL          wakeEvent = FALSE;
1808
1809     status = pPacket->Status;
1810     ar_cookie = (struct ar_cookie *)cookie;
1811     skb = (struct sk_buff *)ar_cookie->arc_bp[0];
1812     streamID = arEndpoint2WMIStreamID(ar,pPacket->Endpoint);
1813     mapNo = ar_cookie->arc_bp[1];
1814
1815     A_ASSERT(skb);
1816     A_ASSERT(pPacket->pBuffer == A_NETBUF_DATA(skb));
1817
1818     if (A_SUCCESS(status)) {
1819         A_ASSERT(pPacket->ActualLength == A_NETBUF_LEN(skb));
1820     }
1821
1822     AR_DEBUG2_PRINTF("ar6000_tx_complete skb=0x%x data=0x%x len=0x%x sid=%d ",
1823                      (A_UINT32)skb, (A_UINT32)pPacket->pBuffer,
1824                      pPacket->ActualLength,
1825                      streamID);
1826
1827         /* lock the driver as we update internal state */
1828     AR6000_SPIN_LOCK(&ar->arLock, 0);
1829
1830     ar->arTxPending[streamID]--;
1831
1832     if ((streamID != WMI_CONTROL_PRI) || bypasswmi) {
1833         ar->arTotalTxDataPending--;
1834     }
1835
1836     if (streamID == WMI_CONTROL_PRI)
1837     {
1838         if (ar->arWMIControlEpFull) {
1839                 /* since this packet completed, the WMI EP is no longer full */
1840             ar->arWMIControlEpFull = FALSE;
1841         }
1842
1843         if (ar->arTxPending[streamID] == 0) {
1844             wakeEvent = TRUE;
1845         }
1846     }
1847
1848     if (A_FAILED(status)) {
1849         AR_DEBUG_PRINTF("%s() -TX ERROR, status: 0x%x\n", __func__,
1850                         status);
1851         AR6000_STAT_INC(ar, tx_errors);
1852     } else {
1853         AR_DEBUG2_PRINTF("OK\n");
1854         AR6000_STAT_INC(ar, tx_packets);
1855         ar->arNetStats.tx_bytes += A_NETBUF_LEN(skb);
1856 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1857         aptcTR.bytesTransmitted += a_netbuf_to_len(skb);
1858         applyAPTCHeuristics(ar);
1859 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1860     }
1861
1862     // TODO this needs to be looked at
1863     if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable
1864         && (streamID != WMI_CONTROL_PRI) && mapNo)
1865     {
1866         mapNo --;
1867         ar->arNodeMap[mapNo].txPending --;
1868
1869         if (!ar->arNodeMap[mapNo].txPending && (mapNo == (ar->arNodeNum - 1))) {
1870             A_UINT32 i;
1871             for (i = ar->arNodeNum; i > 0; i --) {
1872                 if (!ar->arNodeMap[i - 1].txPending) {
1873                     A_MEMZERO(&ar->arNodeMap[i - 1], sizeof(struct ar_node_mapping));
1874                     ar->arNodeNum --;
1875                 } else {
1876                     break;
1877                 }
1878             }
1879         }
1880     }
1881
1882     /* Freeing a cookie should not be contingent on either of */
1883     /* these flags, just if we have a cookie or not.           */
1884     /* Can we even get here without a cookie? Fix later.       */
1885     if (ar->arWmiReady == TRUE || (bypasswmi))
1886     {
1887         ar6000_free_cookie(ar, cookie);
1888     }
1889
1890     AR6000_SPIN_UNLOCK(&ar->arLock, 0);
1891
1892     /* lock is released, we can freely call other kernel APIs */
1893
1894         /* this indirectly frees the HTC_PACKET */
1895     A_NETBUF_FREE(skb);
1896
1897     if (wakeEvent) {
1898         wake_up(&arEvent);
1899     }
1900 }
1901
1902 /*
1903  * Receive event handler.  This is called by HTC when a packet is received
1904  */
1905 int pktcount;
1906 static void
1907 ar6000_rx(void *Context, HTC_PACKET *pPacket)
1908 {
1909     AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
1910     struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext;
1911     int minHdrLen;
1912     A_STATUS        status = pPacket->Status;
1913     WMI_PRI_STREAM_ID streamID = arEndpoint2WMIStreamID(ar,pPacket->Endpoint);
1914     HTC_ENDPOINT_ID   ept = pPacket->Endpoint;
1915
1916     A_ASSERT((status != A_OK) || (pPacket->pBuffer == (A_NETBUF_DATA(skb) + HTC_HEADER_LEN)));
1917
1918     AR_DEBUG2_PRINTF("ar6000_rx ar=0x%x sid=%d, skb=0x%x, data=0x%x, len=0x%x ",
1919                     (A_UINT32)ar, streamID, (A_UINT32)skb, (A_UINT32)pPacket->pBuffer,
1920                     pPacket->ActualLength);
1921     if (status != A_OK) {
1922         AR_DEBUG2_PRINTF("ERR\n");
1923     } else {
1924         AR_DEBUG2_PRINTF("OK\n");
1925     }
1926
1927         /* take lock to protect buffer counts
1928          * and adaptive power throughput state */
1929     AR6000_SPIN_LOCK(&ar->arLock, 0);
1930
1931     ar->arRxBuffers[streamID]--;
1932
1933     if (A_SUCCESS(status)) {
1934         AR6000_STAT_INC(ar, rx_packets);
1935         ar->arNetStats.rx_bytes += pPacket->ActualLength;
1936 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1937         aptcTR.bytesReceived += a_netbuf_to_len(skb);
1938         applyAPTCHeuristics(ar);
1939 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1940
1941         A_NETBUF_PUT(skb, pPacket->ActualLength +  HTC_HEADER_LEN);
1942         A_NETBUF_PULL(skb, HTC_HEADER_LEN);
1943
1944 #ifdef DEBUG
1945         if (debugdriver >= 2) {
1946             ar6000_dump_skb(skb);
1947         }
1948 #endif /* DEBUG */
1949     }
1950
1951     AR6000_SPIN_UNLOCK(&ar->arLock, 0);
1952
1953     if (status != A_OK) {
1954         AR6000_STAT_INC(ar, rx_errors);
1955         A_NETBUF_FREE(skb);
1956     } else if (ar->arWmiEnabled == TRUE) {
1957         if (streamID == WMI_CONTROL_PRI) {
1958            /*
1959             * this is a wmi control msg
1960             */
1961             wmi_control_rx(ar->arWmi, skb);
1962         } else {
1963             WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb);
1964             if (WMI_DATA_HDR_IS_MSG_TYPE(dhdr, CNTL_MSGTYPE)) {
1965                 /*
1966                  * this is a wmi control msg
1967                  */
1968                 /* strip off WMI hdr */
1969                 wmi_data_hdr_remove(ar->arWmi, skb);
1970                 wmi_control_rx(ar->arWmi, skb);
1971             } else {
1972                 /*
1973                  * this is a wmi data packet
1974                  */
1975                 minHdrLen = sizeof (WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) +
1976                             sizeof(ATH_LLC_SNAP_HDR);
1977
1978                 if ((pPacket->ActualLength < minHdrLen) ||
1979                     (pPacket->ActualLength > AR6000_BUFFER_SIZE))
1980                 {
1981                     /*
1982                      * packet is too short or too long
1983                      */
1984                     AR_DEBUG_PRINTF("TOO SHORT or TOO LONG\n");
1985                     AR6000_STAT_INC(ar, rx_errors);
1986                     AR6000_STAT_INC(ar, rx_length_errors);
1987                     A_NETBUF_FREE(skb);
1988                 } else {
1989                     if (ar->arWmmEnabled) {
1990                         wmi_implicit_create_pstream(ar->arWmi, skb,
1991                             DNLINK_TRAFFIC, UNDEFINED_PRI);
1992                     }
1993 #if 0
1994                     /* Access RSSI values here */
1995                     AR_DEBUG_PRINTF("RSSI %d\n",
1996                         ((WMI_DATA_HDR *) A_NETBUF_DATA(skb))->rssi);
1997 #endif
1998                     wmi_data_hdr_remove(ar->arWmi, skb);
1999                     wmi_dot3_2_dix(ar->arWmi, skb);
2000
2001 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
2002                     /*
2003                      * extra push and memcpy, for eth_type_trans() of 2.4 kernel
2004                      * will pull out hard_header_len bytes of the skb.
2005                      */
2006                     A_NETBUF_PUSH(skb, sizeof(WMI_DATA_HDR) + sizeof(ATH_LLC_SNAP_HDR) + HTC_HEADER_LEN);
2007                     A_MEMCPY(A_NETBUF_DATA(skb), A_NETBUF_DATA(skb) + sizeof(WMI_DATA_HDR) +
2008                              sizeof(ATH_LLC_SNAP_HDR) + HTC_HEADER_LEN, sizeof(ATH_MAC_HDR));
2009 #endif
2010                     if ((ar->arNetDev->flags & IFF_UP) == IFF_UP)
2011                     {
2012                         skb->dev = ar->arNetDev;
2013                         skb->protocol = eth_type_trans(skb, ar->arNetDev);
2014                         netif_rx(skb);
2015                     }
2016                     else
2017                     {
2018                         A_NETBUF_FREE(skb);
2019                     }
2020                 }
2021             }
2022         }
2023     } else {
2024         if ((ar->arNetDev->flags & IFF_UP) == IFF_UP)
2025         {
2026             skb->dev = ar->arNetDev;
2027             skb->protocol = eth_type_trans(skb, ar->arNetDev);
2028             netif_rx(skb);
2029         }
2030         else
2031         {
2032             A_NETBUF_FREE(skb);
2033         }
2034     }
2035
2036     if (status != A_ECANCELED) {
2037         /*
2038          * HTC provides A_ECANCELED status when it doesn't want to be refilled
2039          * (probably due to a shutdown)
2040          */
2041         ar6000_rx_refill(Context, ept);
2042     }
2043
2044
2045 }
2046
2047 static void
2048 ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint)
2049 {
2050     AR_SOFTC_T  *ar = (AR_SOFTC_T *)Context;
2051     void        *osBuf;
2052     int         RxBuffers;
2053     int         buffersToRefill;
2054     HTC_PACKET  *pPacket;
2055     WMI_PRI_STREAM_ID streamId = arEndpoint2WMIStreamID(ar,Endpoint);
2056
2057     buffersToRefill = (int)AR6000_MAX_RX_BUFFERS -
2058                                     (int)ar->arRxBuffers[streamId];
2059
2060     if (buffersToRefill <= 0) {
2061             /* fast return, nothing to fill */
2062         return;
2063     }
2064
2065     AR_DEBUG2_PRINTF("ar6000_rx_refill: providing htc with %d buffers at eid=%d\n",
2066                     buffersToRefill, Endpoint);
2067
2068     for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) {
2069         osBuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE);
2070         if (NULL == osBuf) {
2071             break;
2072         }
2073             /* the HTC packet wrapper is at the head of the reserved area
2074              * in the skb */
2075         pPacket = (HTC_PACKET *)(A_NETBUF_HEAD(osBuf));
2076             /* set re-fill info */
2077         SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_BUFFER_SIZE,Endpoint);
2078             /* add this packet */
2079         HTCAddReceivePkt(ar->arHtcTarget, pPacket);
2080     }
2081
2082         /* update count */
2083     AR6000_SPIN_LOCK(&ar->arLock, 0);
2084     ar->arRxBuffers[streamId] += RxBuffers;
2085     AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2086 }
2087
2088 static struct net_device_stats *
2089 ar6000_get_stats(struct net_device *dev)
2090 {
2091     AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev);
2092     return &ar->arNetStats;
2093 }
2094
2095 static struct iw_statistics *
2096 ar6000_get_iwstats(struct net_device * dev)
2097 {
2098     AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev);
2099     TARGET_STATS *pStats = &ar->arTargetStats;
2100     struct iw_statistics * pIwStats = &ar->arIwStats;
2101
2102     if ((ar->arWmiReady == FALSE)
2103     /*
2104      * The in_atomic function is used to determine if the scheduling is
2105      * allowed in the current context or not. This was introduced in 2.6
2106      * From what I have read on the differences between 2.4 and 2.6, the
2107      * 2.4 kernel did not support preemption and so this check might not
2108      * be required for 2.4 kernels.
2109      */
2110 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
2111         || (in_atomic())
2112 #endif
2113        )
2114     {
2115         pIwStats->status = 0;
2116         pIwStats->qual.qual = 0;
2117         pIwStats->qual.level =0;
2118         pIwStats->qual.noise = 0;
2119         pIwStats->discard.code =0;
2120         pIwStats->discard.retries=0;
2121         pIwStats->miss.beacon =0;
2122         return pIwStats;
2123     }
2124     if (down_interruptible(&ar->arSem)) {
2125         pIwStats->status = 0;
2126         return pIwStats;
2127     }
2128
2129
2130     ar->statsUpdatePending = TRUE;
2131
2132     if(wmi_get_stats_cmd(ar->arWmi) != A_OK) {
2133         up(&ar->arSem);
2134         pIwStats->status = 0;
2135         return pIwStats;
2136     }
2137
2138     wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ);
2139
2140     if (signal_pending(current)) {
2141         AR_DEBUG_PRINTF("ar6000 : WMI get stats timeout \n");
2142         up(&ar->arSem);
2143         pIwStats->status = 0;
2144         return pIwStats;
2145     }
2146     pIwStats->status = 1 ;
2147     pIwStats->qual.qual = pStats->cs_aveBeacon_rssi;
2148     pIwStats->qual.level =pStats->cs_aveBeacon_rssi + 161;  /* noise is -95 dBm */
2149     pIwStats->qual.noise = pStats->noise_floor_calibation;
2150     pIwStats->discard.code = pStats->rx_decrypt_err;
2151     pIwStats->discard.retries = pStats->tx_retry_cnt;
2152     pIwStats->miss.beacon = pStats->cs_bmiss_cnt;
2153     up(&ar->arSem);
2154     return pIwStats;
2155 }
2156
2157 void
2158 ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap)
2159 {
2160     AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
2161     struct net_device *dev = ar->arNetDev;
2162
2163     ar->arWmiReady = TRUE;
2164     wake_up(&arEvent);
2165     A_MEMCPY(dev->dev_addr, datap, AR6000_ETH_ADDR_LEN);
2166     AR_DEBUG_PRINTF("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
2167         dev->dev_addr[0], dev->dev_addr[1],
2168         dev->dev_addr[2], dev->dev_addr[3],
2169         dev->dev_addr[4], dev->dev_addr[5]);
2170
2171     ar->arPhyCapability = phyCap;
2172 }
2173
2174 A_UINT8
2175 ar6000_iptos_to_userPriority(A_UINT8 *pkt)
2176 {
2177     struct iphdr *ipHdr = (struct iphdr *)pkt;
2178     A_UINT8 userPriority;
2179
2180     /*
2181      * IP Tos format :
2182      *      (Refer Pg 57 WMM-test-plan-v1.2)
2183      * IP-TOS - 8bits
2184      *          : DSCP(6-bits) ECN(2-bits)
2185      *          : DSCP - P2 P1 P0 X X X
2186      *              where (P2 P1 P0) form 802.1D
2187      */
2188     userPriority = ipHdr->tos >> 5;
2189     return (userPriority & 0x7);
2190 }
2191
2192 void
2193 ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_UINT8 *bssid,
2194                      A_UINT16 listenInterval, A_UINT16 beaconInterval,
2195                      NETWORK_TYPE networkType, A_UINT8 beaconIeLen,
2196                      A_UINT8 assocReqLen, A_UINT8 assocRespLen,
2197                      A_UINT8 *assocInfo)
2198 {
2199     union iwreq_data wrqu;
2200     int i, beacon_ie_pos, assoc_resp_ie_pos, assoc_req_ie_pos;
2201     static const char *tag1 = "ASSOCINFO(ReqIEs=";
2202     static const char *tag2 = "ASSOCRESPIE=";
2203     static const char *beaconIetag = "BEACONIE=";
2204     char buf[WMI_CONTROL_MSG_MAX_LEN * 2 + sizeof(tag1)];
2205     char *pos;
2206     A_UINT8 key_op_ctrl;
2207
2208     A_MEMCPY(ar->arBssid, bssid, sizeof(ar->arBssid));
2209     ar->arBssChannel = channel;
2210
2211     A_PRINTF("AR6000 connected event on freq %d ", channel);
2212     A_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
2213             " listenInterval=%d, beaconInterval = %d, beaconIeLen = %d assocReqLen=%d"
2214             " assocRespLen =%d\n",
2215              bssid[0], bssid[1], bssid[2],
2216              bssid[3], bssid[4], bssid[5],
2217              listenInterval, beaconInterval,
2218              beaconIeLen, assocReqLen, assocRespLen);
2219     if (networkType & ADHOC_NETWORK) {
2220         if (networkType & ADHOC_CREATOR) {
2221             A_PRINTF("Network: Adhoc (Creator)\n");
2222         } else {
2223             A_PRINTF("Network: Adhoc (Joiner)\n");
2224         }
2225     } else {
2226         A_PRINTF("Network: Infrastructure\n");
2227     }
2228
2229     if (beaconIeLen && (sizeof(buf) > (9 + beaconIeLen * 2))) {
2230         AR_DEBUG_PRINTF("\nBeaconIEs= ");
2231
2232         beacon_ie_pos = 0;
2233         A_MEMZERO(buf, sizeof(buf));
2234         sprintf(buf, "%s", beaconIetag);
2235         pos = buf + 9;
2236         for (i = beacon_ie_pos; i < beacon_ie_pos + beaconIeLen; i++) {
2237             AR_DEBUG_PRINTF("%2.2x ", assocInfo[i]);
2238             sprintf(pos, "%2.2x", assocInfo[i]);
2239             pos += 2;
2240         }
2241         AR_DEBUG_PRINTF("\n");
2242
2243         A_MEMZERO(&wrqu, sizeof(wrqu));
2244         wrqu.data.length = strlen(buf);
2245         wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
2246     }
2247
2248     if (assocRespLen && (sizeof(buf) > (12 + (assocRespLen * 2))))
2249     {
2250         assoc_resp_ie_pos = beaconIeLen + assocReqLen +
2251                             sizeof(A_UINT16)  +  /* capinfo*/
2252                             sizeof(A_UINT16)  +  /* status Code */
2253                             sizeof(A_UINT16)  ;  /* associd */
2254         A_MEMZERO(buf, sizeof(buf));
2255         sprintf(buf, "%s", tag2);
2256         pos = buf + 12;
2257         AR_DEBUG_PRINTF("\nAssocRespIEs= ");
2258         /*
2259          * The Association Response Frame w.o. the WLAN header is delivered to
2260          * the host, so skip over to the IEs
2261          */
2262         for (i = assoc_resp_ie_pos; i < assoc_resp_ie_pos + assocRespLen - 6; i++)
2263         {
2264             AR_DEBUG_PRINTF("%2.2x ", assocInfo[i]);
2265             sprintf(pos, "%2.2x", assocInfo[i]);
2266             pos += 2;
2267         }
2268         AR_DEBUG_PRINTF("\n");
2269
2270         A_MEMZERO(&wrqu, sizeof(wrqu));
2271         wrqu.data.length = strlen(buf);
2272         wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
2273     }
2274
2275     if (assocReqLen && (sizeof(buf) > (17 + (assocReqLen * 2)))) {
2276         /*
2277          * assoc Request includes capability and listen interval. Skip these.
2278          */
2279         assoc_req_ie_pos =  beaconIeLen +
2280                             sizeof(A_UINT16)  +  /* capinfo*/
2281                             sizeof(A_UINT16);    /* listen interval */
2282
2283         A_MEMZERO(buf, sizeof(buf));
2284         sprintf(buf, "%s", tag1);
2285         pos = buf + 17;
2286         AR_DEBUG_PRINTF("AssocReqIEs= ");
2287         for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen - 4; i++) {
2288             AR_DEBUG_PRINTF("%2.2x ", assocInfo[i]);
2289             sprintf(pos, "%2.2x", assocInfo[i]);
2290             pos += 2;;
2291         }
2292         AR_DEBUG_PRINTF("\n");
2293
2294         A_MEMZERO(&wrqu, sizeof(wrqu));
2295         wrqu.data.length = strlen(buf);
2296         wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
2297     }
2298
2299 #ifdef USER_KEYS
2300     if (ar->user_savedkeys_stat == USER_SAVEDKEYS_STAT_RUN &&
2301         ar->user_saved_keys.keyOk == TRUE)
2302     {
2303
2304         key_op_ctrl = KEY_OP_VALID_MASK & ~KEY_OP_INIT_TSC;
2305         if (ar->user_key_ctrl & AR6000_USER_SETKEYS_RSC_UNCHANGED) {
2306             key_op_ctrl &= ~KEY_OP_INIT_RSC;
2307         } else {
2308             key_op_ctrl |= KEY_OP_INIT_RSC;
2309         }
2310         ar6000_reinstall_keys(ar, key_op_ctrl);
2311     }
2312 #endif /* USER_KEYS */
2313
2314         /* flush data queues */
2315     ar6000_TxDataCleanup(ar);
2316
2317     netif_start_queue(ar->arNetDev);
2318
2319     if ((OPEN_AUTH == ar->arDot11AuthMode) &&
2320         (NONE_AUTH == ar->arAuthMode)      &&
2321         (WEP_CRYPT == ar->arPairwiseCrypto))
2322     {
2323         if (!ar->arConnected) {
2324             ar6000_install_static_wep_keys(ar);
2325         }
2326     }
2327
2328     ar->arConnected  = TRUE;
2329     ar->arConnectPending = FALSE;
2330
2331     reconnect_flag = 0;
2332
2333     A_MEMZERO(&wrqu, sizeof(wrqu));
2334     A_MEMCPY(wrqu.addr.sa_data, bssid, IEEE80211_ADDR_LEN);
2335     wrqu.addr.sa_family = ARPHRD_ETHER;
2336     wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
2337     if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable) {
2338         A_MEMZERO(ar->arNodeMap, sizeof(ar->arNodeMap));
2339         ar->arNodeNum = 0;
2340         ar->arNexEpId = ENDPOINT_2;
2341     }
2342
2343 }
2344
2345 void ar6000_set_numdataendpts(AR_SOFTC_T *ar, A_UINT32 num)
2346 {
2347     A_ASSERT(num <= (HTC_MAILBOX_NUM_MAX - 1));
2348     ar->arNumDataEndPts = num;
2349 }
2350
2351 void
2352 ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid,
2353                         A_UINT8 assocRespLen, A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus)
2354 {
2355     A_UINT8 i;
2356
2357     A_PRINTF("AR6000 disconnected");
2358     if (bssid[0] || bssid[1] || bssid[2] || bssid[3] || bssid[4] || bssid[5]) {
2359         A_PRINTF(" from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
2360                  bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
2361     }
2362     A_PRINTF("\n");
2363
2364     AR_DEBUG_PRINTF("\nDisconnect Reason is %d", reason);
2365     AR_DEBUG_PRINTF("\nProtocol Reason/Status Code is %d", protocolReasonStatus);
2366     AR_DEBUG_PRINTF("\nAssocResp Frame = %s",
2367                     assocRespLen ? " " : "NULL");
2368     for (i = 0; i < assocRespLen; i++) {
2369         if (!(i % 0x10)) {
2370             AR_DEBUG_PRINTF("\n");
2371         }
2372         AR_DEBUG_PRINTF("%2.2x ", assocInfo[i]);
2373     }
2374     AR_DEBUG_PRINTF("\n");
2375     /*
2376      * If the event is due to disconnect cmd from the host, only they the target
2377      * would stop trying to connect. Under any other condition, target would
2378      * keep trying to connect.
2379      *
2380      */
2381     if( reason == DISCONNECT_CMD)
2382     {
2383         ar->arConnectPending = FALSE;
2384     } else {
2385         ar->arConnectPending = TRUE;
2386         if (((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x11)) ||
2387             ((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x0) && (reconnect_flag == 1))) {
2388             ar->arConnected = TRUE;
2389             return;
2390         }
2391     }
2392     ar->arConnected = FALSE;
2393
2394     if( (reason != CSERV_DISCONNECT) || (reconnect_flag != 1) ) {
2395         reconnect_flag = 0;
2396     }
2397
2398 #ifdef USER_KEYS
2399     if (reason != CSERV_DISCONNECT)
2400     {
2401         ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
2402         ar->user_key_ctrl      = 0;
2403     }
2404 #endif /* USER_KEYS */
2405
2406     netif_stop_queue(ar->arNetDev);
2407     A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
2408     ar->arBssChannel = 0;
2409     ar->arBeaconInterval = 0;
2410
2411     ar6000_TxDataCleanup(ar);
2412 }
2413
2414 void
2415 ar6000_regDomain_event(AR_SOFTC_T *ar, A_UINT32 regCode)
2416 {
2417     A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode);
2418     ar->arRegCode = regCode;
2419 }
2420
2421 void
2422 ar6000_neighborReport_event(AR_SOFTC_T *ar, int numAps, WMI_NEIGHBOR_INFO *info)
2423 {
2424     static const char *tag = "PRE-AUTH";
2425     char buf[128];
2426     union iwreq_data wrqu;
2427     int i;
2428
2429     AR_DEBUG_PRINTF("AR6000 Neighbor Report Event\n");
2430     for (i=0; i < numAps; info++, i++) {
2431         AR_DEBUG_PRINTF("bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
2432             info->bssid[0], info->bssid[1], info->bssid[2],
2433             info->bssid[3], info->bssid[4], info->bssid[5]);
2434         if (info->bssFlags & WMI_PREAUTH_CAPABLE_BSS) {
2435             AR_DEBUG_PRINTF("preauth-cap");
2436         }
2437         if (info->bssFlags & WMI_PMKID_VALID_BSS) {
2438             AR_DEBUG_PRINTF(" pmkid-valid\n");
2439             continue;           /* we skip bss if the pmkid is already valid */
2440         }
2441         AR_DEBUG_PRINTF("\n");
2442         snprintf(buf, sizeof(buf), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
2443                  tag,
2444                  info->bssid[0], info->bssid[1], info->bssid[2],
2445                  info->bssid[3], info->bssid[4], info->bssid[5],
2446                  i, info->bssFlags);
2447         A_MEMZERO(&wrqu, sizeof(wrqu));
2448         wrqu.data.length = strlen(buf);
2449         wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
2450     }
2451 }
2452
2453 void
2454 ar6000_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast)
2455 {
2456     static const char *tag = "MLME-MICHAELMICFAILURE.indication";
2457     char buf[128];
2458     union iwreq_data wrqu;
2459
2460     A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n",
2461              keyid, ismcast ? "multi": "uni");
2462     snprintf(buf, sizeof(buf), "%s(keyid=%d %scat)", tag, keyid,
2463              ismcast ? "multi" : "uni");
2464     memset(&wrqu, 0, sizeof(wrqu));
2465     wrqu.data.length = strlen(buf);
2466     wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
2467 }
2468
2469 void
2470 ar6000_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status)
2471 {
2472         AR_DEBUG_PRINTF("AR6000 scan complete: %d\n", status);
2473
2474         ar->scan_complete = 1;
2475         wake_up_interruptible(&ar6000_scan_queue);
2476 }
2477
2478 void
2479 ar6000_targetStats_event(AR_SOFTC_T *ar,  WMI_TARGET_STATS *pTarget)
2480 {
2481     TARGET_STATS *pStats = &ar->arTargetStats;
2482     A_UINT8 ac;
2483
2484     /*A_PRINTF("AR6000 updating target stats\n");*/
2485     pStats->tx_packets          += pTarget->txrxStats.tx_stats.tx_packets;
2486     pStats->tx_bytes            += pTarget->txrxStats.tx_stats.tx_bytes;
2487     pStats->tx_unicast_pkts     += pTarget->txrxStats.tx_stats.tx_unicast_pkts;
2488     pStats->tx_unicast_bytes    += pTarget->txrxStats.tx_stats.tx_unicast_bytes;
2489     pStats->tx_multicast_pkts   += pTarget->txrxStats.tx_stats.tx_multicast_pkts;
2490     pStats->tx_multicast_bytes  += pTarget->txrxStats.tx_stats.tx_multicast_bytes;
2491     pStats->tx_broadcast_pkts   += pTarget->txrxStats.tx_stats.tx_broadcast_pkts;
2492     pStats->tx_broadcast_bytes  += pTarget->txrxStats.tx_stats.tx_broadcast_bytes;
2493     pStats->tx_rts_success_cnt  += pTarget->txrxStats.tx_stats.tx_rts_success_cnt;
2494     for(ac = 0; ac < WMM_NUM_AC; ac++)
2495         pStats->tx_packet_per_ac[ac] += pTarget->txrxStats.tx_stats.tx_packet_per_ac[ac];
2496     pStats->tx_errors           += pTarget->txrxStats.tx_stats.tx_errors;
2497     pStats->tx_failed_cnt       += pTarget->txrxStats.tx_stats.tx_failed_cnt;
2498     pStats->tx_retry_cnt        += pTarget->txrxStats.tx_stats.tx_retry_cnt;
2499     pStats->tx_rts_fail_cnt     += pTarget->txrxStats.tx_stats.tx_rts_fail_cnt;
2500     pStats->tx_unicast_rate      = wmi_get_rate(pTarget->txrxStats.tx_stats.tx_unicast_rate);
2501
2502     pStats->rx_packets          += pTarget->txrxStats.rx_stats.rx_packets;
2503     pStats->rx_bytes            += pTarget->txrxStats.rx_stats.rx_bytes;
2504     pStats->rx_unicast_pkts     += pTarget->txrxStats.rx_stats.rx_unicast_pkts;
2505     pStats->rx_unicast_bytes    += pTarget->txrxStats.rx_stats.rx_unicast_bytes;
2506     pStats->rx_multicast_pkts   += pTarget->txrxStats.rx_stats.rx_multicast_pkts;
2507     pStats->rx_multicast_bytes  += pTarget->txrxStats.rx_stats.rx_multicast_bytes;
2508     pStats->rx_broadcast_pkts   += pTarget->txrxStats.rx_stats.rx_broadcast_pkts;
2509     pStats->rx_broadcast_bytes  += pTarget->txrxStats.rx_stats.rx_broadcast_bytes;
2510     pStats->rx_fragment_pkt     += pTarget->txrxStats.rx_stats.rx_fragment_pkt;
2511     pStats->rx_errors           += pTarget->txrxStats.rx_stats.rx_errors;
2512     pStats->rx_crcerr           += pTarget->txrxStats.rx_stats.rx_crcerr;
2513     pStats->rx_key_cache_miss   += pTarget->txrxStats.rx_stats.rx_key_cache_miss;
2514     pStats->rx_decrypt_err      += pTarget->txrxStats.rx_stats.rx_decrypt_err;
2515     pStats->rx_duplicate_frames += pTarget->txrxStats.rx_stats.rx_duplicate_frames;
2516     pStats->rx_unicast_rate      = wmi_get_rate(pTarget->txrxStats.rx_stats.rx_unicast_rate);
2517
2518
2519     pStats->tkip_local_mic_failure
2520                                 += pTarget->txrxStats.tkipCcmpStats.tkip_local_mic_failure;
2521     pStats->tkip_counter_measures_invoked
2522                                 += pTarget->txrxStats.tkipCcmpStats.tkip_counter_measures_invoked;
2523     pStats->tkip_replays        += pTarget->txrxStats.tkipCcmpStats.tkip_replays;
2524     pStats->tkip_format_errors  += pTarget->txrxStats.tkipCcmpStats.tkip_format_errors;
2525     pStats->ccmp_format_errors  += pTarget->txrxStats.tkipCcmpStats.ccmp_format_errors;
2526     pStats->ccmp_replays        += pTarget->txrxStats.tkipCcmpStats.ccmp_replays;
2527
2528
2529     pStats->power_save_failure_cnt += pTarget->pmStats.power_save_failure_cnt;
2530     pStats->noise_floor_calibation = pTarget->noise_floor_calibation;
2531
2532     pStats->cs_bmiss_cnt        += pTarget->cservStats.cs_bmiss_cnt;
2533     pStats->cs_lowRssi_cnt      += pTarget->cservStats.cs_lowRssi_cnt;
2534     pStats->cs_connect_cnt      += pTarget->cservStats.cs_connect_cnt;
2535     pStats->cs_disconnect_cnt   += pTarget->cservStats.cs_disconnect_cnt;
2536     pStats->cs_aveBeacon_snr    = pTarget->cservStats.cs_aveBeacon_snr;
2537     pStats->cs_aveBeacon_rssi   = pTarget->cservStats.cs_aveBeacon_rssi;
2538     pStats->cs_lastRoam_msec    = pTarget->cservStats.cs_lastRoam_msec;
2539     pStats->cs_snr              = pTarget->cservStats.cs_snr;
2540     pStats->cs_rssi             = pTarget->cservStats.cs_rssi;
2541
2542     pStats->lq_val              = pTarget->lqVal;
2543
2544     pStats->wow_num_pkts_dropped += pTarget->wowStats.wow_num_pkts_dropped;
2545     pStats->wow_num_host_pkt_wakeups += pTarget->wowStats.wow_num_host_pkt_wakeups;
2546     pStats->wow_num_host_event_wakeups += pTarget->wowStats.wow_num_host_event_wakeups;
2547     pStats->wow_num_events_discarded += pTarget->wowStats.wow_num_events_discarded;
2548
2549     ar->statsUpdatePending = FALSE;
2550     wake_up(&arEvent);
2551 }
2552
2553 void
2554 ar6000_rssiThreshold_event(AR_SOFTC_T *ar,  WMI_RSSI_THRESHOLD_VAL newThreshold, A_INT16 rssi)
2555 {
2556     USER_RSSI_THOLD userRssiThold;
2557
2558     userRssiThold.tag = rssi_map[newThreshold].tag;
2559     userRssiThold.rssi = rssi;
2560     AR_DEBUG2_PRINTF("rssi Threshold range = %d tag = %d  rssi = %d\n", newThreshold, userRssiThold.tag, rssi);
2561 #ifdef SEND_EVENT_TO_APP
2562     ar6000_send_event_to_app(ar, WMI_RSSI_THRESHOLD_EVENTID,(A_UINT8 *)&userRssiThold, sizeof(USER_RSSI_THOLD));
2563 #endif
2564 }
2565
2566
2567 void
2568 ar6000_hbChallengeResp_event(AR_SOFTC_T *ar, A_UINT32 cookie, A_UINT32 source)
2569 {
2570     if (source == APP_HB_CHALLENGE) {
2571         /* Report it to the app in case it wants a positive acknowledgement */
2572 #ifdef SEND_EVENT_TO_APP
2573         ar6000_send_event_to_app(ar, WMIX_HB_CHALLENGE_RESP_EVENTID,
2574                                  (A_UINT8 *)&cookie, sizeof(cookie));
2575 #endif
2576     } else {
2577         /* This would ignore the replys that come in after their due time */
2578         if (cookie == ar->arHBChallengeResp.seqNum) {
2579             ar->arHBChallengeResp.outstanding = FALSE;
2580         }
2581     }
2582 }
2583
2584
2585 void
2586 ar6000_reportError_event(AR_SOFTC_T *ar, WMI_TARGET_ERROR_VAL errorVal)
2587 {
2588     char    *errString[] = {
2589                 [WMI_TARGET_PM_ERR_FAIL]    "WMI_TARGET_PM_ERR_FAIL",
2590                 [WMI_TARGET_KEY_NOT_FOUND]  "WMI_TARGET_KEY_NOT_FOUND",
2591                 [WMI_TARGET_DECRYPTION_ERR] "WMI_TARGET_DECRYPTION_ERR",
2592                 [WMI_TARGET_BMISS]          "WMI_TARGET_BMISS",
2593                 [WMI_PSDISABLE_NODE_JOIN]   "WMI_PSDISABLE_NODE_JOIN"
2594                 };
2595
2596     A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal);
2597
2598     /* One error is reported at a time, and errorval is a bitmask */
2599     if(errorVal & (errorVal - 1))
2600        return;
2601
2602     A_PRINTF("AR6000 Error type = ");
2603     switch(errorVal)
2604     {
2605         case WMI_TARGET_PM_ERR_FAIL:
2606         case WMI_TARGET_KEY_NOT_FOUND:
2607         case WMI_TARGET_DECRYPTION_ERR:
2608         case WMI_TARGET_BMISS:
2609         case WMI_PSDISABLE_NODE_JOIN:
2610             A_PRINTF("%s\n", errString[errorVal]);
2611             break;
2612         default:
2613             A_PRINTF("INVALID\n");
2614             break;
2615     }
2616
2617 }
2618
2619
2620 void
2621 ar6000_cac_event(AR_SOFTC_T *ar, A_UINT8 ac, A_UINT8 cacIndication,
2622                  A_UINT8 statusCode, A_UINT8 *tspecSuggestion)
2623 {
2624     WMM_TSPEC_IE    *tspecIe;
2625
2626     /*
2627      * This is the TSPEC IE suggestion from AP.
2628      * Suggestion provided by AP under some error
2629      * cases, could be helpful for the host app.
2630      * Check documentation.
2631      */
2632     tspecIe = (WMM_TSPEC_IE *)tspecSuggestion;
2633
2634     /*
2635      * What do we do, if we get TSPEC rejection? One thought
2636      * that comes to mind is implictly delete the pstream...
2637      */
2638     A_PRINTF("AR6000 CAC notification. "
2639                 "AC = %d, cacIndication = 0x%x, statusCode = 0x%x\n",
2640                  ac, cacIndication, statusCode);
2641 }
2642
2643 #define AR6000_PRINT_BSSID(_pBss)  do {     \
2644         A_PRINTF("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",\
2645                  (_pBss)[0],(_pBss)[1],(_pBss)[2],(_pBss)[3],\
2646                  (_pBss)[4],(_pBss)[5]);  \
2647 } while(0)
2648
2649 void
2650 ar6000_roam_tbl_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_TBL *pTbl)
2651 {
2652     A_UINT8 i;
2653
2654     A_PRINTF("ROAM TABLE NO OF ENTRIES is %d ROAM MODE is %d\n",
2655               pTbl->numEntries, pTbl->roamMode);
2656     for (i= 0; i < pTbl->numEntries; i++) {
2657         A_PRINTF("[%d]bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", i,
2658             pTbl->bssRoamInfo[i].bssid[0], pTbl->bssRoamInfo[i].bssid[1],
2659             pTbl->bssRoamInfo[i].bssid[2],
2660             pTbl->bssRoamInfo[i].bssid[3],
2661             pTbl->bssRoamInfo[i].bssid[4],
2662             pTbl->bssRoamInfo[i].bssid[5]);
2663         A_PRINTF("RSSI %d RSSIDT %d LAST RSSI %d UTIL %d ROAM_UTIL %d"
2664                  " BIAS %d\n",
2665             pTbl->bssRoamInfo[i].rssi,
2666             pTbl->bssRoamInfo[i].rssidt,
2667             pTbl->bssRoamInfo[i].last_rssi,
2668             pTbl->bssRoamInfo[i].util,
2669             pTbl->bssRoamInfo[i].roam_util,
2670             pTbl->bssRoamInfo[i].bias);
2671     }
2672 }
2673
2674 void
2675 ar6000_wow_list_event(struct ar6_softc *ar, A_UINT8 num_filters, WMI_GET_WOW_LIST_REPLY *wow_reply)
2676 {
2677     A_UINT8 i,j;
2678
2679     /*Each event now contains exactly one filter, see bug 26613*/
2680     A_PRINTF("WOW pattern %d of %d patterns\n", wow_reply->this_filter_num,                 wow_reply->num_filters);
2681     A_PRINTF("wow mode = %s host mode = %s\n",
2682             (wow_reply->wow_mode == 0? "disabled":"enabled"),
2683             (wow_reply->host_mode == 1 ? "awake":"asleep"));
2684
2685
2686     /*If there are no patterns, the reply will only contain generic
2687       WoW information. Pattern information will exist only if there are
2688       patterns present. Bug 26716*/
2689
2690    /* If this event contains pattern information, display it*/
2691     if (wow_reply->this_filter_num) {
2692         i=0;
2693         A_PRINTF("id=%d size=%d offset=%d\n",
2694                     wow_reply->wow_filters[i].wow_filter_id,
2695                     wow_reply->wow_filters[i].wow_filter_size,
2696                     wow_reply->wow_filters[i].wow_filter_offset);
2697        A_PRINTF("wow pattern = ");
2698        for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
2699              A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_pattern[j]);
2700         }
2701
2702         A_PRINTF("\nwow mask = ");
2703         for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
2704             A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_mask[j]);
2705         }
2706         A_PRINTF("\n");
2707     }
2708 }
2709
2710 /*
2711  * Report the Roaming related data collected on the target
2712  */
2713 void
2714 ar6000_display_roam_time(WMI_TARGET_ROAM_TIME *p)
2715 {
2716     A_PRINTF("Disconnect Data : BSSID: ");
2717     AR6000_PRINT_BSSID(p->disassoc_bssid);
2718     A_PRINTF(" RSSI %d DISASSOC Time %d NO_TXRX_TIME %d\n",
2719              p->disassoc_bss_rssi,p->disassoc_time,
2720              p->no_txrx_time);
2721     A_PRINTF("Connect Data: BSSID: ");
2722     AR6000_PRINT_BSSID(p->assoc_bssid);
2723     A_PRINTF(" RSSI %d ASSOC Time %d TXRX_TIME %d\n",
2724              p->assoc_bss_rssi,p->assoc_time,
2725              p->allow_txrx_time);
2726     A_PRINTF("Last Data Tx Time (b4 Disassoc) %d "\
2727              "First Data Tx Time (after Assoc) %d\n",
2728              p->last_data_txrx_time, p->first_data_txrx_time);
2729 }
2730
2731 void
2732 ar6000_roam_data_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_DATA *p)
2733 {
2734     switch (p->roamDataType) {
2735         case ROAM_DATA_TIME:
2736             ar6000_display_roam_time(&p->u.roamTime);
2737             break;
2738         default:
2739             break;
2740     }
2741 }
2742
2743 void
2744 ar6000_bssInfo_event_rx(AR_SOFTC_T *ar, A_UINT8 *datap, int len)
2745 {
2746     struct sk_buff *skb;
2747     WMI_BSS_INFO_HDR *bih = (WMI_BSS_INFO_HDR *)datap;
2748
2749
2750     if (!ar->arMgmtFilter) {
2751         return;
2752     }
2753     if (((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_BEACON) &&
2754         (bih->frameType != BEACON_FTYPE))  ||
2755         ((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_PROBE_RESP) &&
2756         (bih->frameType != PROBERESP_FTYPE)))
2757     {
2758         return;
2759     }
2760
2761     if ((skb = A_NETBUF_ALLOC_RAW(len)) != NULL) {
2762
2763         A_NETBUF_PUT(skb, len);
2764         A_MEMCPY(A_NETBUF_DATA(skb), datap, len);
2765         skb->dev = ar->arNetDev;
2766         printk("MAC RAW...\n");
2767 //        skb->mac.raw = A_NETBUF_DATA(skb);
2768         skb->ip_summed = CHECKSUM_NONE;
2769         skb->pkt_type = PACKET_OTHERHOST;
2770         skb->protocol = __constant_htons(0x0019);
2771         netif_rx(skb);
2772     }
2773 }
2774
2775 A_UINT32 wmiSendCmdNum;
2776
2777 A_STATUS
2778 ar6000_control_tx(void *devt, void *osbuf, WMI_PRI_STREAM_ID streamID)
2779 {
2780     AR_SOFTC_T       *ar = (AR_SOFTC_T *)devt;
2781     A_STATUS         status = A_OK;
2782     struct ar_cookie *cookie = NULL;
2783     int i;
2784
2785         /* take lock to protect ar6000_alloc_cookie() */
2786     AR6000_SPIN_LOCK(&ar->arLock, 0);
2787
2788     do {
2789
2790         AR_DEBUG2_PRINTF("ar_contrstatus = ol_tx: skb=0x%x, len=0x%x, sid=%d\n",
2791                          (A_UINT32)osbuf, A_NETBUF_LEN(osbuf), streamID);
2792
2793         if ((streamID == WMI_CONTROL_PRI) && (ar->arWMIControlEpFull)) {
2794                 /* control endpoint is full, don't allocate resources, we
2795                  * are just going to drop this packet */
2796             cookie = NULL;
2797             AR_DEBUG_PRINTF(" WMI Control EP full, dropping packet : 0x%X, len:%d \n",
2798                     (A_UINT32)osbuf, A_NETBUF_LEN(osbuf));
2799         } else {
2800             cookie = ar6000_alloc_cookie(ar);
2801         }
2802
2803         if (cookie == NULL) {
2804             status = A_NO_MEMORY;
2805             break;
2806         }
2807
2808         if(logWmiRawMsgs) {
2809             A_PRINTF("WMI cmd send, msgNo %d :", wmiSendCmdNum);
2810             for(i = 0; i < a_netbuf_to_len(osbuf); i++)
2811                 A_PRINTF("%x ", ((A_UINT8 *)a_netbuf_to_data(osbuf))[i]);
2812             A_PRINTF("\n");
2813         }
2814
2815         wmiSendCmdNum++;
2816
2817     } while (FALSE);
2818
2819     if (cookie != NULL) {
2820             /* got a structure to send it out on */
2821         ar->arTxPending[streamID]++;
2822
2823         if (streamID != WMI_CONTROL_PRI) {
2824             ar->arTotalTxDataPending++;
2825         }
2826     }
2827
2828     AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2829
2830     if (cookie != NULL) {
2831         cookie->arc_bp[0] = (A_UINT32)osbuf;
2832         cookie->arc_bp[1] = 0;
2833         SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
2834                                cookie,
2835                                A_NETBUF_DATA(osbuf),
2836                                A_NETBUF_LEN(osbuf),
2837                                arWMIStream2EndpointID(ar,streamID),
2838                                AR6K_CONTROL_PKT_TAG);
2839             /* this interface is asynchronous, if there is an error, cleanup will happen in the
2840              * TX completion callback */
2841         HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
2842         status = A_OK;
2843     }
2844
2845     return status;
2846 }
2847
2848 /* indicate tx activity or inactivity on a WMI stream */
2849 void ar6000_indicate_tx_activity(void *devt, A_UINT8 TrafficClass, A_BOOL Active)
2850 {
2851     AR_SOFTC_T  *ar = (AR_SOFTC_T *)devt;
2852     WMI_PRI_STREAM_ID streamid;
2853
2854     if (ar->arWmiEnabled) {
2855         streamid = wmi_get_stream_id(ar->arWmi, TrafficClass);
2856     } else {
2857             /* for mbox ping testing, the traffic class is mapped directly as a stream ID,
2858              * see handling of AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE in ioctl.c */
2859         streamid = (WMI_PRI_STREAM_ID)TrafficClass;
2860     }
2861
2862         /* notify HTC, this may cause credit distribution changes */
2863
2864     HTCIndicateActivityChange(ar->arHtcTarget,
2865                               arWMIStream2EndpointID(ar,streamid),
2866                               Active);
2867
2868 }
2869
2870 module_init(ar6000_init_module);
2871 module_exit(ar6000_cleanup_module);
2872
2873 /* Init cookie queue */
2874 static void
2875 ar6000_cookie_init(AR_SOFTC_T *ar)
2876 {
2877     A_UINT32    i;
2878
2879     ar->arCookieList = NULL;
2880     A_MEMZERO(s_ar_cookie_mem, sizeof(s_ar_cookie_mem));
2881
2882     for (i = 0; i < MAX_COOKIE_NUM; i++) {
2883         ar6000_free_cookie(ar, &s_ar_cookie_mem[i]);
2884     }
2885 }
2886
2887 /* cleanup cookie queue */
2888 static void
2889 ar6000_cookie_cleanup(AR_SOFTC_T *ar)
2890 {
2891     /* It is gone .... */
2892     ar->arCookieList = NULL;
2893 }
2894
2895 /* Init cookie queue */
2896 static void
2897 ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie)
2898 {
2899     /* Insert first */
2900     A_ASSERT(ar != NULL);
2901     A_ASSERT(cookie != NULL);
2902     cookie->arc_list_next = ar->arCookieList;
2903     ar->arCookieList = cookie;
2904 }
2905
2906 /* cleanup cookie queue */
2907 static struct ar_cookie *
2908 ar6000_alloc_cookie(AR_SOFTC_T  *ar)
2909 {
2910     struct ar_cookie   *cookie;
2911
2912     cookie = ar->arCookieList;
2913     if(cookie != NULL)
2914     {
2915         ar->arCookieList = cookie->arc_list_next;
2916     }
2917
2918     return cookie;
2919 }
2920
2921 #ifdef SEND_EVENT_TO_APP
2922 /*
2923  * This function is used to send event which come from taget to
2924  * the application. The buf which send to application is include
2925  * the event ID and event content.
2926  */
2927 #define EVENT_ID_LEN   2
2928 void ar6000_send_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId,
2929                               A_UINT8 *datap, int len)
2930 {
2931
2932 #if (WIRELESS_EXT >= 15)
2933
2934 /* note: IWEVCUSTOM only exists in wireless extensions after version 15 */
2935
2936     char *buf;
2937     A_UINT16 size;
2938     union iwreq_data wrqu;
2939
2940     size = len + EVENT_ID_LEN;
2941
2942     if (size > IW_CUSTOM_MAX) {
2943         AR_DEBUG_PRINTF("WMI event ID : 0x%4.4X, len = %d too big for IWEVCUSTOM (max=%d) \n",
2944                 eventId, size, IW_CUSTOM_MAX);
2945         return;
2946     }
2947
2948     buf = A_MALLOC_NOWAIT(size);
2949     A_MEMZERO(buf, size);
2950     A_MEMCPY(buf, &eventId, EVENT_ID_LEN);
2951     A_MEMCPY(buf+EVENT_ID_LEN, datap, len);
2952
2953     //AR_DEBUG_PRINTF("event ID = %d,len = %d\n",*(A_UINT16*)buf, size);
2954     A_MEMZERO(&wrqu, sizeof(wrqu));
2955     wrqu.data.length = size;
2956     wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
2957
2958     A_FREE(buf);
2959 #endif
2960
2961
2962 }
2963 #endif
2964
2965
2966 void
2967 ar6000_tx_retry_err_event(void *devt)
2968 {
2969     AR_DEBUG2_PRINTF("Tx retries reach maximum!\n");
2970 }
2971
2972 void
2973 ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, A_UINT8 snr)
2974 {
2975     AR_DEBUG2_PRINTF("snr threshold range %d, snr %d\n", newThreshold, snr);
2976 }
2977
2978 void
2979 ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL newThreshold, A_UINT8 lq)
2980 {
2981     AR_DEBUG2_PRINTF("lq threshold range %d, lq %d\n", newThreshold, lq);
2982 }
2983
2984
2985
2986 A_UINT32
2987 a_copy_to_user(void *to, const void *from, A_UINT32 n)
2988 {
2989     return(copy_to_user(to, from, n));
2990 }
2991
2992 A_UINT32
2993 a_copy_from_user(void *to, const void *from, A_UINT32 n)
2994 {
2995     return(copy_from_user(to, from, n));
2996 }
2997
2998
2999 A_STATUS
3000 ar6000_get_driver_cfg(struct net_device *dev,
3001                         A_UINT16 cfgParam,
3002                         void *result)
3003 {
3004
3005     A_STATUS    ret = 0;
3006
3007     switch(cfgParam)
3008     {
3009         case AR6000_DRIVER_CFG_GET_WLANNODECACHING:
3010            *((A_UINT32 *)result) = wlanNodeCaching;
3011            break;
3012         case AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS:
3013            *((A_UINT32 *)result) = logWmiRawMsgs;
3014             break;
3015         default:
3016            ret = EINVAL;
3017            break;
3018     }
3019
3020     return ret;
3021 }
3022
3023 void
3024 ar6000_keepalive_rx(void *devt, A_UINT8 configured)
3025 {
3026     AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
3027
3028     ar->arKeepaliveConfigured = configured;
3029     wake_up(&arEvent);
3030 }
3031
3032 void
3033 ar6000_pmkid_list_event(void *devt, A_UINT8 numPMKID, WMI_PMKID *pmkidList)
3034 {
3035     A_UINT8 i, j;
3036
3037     A_PRINTF("Number of Cached PMKIDs is %d\n", numPMKID);
3038
3039     for (i = 0; i < numPMKID; i++) {
3040         A_PRINTF("\nPMKID %d ", i);
3041             for (j = 0; j < WMI_PMKID_LEN; j++) {
3042                 A_PRINTF("%2.2x", pmkidList->pmkid[j]);
3043             }
3044         pmkidList++;
3045     }
3046 }
3047
3048 #ifdef USER_KEYS
3049 static A_STATUS
3050
3051 ar6000_reinstall_keys(AR_SOFTC_T *ar, A_UINT8 key_op_ctrl)
3052 {
3053     A_STATUS status = A_OK;
3054     struct ieee80211req_key *uik = &ar->user_saved_keys.ucast_ik;
3055     struct ieee80211req_key *bik = &ar->user_saved_keys.bcast_ik;
3056     CRYPTO_TYPE  keyType = ar->user_saved_keys.keyType;
3057
3058     if (IEEE80211_CIPHER_CCKM_KRK != uik->ik_type) {
3059         if (NONE_CRYPT == keyType) {
3060             goto _reinstall_keys_out;
3061         }
3062
3063         if (uik->ik_keylen) {
3064             status = wmi_addKey_cmd(ar->arWmi, uik->ik_keyix,
3065                     ar->user_saved_keys.keyType, PAIRWISE_USAGE,
3066                     uik->ik_keylen, (A_UINT8 *)&uik->ik_keyrsc,
3067                     uik->ik_keydata, key_op_ctrl, SYNC_BEFORE_WMIFLAG);
3068         }
3069
3070     } else {
3071         status = wmi_add_krk_cmd(ar->arWmi, uik->ik_keydata);
3072     }
3073
3074     if (IEEE80211_CIPHER_CCKM_KRK != bik->ik_type) {
3075         if (NONE_CRYPT == keyType) {
3076             goto _reinstall_keys_out;
3077         }
3078
3079         if (bik->ik_keylen) {
3080             status = wmi_addKey_cmd(ar->arWmi, bik->ik_keyix,
3081                     ar->user_saved_keys.keyType, GROUP_USAGE,
3082                     bik->ik_keylen, (A_UINT8 *)&bik->ik_keyrsc,
3083                     bik->ik_keydata, key_op_ctrl, NO_SYNC_WMIFLAG);
3084         }
3085     } else {
3086         status = wmi_add_krk_cmd(ar->arWmi, bik->ik_keydata);
3087     }
3088
3089 _reinstall_keys_out:
3090     ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
3091     ar->user_key_ctrl      = 0;
3092
3093     return status;
3094 }
3095 #endif /* USER_KEYS */
3096
3097
3098 void
3099 ar6000_dset_open_req(
3100     void *context,
3101     A_UINT32 id,
3102     A_UINT32 targHandle,
3103     A_UINT32 targReplyFn,
3104     A_UINT32 targReplyArg)
3105 {
3106 }
3107
3108 void
3109 ar6000_dset_close(
3110     void *context,
3111     A_UINT32 access_cookie)
3112 {
3113     return;
3114 }
3115
3116 void
3117 ar6000_dset_data_req(
3118    void *context,
3119    A_UINT32 accessCookie,
3120    A_UINT32 offset,
3121    A_UINT32 length,
3122    A_UINT32 targBuf,
3123    A_UINT32 targReplyFn,
3124    A_UINT32 targReplyArg)
3125 {
3126 }