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