[s3c24xx] bump to 2.6.30-rc6
[openwrt/svn-archive/archive.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 }