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