3 * Copyright (c) 2004-2007 Atheros Communications Inc.
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;
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.
21 * This driver is a pseudo ethernet driver to access the Atheros AR6000
24 static const char athId
[] __attribute__ ((unused
)) = "$Id: //depot/sw/releases/olca2.0-GPL/host/os/linux/ar6000_drv.c#2 $";
26 #include "ar6000_drv.h"
29 MODULE_LICENSE("GPL and additional rights");
31 #ifndef REORG_APTC_HEURISTICS
32 #undef ADAPTIVE_POWER_THROUGHPUT_CONTROL
33 #endif /* REORG_APTC_HEURISTICS */
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 */
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
;
48 APTC_TRAFFIC_RECORD aptcTR
;
49 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
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;
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);
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");
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
117 unsigned int mboxnum
= HTC_MAILBOX_NUM_MAX
;
120 #ifdef CONFIG_AR6000_WLAN_RESET
121 unsigned int resetok
= 1;
123 unsigned int resetok
= 0;
127 A_UINT32 g_dbg_flags
= DBG_DEFAULTS
;
128 unsigned int debugflags
= 0;
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};
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);
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");
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 */
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 */
193 #ifdef BLOCK_TX_PATH_FLAG
195 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
196 module_param(blocktx
, int, 0644);
198 MODULE_PARM(blocktx
, "i");
200 #endif /* BLOCK_TX_PATH_FLAG */
202 // TODO move to arsoft_c
203 USER_RSSI_THOLD rssi_map
[12];
205 int reconnect_flag
= 0;
207 DECLARE_WAIT_QUEUE_HEAD(ar6000_scan_queue
);
209 /* Function declarations */
210 static int ar6000_init_module(void);
211 static void ar6000_cleanup_module(void);
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 int ar6000_cleanup(struct net_device
*dev
);
217 static void ar6000_init_control_info(AR_SOFTC_T
*ar
);
218 static int ar6000_data_tx(struct sk_buff
*skb
, struct net_device
*dev
);
220 static void ar6000_destroy(struct net_device
*dev
, unsigned int unregister
);
221 static void ar6000_detect_error(unsigned long ptr
);
222 static struct net_device_stats
*ar6000_get_stats(struct net_device
*dev
);
223 static struct iw_statistics
*ar6000_get_iwstats(struct net_device
* dev
);
226 * HTC service connection handlers
228 static void ar6000_avail_ev(HTC_HANDLE HTCHandle
);
230 static void ar6000_unavail_ev(void *Instance
);
232 static void ar6000_target_failure(void *Instance
, A_STATUS Status
);
234 static void ar6000_rx(void *Context
, HTC_PACKET
*pPacket
);
236 static void ar6000_rx_refill(void *Context
,HTC_ENDPOINT_ID Endpoint
);
238 static void ar6000_tx_complete(void *Context
, HTC_PACKET
*pPacket
);
240 static void ar6000_tx_queue_full(void *Context
, HTC_ENDPOINT_ID Endpoint
);
242 static void ar6000_tx_queue_avail(void *Context
, HTC_ENDPOINT_ID Endpoint
);
248 static struct net_device
*ar6000_devices
[MAX_AR6000
];
249 extern struct iw_handler_def ath_iw_handler_def
;
250 DECLARE_WAIT_QUEUE_HEAD(arEvent
);
251 static void ar6000_cookie_init(AR_SOFTC_T
*ar
);
252 static void ar6000_cookie_cleanup(AR_SOFTC_T
*ar
);
253 static void ar6000_free_cookie(AR_SOFTC_T
*ar
, struct ar_cookie
* cookie
);
254 static struct ar_cookie
*ar6000_alloc_cookie(AR_SOFTC_T
*ar
);
255 static void ar6000_TxDataCleanup(AR_SOFTC_T
*ar
);
258 static A_STATUS
ar6000_reinstall_keys(AR_SOFTC_T
*ar
,A_UINT8 key_op_ctrl
);
262 static struct ar_cookie s_ar_cookie_mem
[MAX_COOKIE_NUM
];
264 #define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
265 ((ar->arTargetType == TARGET_TYPE_AR6001) ? \
266 AR6001_HOST_INTEREST_ITEM_ADDRESS(item) : \
267 AR6002_HOST_INTEREST_ITEM_ADDRESS(item))
270 /* Debug log support */
273 * Flag to govern whether the debug logs should be parsed in the kernel
274 * or reported to the application.
277 #define REPORT_DEBUG_LOGS_TO_APP
281 ar6000_set_host_app_area(AR_SOFTC_T
*ar
)
283 A_UINT32 address
, data
;
284 struct host_app_area_s host_app_area
;
286 /* Fetch the address of the host_app_area_s instance in the host interest area */
287 address
= HOST_INTEREST_ITEM_ADDRESS(ar
, hi_app_host_interest
);
288 if (ar6000_ReadRegDiag(ar
->arHifDevice
, &address
, &data
) != A_OK
) {
292 host_app_area
.wmi_protocol_ver
= WMI_PROTOCOL_VERSION
;
293 if (ar6000_WriteDataDiag(ar
->arHifDevice
, address
,
294 (A_UCHAR
*)&host_app_area
,
295 sizeof(struct host_app_area_s
)) != A_OK
)
304 dbglog_get_debug_hdr_ptr(AR_SOFTC_T
*ar
)
310 address
= HOST_INTEREST_ITEM_ADDRESS(ar
, hi_dbglog_hdr
);
311 if ((status
= ar6000_ReadDataDiag(ar
->arHifDevice
, address
,
312 (A_UCHAR
*)¶m
, 4)) != A_OK
)
321 * The dbglog module has been initialized. Its ok to access the relevant
322 * data stuctures over the diagnostic window.
325 ar6000_dbglog_init_done(AR_SOFTC_T
*ar
)
327 ar
->dbglog_init_done
= TRUE
;
331 dbglog_get_debug_fragment(A_INT8
*datap
, A_UINT32 len
, A_UINT32 limit
)
340 buffer
= (A_INT32
*)datap
;
341 length
= (limit
>> 2);
346 while (count
< length
) {
347 numargs
= DBGLOG_GET_NUMARGS(buffer
[count
]);
348 fraglen
= (count
<< 2);
349 count
+= numargs
+ 1;
357 dbglog_parse_debug_logs(A_INT8
*datap
, A_UINT32 len
)
368 buffer
= (A_INT32
*)datap
;
370 while (count
< length
) {
371 debugid
= DBGLOG_GET_DBGID(buffer
[count
]);
372 moduleid
= DBGLOG_GET_MODULEID(buffer
[count
]);
373 numargs
= DBGLOG_GET_NUMARGS(buffer
[count
]);
374 timestamp
= DBGLOG_GET_TIMESTAMP(buffer
[count
]);
377 AR_DEBUG_PRINTF("%d %d (%d)\n", moduleid
, debugid
, timestamp
);
381 AR_DEBUG_PRINTF("%d %d (%d): 0x%x\n", moduleid
, debugid
,
382 timestamp
, buffer
[count
+1]);
386 AR_DEBUG_PRINTF("%d %d (%d): 0x%x, 0x%x\n", moduleid
, debugid
,
387 timestamp
, buffer
[count
+1], buffer
[count
+2]);
391 AR_DEBUG_PRINTF("Invalid args: %d\n", numargs
);
393 count
+= numargs
+ 1;
398 ar6000_dbglog_get_debug_logs(AR_SOFTC_T
*ar
)
400 struct dbglog_hdr_s debug_hdr
;
401 struct dbglog_buf_s debug_buf
;
406 A_UINT32 debug_hdr_ptr
;
408 if (!ar
->dbglog_init_done
) return A_ERROR
;
410 #ifndef CONFIG_AR6000_WLAN_DEBUG
414 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
416 if (ar
->dbgLogFetchInProgress
) {
417 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
421 /* block out others */
422 ar
->dbgLogFetchInProgress
= TRUE
;
424 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
426 debug_hdr_ptr
= dbglog_get_debug_hdr_ptr(ar
);
427 printk("debug_hdr_ptr: 0x%x\n", debug_hdr_ptr
);
429 /* Get the contents of the ring buffer */
431 address
= debug_hdr_ptr
;
432 length
= sizeof(struct dbglog_hdr_s
);
433 ar6000_ReadDataDiag(ar
->arHifDevice
, address
,
434 (A_UCHAR
*)&debug_hdr
, length
);
435 address
= (A_UINT32
)debug_hdr
.dbuf
;
437 dropped
= debug_hdr
.dropped
;
438 length
= sizeof(struct dbglog_buf_s
);
439 ar6000_ReadDataDiag(ar
->arHifDevice
, address
,
440 (A_UCHAR
*)&debug_buf
, length
);
443 address
= (A_UINT32
)debug_buf
.buffer
;
444 length
= debug_buf
.length
;
445 if ((length
) && (debug_buf
.length
<= debug_buf
.bufsize
)) {
446 /* Rewind the index if it is about to overrun the buffer */
447 if (ar
->log_cnt
> (DBGLOG_HOST_LOG_BUFFER_SIZE
- length
)) {
450 if(A_OK
!= ar6000_ReadDataDiag(ar
->arHifDevice
, address
,
451 (A_UCHAR
*)&ar
->log_buffer
[ar
->log_cnt
], length
))
455 ar6000_dbglog_event(ar
, dropped
, &ar
->log_buffer
[ar
->log_cnt
], length
);
456 ar
->log_cnt
+= length
;
458 AR_DEBUG_PRINTF("Length: %d (Total size: %d)\n",
459 debug_buf
.length
, debug_buf
.bufsize
);
462 address
= (A_UINT32
)debug_buf
.next
;
463 length
= sizeof(struct dbglog_buf_s
);
464 if(A_OK
!= ar6000_ReadDataDiag(ar
->arHifDevice
, address
,
465 (A_UCHAR
*)&debug_buf
, length
))
470 } while (address
!= firstbuf
);
473 ar
->dbgLogFetchInProgress
= FALSE
;
479 ar6000_dbglog_event(AR_SOFTC_T
*ar
, A_UINT32 dropped
,
480 A_INT8
*buffer
, A_UINT32 length
)
482 #ifdef REPORT_DEBUG_LOGS_TO_APP
483 #define MAX_WIRELESS_EVENT_SIZE 252
485 * Break it up into chunks of MAX_WIRELESS_EVENT_SIZE bytes of messages.
486 * There seems to be a limitation on the length of message that could be
487 * transmitted to the user app via this mechanism.
492 send
= dbglog_get_debug_fragment(&buffer
[sent
], length
- sent
,
493 MAX_WIRELESS_EVENT_SIZE
);
495 ar6000_send_event_to_app(ar
, WMIX_DBGLOG_EVENTID
, &buffer
[sent
], send
);
497 send
= dbglog_get_debug_fragment(&buffer
[sent
], length
- sent
,
498 MAX_WIRELESS_EVENT_SIZE
);
501 AR_DEBUG_PRINTF("Dropped logs: 0x%x\nDebug info length: %d\n",
504 /* Interpret the debug logs */
505 dbglog_parse_debug_logs(buffer
, length
);
506 #endif /* REPORT_DEBUG_LOGS_TO_APP */
512 ar6000_init_module(void)
514 static int probed
= 0;
516 HTC_INIT_INFO initInfo
;
518 A_MEMZERO(&initInfo
,sizeof(initInfo
));
519 initInfo
.AddInstance
= ar6000_avail_ev
;
520 initInfo
.DeleteInstance
= ar6000_unavail_ev
;
521 initInfo
.TargetFailure
= ar6000_target_failure
;
525 /* Set the debug flags if specified at load time */
528 g_dbg_flags
= debugflags
;
537 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
538 memset(&aptcTR
, 0, sizeof(APTC_TRAFFIC_RECORD
));
539 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
541 #ifdef CONFIG_HOST_GPIO_SUPPORT
543 #endif /* CONFIG_HOST_GPIO_SUPPORT */
545 status
= HTCInit(&initInfo
);
553 ar6000_cleanup_module(void)
556 struct net_device
*ar6000_netdev
;
558 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
559 /* Delete the Adaptive Power Control timer */
560 if (timer_pending(&aptcTimer
)) {
561 del_timer_sync(&aptcTimer
);
563 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
565 for (i
=0; i
< MAX_AR6000
; i
++) {
566 if (ar6000_devices
[i
] != NULL
) {
567 ar6000_netdev
= ar6000_devices
[i
];
568 ar6000_devices
[i
] = NULL
;
569 ar6000_destroy(ar6000_netdev
, 1);
573 /* shutting down HTC will cause the HIF layer to detach from the
574 * underlying bus driver which will cause the subsequent deletion of
575 * all HIF and HTC instances */
578 AR_DEBUG_PRINTF("ar6000_cleanup: success\n");
581 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
583 aptcTimerHandler(unsigned long arg
)
590 ar
= (AR_SOFTC_T
*)arg
;
591 A_ASSERT(ar
!= NULL
);
592 A_ASSERT(!timer_pending(&aptcTimer
));
594 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
596 /* Get the number of bytes transferred */
597 numbytes
= aptcTR
.bytesTransmitted
+ aptcTR
.bytesReceived
;
598 aptcTR
.bytesTransmitted
= aptcTR
.bytesReceived
= 0;
600 /* Calculate and decide based on throughput thresholds */
601 throughput
= ((numbytes
* 8)/APTC_TRAFFIC_SAMPLING_INTERVAL
); /* Kbps */
602 if (throughput
< APTC_LOWER_THROUGHPUT_THRESHOLD
) {
603 /* Enable Sleep and delete the timer */
604 A_ASSERT(ar
->arWmiReady
== TRUE
);
605 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
606 status
= wmi_powermode_cmd(ar
->arWmi
, REC_POWER
);
607 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
608 A_ASSERT(status
== A_OK
);
609 aptcTR
.timerScheduled
= FALSE
;
611 A_TIMEOUT_MS(&aptcTimer
, APTC_TRAFFIC_SAMPLING_INTERVAL
, 0);
614 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
616 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
620 /* set HTC block size, assume BMI is already initialized */
621 A_STATUS
ar6000_SetHTCBlockSize(AR_SOFTC_T
*ar
)
624 A_UINT32 blocksizes
[HTC_MAILBOX_NUM_MAX
];
627 /* get the block sizes */
628 status
= HIFConfigureDevice(ar
->arHifDevice
, HIF_DEVICE_GET_MBOX_BLOCK_SIZE
,
629 blocksizes
, sizeof(blocksizes
));
631 if (A_FAILED(status
)) {
632 AR_DEBUG_PRINTF("Failed to get block size info from HIF layer...\n");
635 /* note: we actually get the block size for mailbox 1, for SDIO the block
636 * size on mailbox 0 is artificially set to 1 */
637 /* must be a power of 2 */
638 A_ASSERT((blocksizes
[1] & (blocksizes
[1] - 1)) == 0);
640 /* set the host interest area for the block size */
641 status
= BMIWriteMemory(ar
->arHifDevice
,
642 HOST_INTEREST_ITEM_ADDRESS(ar
, hi_mbox_io_block_sz
),
643 (A_UCHAR
*)&blocksizes
[1],
646 if (A_FAILED(status
)) {
647 AR_DEBUG_PRINTF("BMIWriteMemory for IO block size failed \n");
651 AR_DEBUG_PRINTF("Block Size Set: %d (target address:0x%X)\n",
652 blocksizes
[1], HOST_INTEREST_ITEM_ADDRESS(ar
, hi_mbox_io_block_sz
));
654 /* set the host interest area for the mbox ISR yield limit */
655 status
= BMIWriteMemory(ar
->arHifDevice
,
656 HOST_INTEREST_ITEM_ADDRESS(ar
, hi_mbox_isr_yield_limit
),
657 (A_UCHAR
*)&mbox_yield_limit
,
660 if (A_FAILED(status
)) {
661 AR_DEBUG_PRINTF("BMIWriteMemory for yield limit failed \n");
670 static void free_raw_buffers(AR_SOFTC_T
*ar
)
674 for (i
= 0; i
!= HTC_RAW_STREAM_NUM_MAX
; i
++) {
675 for (j
= 0; j
!= RAW_HTC_READ_BUFFERS_NUM
; j
++)
676 kfree(ar
->raw_htc_read_buffer
[i
][j
]);
677 for (j
= 0; j
!= RAW_HTC_WRITE_BUFFERS_NUM
; j
++)
678 kfree(ar
->raw_htc_write_buffer
[i
][j
]);
682 static int alloc_raw_buffers(AR_SOFTC_T
*ar
)
687 for (i
= 0; i
!= HTC_RAW_STREAM_NUM_MAX
; i
++) {
688 for (j
= 0; j
!= RAW_HTC_READ_BUFFERS_NUM
; j
++) {
689 b
= kzalloc(sizeof(*b
), GFP_KERNEL
);
692 ar
->raw_htc_read_buffer
[i
][j
] = b
;
694 for (j
= 0; j
!= RAW_HTC_WRITE_BUFFERS_NUM
; j
++) {
695 b
= kzalloc(sizeof(*b
), GFP_KERNEL
);
698 ar
->raw_htc_write_buffer
[i
][j
] = b
;
708 ar6000_avail_ev(HTC_HANDLE HTCHandle
)
711 struct net_device
*dev
;
713 int device_index
= 0;
715 AR_DEBUG_PRINTF("ar6000_available\n");
717 for (i
=0; i
< MAX_AR6000
; i
++) {
718 if (ar6000_devices
[i
] == NULL
) {
723 if (i
== MAX_AR6000
) {
724 AR_DEBUG_PRINTF("ar6000_available: max devices reached\n");
728 /* Save this. It gives a bit better readability especially since */
729 /* we use another local "i" variable below. */
732 A_ASSERT(HTCHandle
!= NULL
);
734 dev
= alloc_etherdev(sizeof(AR_SOFTC_T
));
736 AR_DEBUG_PRINTF("ar6000_available: can't alloc etherdev\n");
742 if (netdev_priv(dev
) == NULL
) {
743 printk(KERN_CRIT
"ar6000_available: Could not allocate memory\n");
747 A_MEMZERO(netdev_priv(dev
), sizeof(AR_SOFTC_T
));
749 ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
751 ar
->arHtcTarget
= HTCHandle
;
752 ar
->arHifDevice
= HTCGetHifDevice(HTCHandle
);
753 ar
->arWlanState
= WLAN_ENABLED
;
754 ar
->arRadioSwitch
= WLAN_ENABLED
;
755 ar
->arDeviceIndex
= device_index
;
757 A_INIT_TIMER(&ar
->arHBChallengeResp
.timer
, ar6000_detect_error
, dev
);
758 ar
->arHBChallengeResp
.seqNum
= 0;
759 ar
->arHBChallengeResp
.outstanding
= FALSE
;
760 ar
->arHBChallengeResp
.missCnt
= 0;
761 ar
->arHBChallengeResp
.frequency
= AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT
;
762 ar
->arHBChallengeResp
.missThres
= AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT
;
764 ar6000_init_control_info(ar
);
765 init_waitqueue_head(&arEvent
);
766 sema_init(&ar
->arSem
, 1);
768 if (alloc_raw_buffers(ar
)) {
769 free_raw_buffers(ar
);
771 * @@@ Clean up our own mess, but for anything else, cheerfully mimick
772 * the beautiful error non-handling of the rest of this function.
777 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
778 A_INIT_TIMER(&aptcTimer
, aptcTimerHandler
, ar
);
779 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
782 * If requested, perform some magic which requires no cooperation from
783 * the Target. It causes the Target to ignore flash and execute to the
786 * This is intended to support recovery from a corrupted flash on Targets
787 * that support flash.
791 ar6000_reset_device_skipflash(ar
->arHifDevice
);
796 struct bmi_target_info targ_info
;
798 if (BMIGetTargetInfo(ar
->arHifDevice
, &targ_info
) != A_OK
) {
802 ar
->arVersion
.target_ver
= targ_info
.target_ver
;
803 ar
->arTargetType
= targ_info
.target_type
;
806 if (enableuartprint
) {
809 if (BMIWriteMemory(ar
->arHifDevice
,
810 HOST_INTEREST_ITEM_ADDRESS(ar
, hi_serial_enable
),
814 AR_DEBUG_PRINTF("BMIWriteMemory for enableuartprint failed \n");
817 AR_DEBUG_PRINTF("Serial console prints enabled\n");
819 #ifdef CONFIG_HOST_TCMD_SUPPORT
821 ar
->arTargetMode
= AR6000_TCMD_MODE
;
823 ar
->arTargetMode
= AR6000_WLAN_MODE
;
826 if (enabletimerwar
) {
829 if (BMIReadMemory(ar
->arHifDevice
,
830 HOST_INTEREST_ITEM_ADDRESS(ar
, hi_option_flag
),
834 AR_DEBUG_PRINTF("BMIReadMemory for enabletimerwar failed \n");
838 param
|= HI_OPTION_TIMER_WAR
;
840 if (BMIWriteMemory(ar
->arHifDevice
,
841 HOST_INTEREST_ITEM_ADDRESS(ar
, hi_option_flag
),
845 AR_DEBUG_PRINTF("BMIWriteMemory for enabletimerwar failed \n");
848 AR_DEBUG_PRINTF("Timer WAR enabled\n");
852 /* since BMIInit is called in the driver layer, we have to set the block
853 * size here for the target */
855 if (A_FAILED(ar6000_SetHTCBlockSize(ar
))) {
859 spin_lock_init(&ar
->arLock
);
861 /* Don't install the init function if BMI is requested */
864 dev
->init
= ar6000_init
;
866 AR_DEBUG_PRINTF(" BMI enabled \n");
869 dev
->open
= &ar6000_open
;
870 dev
->stop
= &ar6000_close
;
871 dev
->hard_start_xmit
= &ar6000_data_tx
;
872 dev
->get_stats
= &ar6000_get_stats
;
874 /* dev->tx_timeout = ar6000_tx_timeout; */
875 dev
->do_ioctl
= &ar6000_ioctl
;
876 dev
->watchdog_timeo
= AR6000_TX_TIMEOUT
;
877 ar6000_ioctl_iwsetup(&ath_iw_handler_def
);
878 dev
->wireless_handlers
= &ath_iw_handler_def
;
879 ath_iw_handler_def
.get_wireless_stats
= ar6000_get_iwstats
; /*Displayed via proc fs */
882 * We need the OS to provide us with more headroom in order to
883 * perform dix to 802.3, WMI header encap, and the HTC header
885 dev
->hard_header_len
= ETH_HLEN
+ sizeof(ATH_LLC_SNAP_HDR
) +
886 sizeof(WMI_DATA_HDR
) + HTC_HEADER_LEN
;
888 /* This runs the init function */
889 SET_NETDEV_DEV(dev
, HIFGetOSDevice(ar
->arHifDevice
));
890 if (register_netdev(dev
)) {
891 AR_DEBUG_PRINTF("ar6000_avail: register_netdev failed\n");
892 ar6000_destroy(dev
, 0);
896 HTCSetInstance(ar
->arHtcTarget
, ar
);
898 /* We only register the device in the global list if we succeed. */
899 /* If the device is in the global list, it will be destroyed */
900 /* when the module is unloaded. */
901 ar6000_devices
[device_index
] = dev
;
903 AR_DEBUG_PRINTF("ar6000_avail: name=%s htcTarget=0x%x, dev=0x%x (%d), ar=0x%x\n",
904 dev
->name
, (A_UINT32
)HTCHandle
, (A_UINT32
)dev
, device_index
,
908 static void ar6000_target_failure(void *Instance
, A_STATUS Status
)
910 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Instance
;
911 WMI_TARGET_ERROR_REPORT_EVENT errEvent
;
912 static A_BOOL sip
= FALSE
;
914 if (Status
!= A_OK
) {
915 if (timer_pending(&ar
->arHBChallengeResp
.timer
)) {
916 A_UNTIMEOUT(&ar
->arHBChallengeResp
.timer
);
919 /* try dumping target assertion information (if any) */
920 ar6000_dump_target_assert_info(ar
->arHifDevice
,ar
->arTargetType
);
923 * Fetch the logs from the target via the diagnostic
926 ar6000_dbglog_get_debug_logs(ar
);
928 /* Report the error only once */
931 errEvent
.errorVal
= WMI_TARGET_COM_ERR
|
932 WMI_TARGET_FATAL_ERR
;
933 #ifdef SEND_EVENT_TO_APP
934 ar6000_send_event_to_app(ar
, WMI_ERROR_REPORT_EVENTID
,
935 (A_UINT8
*)&errEvent
,
936 sizeof(WMI_TARGET_ERROR_REPORT_EVENT
));
943 ar6000_unavail_ev(void *Instance
)
945 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Instance
;
946 /* NULL out it's entry in the global list */
947 ar6000_devices
[ar
->arDeviceIndex
] = NULL
;
948 ar6000_destroy(ar
->arNetDev
, 1);
952 * We need to differentiate between the surprise and planned removal of the
953 * device because of the following consideration:
954 * - In case of surprise removal, the hcd already frees up the pending
955 * for the device and hence there is no need to unregister the function
956 * driver inorder to get these requests. For planned removal, the function
957 * driver has to explictly unregister itself to have the hcd return all the
958 * pending requests before the data structures for the devices are freed up.
959 * Note that as per the current implementation, the function driver will
960 * end up releasing all the devices since there is no API to selectively
961 * release a particular device.
962 * - Certain commands issued to the target can be skipped for surprise
963 * removal since they will anyway not go through.
966 ar6000_destroy(struct net_device
*dev
, unsigned int unregister
)
970 AR_DEBUG_PRINTF("+ar6000_destroy \n");
972 if((dev
== NULL
) || ((ar
= netdev_priv(dev
)) == NULL
))
974 AR_DEBUG_PRINTF("%s(): Failed to get device structure.\n", __func__
);
978 /* Clear the tx counters */
979 memset(tx_attempt
, 0, sizeof(tx_attempt
));
980 memset(tx_post
, 0, sizeof(tx_post
));
981 memset(tx_complete
, 0, sizeof(tx_complete
));
983 /* Free up the device data structure */
985 unregister_netdev(dev
);
991 free_raw_buffers(ar
);
999 AR_DEBUG_PRINTF("-ar6000_destroy \n");
1002 static void ar6000_detect_error(unsigned long ptr
)
1004 struct net_device
*dev
= (struct net_device
*)ptr
;
1005 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1006 WMI_TARGET_ERROR_REPORT_EVENT errEvent
;
1008 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1010 if (ar
->arHBChallengeResp
.outstanding
) {
1011 ar
->arHBChallengeResp
.missCnt
++;
1013 ar
->arHBChallengeResp
.missCnt
= 0;
1016 if (ar
->arHBChallengeResp
.missCnt
> ar
->arHBChallengeResp
.missThres
) {
1017 /* Send Error Detect event to the application layer and do not reschedule the error detection module timer */
1018 ar
->arHBChallengeResp
.missCnt
= 0;
1019 ar
->arHBChallengeResp
.seqNum
= 0;
1020 errEvent
.errorVal
= WMI_TARGET_COM_ERR
| WMI_TARGET_FATAL_ERR
;
1021 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1022 #ifdef SEND_EVENT_TO_APP
1023 ar6000_send_event_to_app(ar
, WMI_ERROR_REPORT_EVENTID
,
1024 (A_UINT8
*)&errEvent
,
1025 sizeof(WMI_TARGET_ERROR_REPORT_EVENT
));
1030 /* Generate the sequence number for the next challenge */
1031 ar
->arHBChallengeResp
.seqNum
++;
1032 ar
->arHBChallengeResp
.outstanding
= TRUE
;
1034 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1036 /* Send the challenge on the control channel */
1037 if (wmi_get_challenge_resp_cmd(ar
->arWmi
, ar
->arHBChallengeResp
.seqNum
, DRV_HB_CHALLENGE
) != A_OK
) {
1038 AR_DEBUG_PRINTF("Unable to send heart beat challenge\n");
1042 /* Reschedule the timer for the next challenge */
1043 A_TIMEOUT_MS(&ar
->arHBChallengeResp
.timer
, ar
->arHBChallengeResp
.frequency
* 1000, 0);
1046 void ar6000_init_profile_info(AR_SOFTC_T
*ar
)
1049 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
1050 ar
->arNetworkType
= INFRA_NETWORK
;
1051 ar
->arDot11AuthMode
= OPEN_AUTH
;
1052 ar
->arAuthMode
= NONE_AUTH
;
1053 ar
->arPairwiseCrypto
= NONE_CRYPT
;
1054 ar
->arPairwiseCryptoLen
= 0;
1055 ar
->arGroupCrypto
= NONE_CRYPT
;
1056 ar
->arGroupCryptoLen
= 0;
1057 A_MEMZERO(ar
->arWepKeyList
, sizeof(ar
->arWepKeyList
));
1058 A_MEMZERO(ar
->arReqBssid
, sizeof(ar
->arReqBssid
));
1059 A_MEMZERO(ar
->arBssid
, sizeof(ar
->arBssid
));
1060 ar
->arBssChannel
= 0;
1064 ar6000_init_control_info(AR_SOFTC_T
*ar
)
1066 ar
->arWmiEnabled
= FALSE
;
1067 ar6000_init_profile_info(ar
);
1068 ar
->arDefTxKeyIndex
= 0;
1069 A_MEMZERO(ar
->arWepKeyList
, sizeof(ar
->arWepKeyList
));
1070 ar
->arChannelHint
= 0;
1071 ar
->arListenInterval
= MAX_LISTEN_INTERVAL
;
1072 ar
->arVersion
.host_ver
= AR6K_SW_VERSION
;
1075 ar
->arTxPwrSet
= FALSE
;
1077 ar
->arBeaconInterval
= 0;
1079 ar
->arMaxRetries
= 0;
1080 ar
->arWmmEnabled
= TRUE
;
1084 ar6000_open(struct net_device
*dev
)
1086 /* Wake up the queues */
1087 netif_start_queue(dev
);
1093 ar6000_close(struct net_device
*dev
)
1095 /* Stop the transmit queues */
1096 netif_stop_queue(dev
);
1101 ar6000_cleanup(struct net_device
*dev
)
1103 AR_SOFTC_T
*ar
= netdev_priv(dev
);
1105 /* Stop the transmit queues */
1106 netif_stop_queue(dev
);
1108 /* Disable the target and the interrupts associated with it */
1109 if (ar
->arWmiReady
== TRUE
)
1113 if (ar
->arConnected
== TRUE
|| ar
->arConnectPending
== TRUE
)
1115 AR_DEBUG_PRINTF("%s(): Disconnect\n", __func__
);
1116 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1117 ar6000_init_profile_info(ar
);
1118 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1119 wmi_disconnect_cmd(ar
->arWmi
);
1122 ar6000_dbglog_get_debug_logs(ar
);
1123 ar
->arWmiReady
= FALSE
;
1124 ar
->arConnected
= FALSE
;
1125 ar
->arConnectPending
= FALSE
;
1126 wmi_shutdown(ar
->arWmi
);
1127 ar
->arWmiEnabled
= FALSE
;
1129 ar
->arWlanState
= WLAN_ENABLED
;
1131 ar
->user_savedkeys_stat
= USER_SAVEDKEYS_STAT_INIT
;
1132 ar
->user_key_ctrl
= 0;
1136 AR_DEBUG_PRINTF("%s(): WMI stopped\n", __func__
);
1140 AR_DEBUG_PRINTF("%s(): WMI not ready 0x%08x 0x%08x\n",
1141 __func__
, (unsigned int) ar
, (unsigned int) ar
->arWmi
);
1143 /* Shut down WMI if we have started it */
1144 if(ar
->arWmiEnabled
== TRUE
)
1146 AR_DEBUG_PRINTF("%s(): Shut down WMI\n", __func__
);
1147 wmi_shutdown(ar
->arWmi
);
1148 ar
->arWmiEnabled
= FALSE
;
1154 HTCStop(ar
->arHtcTarget
);
1156 /* set the instance to NULL so we do not get called back on remove incase we
1157 * we're explicity destroyed by module unload */
1158 HTCSetInstance(ar
->arHtcTarget
, NULL
);
1161 /* try to reset the device if we can
1162 * The driver may have been configure NOT to reset the target during
1163 * a debug session */
1164 AR_DEBUG_PRINTF(" Attempting to reset target on instance destroy.... \n");
1165 ar6000_reset_device(ar
->arHifDevice
, ar
->arTargetType
);
1167 AR_DEBUG_PRINTF(" Host does not want target reset. \n");
1170 /* Done with cookies */
1171 ar6000_cookie_cleanup(ar
);
1179 /* connect to a service */
1180 static A_STATUS
ar6000_connectservice(AR_SOFTC_T
*ar
,
1181 HTC_SERVICE_CONNECT_REQ
*pConnect
,
1182 WMI_PRI_STREAM_ID WmiStreamID
,
1186 HTC_SERVICE_CONNECT_RESP response
;
1190 A_MEMZERO(&response
,sizeof(response
));
1192 status
= HTCConnectService(ar
->arHtcTarget
,
1196 if (A_FAILED(status
)) {
1197 AR_DEBUG_PRINTF(" Failed to connect to %s service status:%d \n", pDesc
, status
);
1201 if (WmiStreamID
== WMI_NOT_MAPPED
) {
1206 /* set endpoint mapping for the WMI stream in the driver layer */
1207 arSetWMIStream2EndpointIDMap(ar
,WmiStreamID
,response
.Endpoint
);
1214 static void ar6000_TxDataCleanup(AR_SOFTC_T
*ar
)
1216 /* flush all the data (non-control) streams
1217 * we only flush packets that are tagged as data, we leave any control packets that
1218 * were in the TX queues alone */
1219 HTCFlushEndpoint(ar
->arHtcTarget
,
1220 arWMIStream2EndpointID(ar
,WMI_BEST_EFFORT_PRI
),
1222 HTCFlushEndpoint(ar
->arHtcTarget
,
1223 arWMIStream2EndpointID(ar
,WMI_LOW_PRI
),
1225 HTCFlushEndpoint(ar
->arHtcTarget
,
1226 arWMIStream2EndpointID(ar
,WMI_HIGH_PRI
),
1228 HTCFlushEndpoint(ar
->arHtcTarget
,
1229 arWMIStream2EndpointID(ar
,WMI_HIGHEST_PRI
),
1233 /* This function does one time initialization for the lifetime of the device */
1234 int ar6000_init(struct net_device
*dev
)
1240 if((ar
= netdev_priv(dev
)) == NULL
)
1245 /* Do we need to finish the BMI phase */
1246 if(BMIDone(ar
->arHifDevice
) != A_OK
)
1254 if (ar
->arVersion
.host_ver
!= ar
->arVersion
.target_ver
) {
1255 A_PRINTF("WARNING: Host version 0x%x does not match Target "
1257 ar
->arVersion
.host_ver
, ar
->arVersion
.target_ver
);
1261 /* Indicate that WMI is enabled (although not ready yet) */
1262 ar
->arWmiEnabled
= TRUE
;
1263 if ((ar
->arWmi
= wmi_init((void *) ar
)) == NULL
)
1265 AR_DEBUG_PRINTF("%s() Failed to initialize WMI.\n", __func__
);
1269 AR_DEBUG_PRINTF("%s() Got WMI @ 0x%08x.\n", __func__
,
1270 (unsigned int) ar
->arWmi
);
1274 HTC_SERVICE_CONNECT_REQ connect
;
1276 /* the reason we have to wait for the target here is that the driver layer
1277 * has to init BMI in order to set the host block size,
1279 status
= HTCWaitTarget(ar
->arHtcTarget
);
1281 if (A_FAILED(status
)) {
1285 A_MEMZERO(&connect
,sizeof(connect
));
1286 /* meta data is unused for now */
1287 connect
.pMetaData
= NULL
;
1288 connect
.MetaDataLength
= 0;
1289 /* these fields are the same for all service endpoints */
1290 connect
.EpCallbacks
.pContext
= ar
;
1291 connect
.EpCallbacks
.EpTxComplete
= ar6000_tx_complete
;
1292 connect
.EpCallbacks
.EpRecv
= ar6000_rx
;
1293 connect
.EpCallbacks
.EpRecvRefill
= ar6000_rx_refill
;
1294 connect
.EpCallbacks
.EpSendFull
= ar6000_tx_queue_full
;
1295 connect
.EpCallbacks
.EpSendAvail
= ar6000_tx_queue_avail
;
1296 /* set the max queue depth so that our ar6000_tx_queue_full handler gets called.
1297 * Linux has the peculiarity of not providing flow control between the
1298 * NIC and the network stack. There is no API to indicate that a TX packet
1299 * was sent which could provide some back pressure to the network stack.
1300 * Under linux you would have to wait till the network stack consumed all sk_buffs
1301 * before any back-flow kicked in. Which isn't very friendly.
1302 * So we have to manage this ourselves */
1303 connect
.MaxSendQueueDepth
= 32;
1305 /* connect to control service */
1306 connect
.ServiceID
= WMI_CONTROL_SVC
;
1307 status
= ar6000_connectservice(ar
,
1311 if (A_FAILED(status
)) {
1315 /* for the remaining data services set the connection flag to reduce dribbling,
1316 * if configured to do so */
1317 if (reduce_credit_dribble
) {
1318 connect
.ConnectionFlags
|= HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE
;
1319 /* the credit dribble trigger threshold is (reduce_credit_dribble - 1) for a value
1321 connect
.ConnectionFlags
&= ~HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK
;
1322 connect
.ConnectionFlags
|=
1323 ((A_UINT16
)reduce_credit_dribble
- 1) & HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK
;
1325 /* connect to best-effort service */
1326 connect
.ServiceID
= WMI_DATA_BE_SVC
;
1328 status
= ar6000_connectservice(ar
,
1330 WMI_BEST_EFFORT_PRI
,
1332 if (A_FAILED(status
)) {
1336 /* connect to back-ground
1337 * map this to WMI LOW_PRI */
1338 connect
.ServiceID
= WMI_DATA_BK_SVC
;
1339 status
= ar6000_connectservice(ar
,
1343 if (A_FAILED(status
)) {
1347 /* connect to Video service, map this to
1349 connect
.ServiceID
= WMI_DATA_VI_SVC
;
1350 status
= ar6000_connectservice(ar
,
1354 if (A_FAILED(status
)) {
1358 /* connect to VO service, this is currently not
1359 * mapped to a WMI priority stream due to historical reasons.
1360 * WMI originally defined 3 priorities over 3 mailboxes
1361 * We can change this when WMI is reworked so that priorities are not
1362 * dependent on mailboxes */
1363 connect
.ServiceID
= WMI_DATA_VO_SVC
;
1364 status
= ar6000_connectservice(ar
,
1368 if (A_FAILED(status
)) {
1372 A_ASSERT(arWMIStream2EndpointID(ar
,WMI_CONTROL_PRI
) != 0);
1373 A_ASSERT(arWMIStream2EndpointID(ar
,WMI_BEST_EFFORT_PRI
) != 0);
1374 A_ASSERT(arWMIStream2EndpointID(ar
,WMI_LOW_PRI
) != 0);
1375 A_ASSERT(arWMIStream2EndpointID(ar
,WMI_HIGH_PRI
) != 0);
1376 A_ASSERT(arWMIStream2EndpointID(ar
,WMI_HIGHEST_PRI
) != 0);
1379 if (A_FAILED(status
)) {
1384 * give our connected endpoints some buffers
1386 ar6000_rx_refill(ar
, arWMIStream2EndpointID(ar
,WMI_CONTROL_PRI
));
1388 ar6000_rx_refill(ar
, arWMIStream2EndpointID(ar
,WMI_BEST_EFFORT_PRI
));
1391 * We will post the receive buffers only for SPE testing and so we are
1392 * making it conditional on the 'bypasswmi' flag.
1395 ar6000_rx_refill(ar
,arWMIStream2EndpointID(ar
,WMI_LOW_PRI
));
1396 ar6000_rx_refill(ar
,arWMIStream2EndpointID(ar
,WMI_HIGH_PRI
));
1399 /* setup credit distribution */
1400 ar6000_setup_credit_dist(ar
->arHtcTarget
, &ar
->arCreditStateInfo
);
1402 /* Since cookies are used for HTC transports, they should be */
1403 /* initialized prior to enabling HTC. */
1404 ar6000_cookie_init(ar
);
1407 status
= HTCStart(ar
->arHtcTarget
);
1409 if (status
!= A_OK
) {
1410 if (ar
->arWmiEnabled
== TRUE
) {
1411 wmi_shutdown(ar
->arWmi
);
1412 ar
->arWmiEnabled
= FALSE
;
1415 ar6000_cookie_cleanup(ar
);
1420 /* Wait for Wmi event to be ready */
1421 timeleft
= wait_event_interruptible_timeout(arEvent
,
1422 (ar
->arWmiReady
== TRUE
), wmitimeout
* HZ
);
1424 if(!timeleft
|| signal_pending(current
))
1426 AR_DEBUG_PRINTF("WMI is not ready or wait was interrupted\n");
1427 #if defined(DWSIM) /* TBDXXX */
1428 AR_DEBUG_PRINTF(".....but proceed anyway.\n");
1434 AR_DEBUG_PRINTF("%s() WMI is ready\n", __func__
);
1436 /* Communicate the wmi protocol verision to the target */
1437 if ((ar6000_set_host_app_area(ar
)) != A_OK
) {
1438 AR_DEBUG_PRINTF("Unable to set the host app area\n");
1442 ar
->arNumDataEndPts
= 1;
1449 ar6000_bitrate_rx(void *devt
, A_INT32 rateKbps
)
1451 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
1453 ar
->arBitRate
= rateKbps
;
1458 ar6000_ratemask_rx(void *devt
, A_UINT16 ratemask
)
1460 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
1462 ar
->arRateMask
= ratemask
;
1467 ar6000_txPwr_rx(void *devt
, A_UINT8 txPwr
)
1469 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
1471 ar
->arTxPwr
= txPwr
;
1477 ar6000_channelList_rx(void *devt
, A_INT8 numChan
, A_UINT16
*chanList
)
1479 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
1481 A_MEMCPY(ar
->arChannelList
, chanList
, numChan
* sizeof (A_UINT16
));
1482 ar
->arNumChannels
= numChan
;
1488 ar6000_ibss_map_epid(struct sk_buff
*skb
, struct net_device
*dev
, A_UINT32
* mapNo
)
1490 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1492 ATH_MAC_HDR
*macHdr
;
1496 datap
= A_NETBUF_DATA(skb
);
1497 macHdr
= (ATH_MAC_HDR
*)(datap
+ sizeof(WMI_DATA_HDR
));
1498 if (IEEE80211_IS_MULTICAST(macHdr
->dstMac
)) {
1503 for (i
= 0; i
< ar
->arNodeNum
; i
++) {
1504 if (IEEE80211_ADDR_EQ(macHdr
->dstMac
, ar
->arNodeMap
[i
].macAddress
)) {
1506 ar
->arNodeMap
[i
].txPending
++;
1507 return ar
->arNodeMap
[i
].epId
;
1510 if ((eptMap
== -1) && !ar
->arNodeMap
[i
].txPending
) {
1516 eptMap
= ar
->arNodeNum
;
1518 A_ASSERT(ar
->arNodeNum
<= MAX_NODE_NUM
);
1521 A_MEMCPY(ar
->arNodeMap
[eptMap
].macAddress
, macHdr
->dstMac
, IEEE80211_ADDR_LEN
);
1523 for (i
= ENDPOINT_2
; i
<= ENDPOINT_5
; i
++) {
1524 if (!ar
->arTxPending
[i
]) {
1525 ar
->arNodeMap
[eptMap
].epId
= i
;
1528 // No free endpoint is available, start redistribution on the inuse endpoints.
1529 if (i
== ENDPOINT_5
) {
1530 ar
->arNodeMap
[eptMap
].epId
= ar
->arNexEpId
;
1532 if (ar
->arNexEpId
> ENDPOINT_5
) {
1533 ar
->arNexEpId
= ENDPOINT_2
;
1538 (*mapNo
) = eptMap
+ 1;
1539 ar
->arNodeMap
[eptMap
].txPending
++;
1541 return ar
->arNodeMap
[eptMap
].epId
;
1545 static void ar6000_dump_skb(struct sk_buff
*skb
)
1548 for (ch
= A_NETBUF_DATA(skb
);
1549 (A_UINT32
)ch
< ((A_UINT32
)A_NETBUF_DATA(skb
) +
1550 A_NETBUF_LEN(skb
)); ch
++)
1552 AR_DEBUG_PRINTF("%2.2x ", *ch
);
1554 AR_DEBUG_PRINTF("\n");
1559 ar6000_data_tx(struct sk_buff
*skb
, struct net_device
*dev
)
1561 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1562 WMI_PRI_STREAM_ID streamID
= WMI_NOT_MAPPED
;
1565 struct ar_cookie
*cookie
;
1566 A_BOOL checkAdHocPsMapping
= FALSE
;
1568 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
1572 AR_DEBUG2_PRINTF("ar6000_data_tx start - skb=0x%x, data=0x%x, len=0x%x\n",
1573 (A_UINT32
)skb
, (A_UINT32
)A_NETBUF_DATA(skb
),
1575 #ifdef CONFIG_HOST_TCMD_SUPPORT
1576 /* TCMD doesnt support any data, free the buf and return */
1577 if(ar
->arTargetMode
== AR6000_TCMD_MODE
) {
1584 if (ar
->arWmiReady
== FALSE
&& bypasswmi
== 0) {
1588 #ifdef BLOCK_TX_PATH_FLAG
1592 #endif /* BLOCK_TX_PATH_FLAG */
1594 if (ar
->arWmiEnabled
) {
1595 if (A_NETBUF_HEADROOM(skb
) < dev
->hard_header_len
) {
1596 struct sk_buff
*newbuf
;
1598 * We really should have gotten enough headroom but sometimes
1599 * we still get packets with not enough headroom. Copy the packet.
1601 len
= A_NETBUF_LEN(skb
);
1602 newbuf
= A_NETBUF_ALLOC(len
);
1603 if (newbuf
== NULL
) {
1606 A_NETBUF_PUT(newbuf
, len
);
1607 A_MEMCPY(A_NETBUF_DATA(newbuf
), A_NETBUF_DATA(skb
), len
);
1610 /* fall through and assemble header */
1613 if (wmi_dix_2_dot3(ar
->arWmi
, skb
) != A_OK
) {
1614 AR_DEBUG_PRINTF("ar6000_data_tx - wmi_dix_2_dot3 failed\n");
1618 if (wmi_data_hdr_add(ar
->arWmi
, skb
, DATA_MSGTYPE
) != A_OK
) {
1619 AR_DEBUG_PRINTF("ar6000_data_tx - wmi_data_hdr_add failed\n");
1623 if ((ar
->arNetworkType
== ADHOC_NETWORK
) &&
1624 ar
->arIbssPsEnable
&& ar
->arConnected
) {
1625 /* flag to check adhoc mapping once we take the lock below: */
1626 checkAdHocPsMapping
= TRUE
;
1629 /* get the stream mapping */
1630 if (ar
->arWmmEnabled
) {
1631 streamID
= wmi_get_stream_id(ar
->arWmi
,
1632 wmi_implicit_create_pstream(ar
->arWmi
, skb
, UPLINK_TRAFFIC
, UNDEFINED_PRI
));
1634 streamID
= WMI_BEST_EFFORT_PRI
;
1639 struct iphdr
*ipHdr
;
1641 * the endpoint is directly based on the TOS field in the IP
1642 * header **** only for testing ******
1644 ipHdr
= A_NETBUF_DATA(skb
) + sizeof(ATH_MAC_HDR
);
1645 /* here we map the TOS field to an endpoint number, this is for
1646 * the endpointping test application */
1647 streamID
= IP_TOS_TO_WMI_PRI(ipHdr
->tos
);
1652 /* did we succeed ? */
1653 if ((streamID
== WMI_NOT_MAPPED
) && !checkAdHocPsMapping
) {
1654 /* cleanup and exit */
1656 AR6000_STAT_INC(ar
, tx_dropped
);
1657 AR6000_STAT_INC(ar
, tx_aborted_errors
);
1663 /* take the lock to protect driver data */
1664 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1668 if (checkAdHocPsMapping
) {
1669 streamID
= ar6000_ibss_map_epid(skb
, dev
, &mapNo
);
1672 A_ASSERT(streamID
!= WMI_NOT_MAPPED
);
1674 /* validate that the endpoint is connected */
1675 if (arWMIStream2EndpointID(ar
,streamID
) == 0) {
1676 AR_DEBUG_PRINTF("Stream %d is NOT mapped!\n",streamID
);
1679 /* allocate resource for this packet */
1680 cookie
= ar6000_alloc_cookie(ar
);
1682 if (cookie
!= NULL
) {
1683 /* update counts while the lock is held */
1684 ar
->arTxPending
[streamID
]++;
1685 ar
->arTotalTxDataPending
++;
1690 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1692 if (cookie
!= NULL
) {
1693 cookie
->arc_bp
[0] = (A_UINT32
)skb
;
1694 cookie
->arc_bp
[1] = mapNo
;
1695 SET_HTC_PACKET_INFO_TX(&cookie
->HtcPkt
,
1699 arWMIStream2EndpointID(ar
,streamID
),
1703 if (debugdriver
>= 3) {
1704 ar6000_dump_skb(skb
);
1707 /* HTC interface is asynchronous, if this fails, cleanup will happen in
1708 * the ar6000_tx_complete callback */
1709 HTCSendPkt(ar
->arHtcTarget
, &cookie
->HtcPkt
);
1711 /* no packet to send, cleanup */
1713 AR6000_STAT_INC(ar
, tx_dropped
);
1714 AR6000_STAT_INC(ar
, tx_aborted_errors
);
1720 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1722 tvsub(register struct timeval
*out
, register struct timeval
*in
)
1724 if((out
->tv_usec
-= in
->tv_usec
) < 0) {
1726 out
->tv_usec
+= 1000000;
1728 out
->tv_sec
-= in
->tv_sec
;
1732 applyAPTCHeuristics(AR_SOFTC_T
*ar
)
1736 A_UINT32 throughput
;
1740 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1742 if ((enableAPTCHeuristics
) && (!aptcTR
.timerScheduled
)) {
1743 do_gettimeofday(&ts
);
1744 tvsub(&ts
, &aptcTR
.samplingTS
);
1745 duration
= ts
.tv_sec
* 1000 + ts
.tv_usec
/ 1000; /* ms */
1746 numbytes
= aptcTR
.bytesTransmitted
+ aptcTR
.bytesReceived
;
1748 if (duration
> APTC_TRAFFIC_SAMPLING_INTERVAL
) {
1749 /* Initialize the time stamp and byte count */
1750 aptcTR
.bytesTransmitted
= aptcTR
.bytesReceived
= 0;
1751 do_gettimeofday(&aptcTR
.samplingTS
);
1753 /* Calculate and decide based on throughput thresholds */
1754 throughput
= ((numbytes
* 8) / duration
);
1755 if (throughput
> APTC_UPPER_THROUGHPUT_THRESHOLD
) {
1756 /* Disable Sleep and schedule a timer */
1757 A_ASSERT(ar
->arWmiReady
== TRUE
);
1758 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1759 status
= wmi_powermode_cmd(ar
->arWmi
, MAX_PERF_POWER
);
1760 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1761 A_TIMEOUT_MS(&aptcTimer
, APTC_TRAFFIC_SAMPLING_INTERVAL
, 0);
1762 aptcTR
.timerScheduled
= TRUE
;
1767 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1769 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1772 ar6000_tx_queue_full(void *Context
, HTC_ENDPOINT_ID Endpoint
)
1774 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*) Context
;
1776 if (Endpoint
== arWMIStream2EndpointID(ar
,WMI_CONTROL_PRI
)) {
1778 /* under normal WMI if this is getting full, then something is running rampant
1779 * the host should not be exhausting the WMI queue with too many commands
1780 * the only exception to this is during testing using endpointping */
1782 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1783 /* set flag to handle subsequent messages */
1784 ar
->arWMIControlEpFull
= TRUE
;
1785 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1786 AR_DEBUG_PRINTF("WMI Control Endpoint is FULL!!! \n");
1789 /* one of the data endpoints queues is getting full..need to stop network stack
1790 * the queue will resume after credits received */
1791 netif_stop_queue(ar
->arNetDev
);
1796 ar6000_tx_queue_avail(void *Context
, HTC_ENDPOINT_ID Endpoint
)
1798 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Context
;
1800 if (Endpoint
== arWMIStream2EndpointID(ar
,WMI_CONTROL_PRI
)) {
1801 /* FIXME: what do for it? */
1803 /* Wake up interface, rescheduling prevented. */
1804 if (ar
->arConnected
== TRUE
|| bypasswmi
)
1805 netif_wake_queue(ar
->arNetDev
);
1810 ar6000_tx_complete(void *Context
, HTC_PACKET
*pPacket
)
1812 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Context
;
1813 void *cookie
= (void *)pPacket
->pPktContext
;
1814 struct sk_buff
*skb
= NULL
;
1817 struct ar_cookie
* ar_cookie
;
1818 WMI_PRI_STREAM_ID streamID
;
1819 A_BOOL wakeEvent
= FALSE
;
1821 status
= pPacket
->Status
;
1822 ar_cookie
= (struct ar_cookie
*)cookie
;
1823 skb
= (struct sk_buff
*)ar_cookie
->arc_bp
[0];
1824 streamID
= arEndpoint2WMIStreamID(ar
,pPacket
->Endpoint
);
1825 mapNo
= ar_cookie
->arc_bp
[1];
1828 A_ASSERT(pPacket
->pBuffer
== A_NETBUF_DATA(skb
));
1830 if (A_SUCCESS(status
)) {
1831 A_ASSERT(pPacket
->ActualLength
== A_NETBUF_LEN(skb
));
1834 AR_DEBUG2_PRINTF("ar6000_tx_complete skb=0x%x data=0x%x len=0x%x sid=%d ",
1835 (A_UINT32
)skb
, (A_UINT32
)pPacket
->pBuffer
,
1836 pPacket
->ActualLength
,
1839 /* lock the driver as we update internal state */
1840 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1842 ar
->arTxPending
[streamID
]--;
1844 if ((streamID
!= WMI_CONTROL_PRI
) || bypasswmi
) {
1845 ar
->arTotalTxDataPending
--;
1848 if (streamID
== WMI_CONTROL_PRI
)
1850 if (ar
->arWMIControlEpFull
) {
1851 /* since this packet completed, the WMI EP is no longer full */
1852 ar
->arWMIControlEpFull
= FALSE
;
1855 if (ar
->arTxPending
[streamID
] == 0) {
1860 if (A_FAILED(status
)) {
1861 AR_DEBUG_PRINTF("%s() -TX ERROR, status: 0x%x\n", __func__
,
1863 AR6000_STAT_INC(ar
, tx_errors
);
1865 AR_DEBUG2_PRINTF("OK\n");
1866 AR6000_STAT_INC(ar
, tx_packets
);
1867 ar
->arNetStats
.tx_bytes
+= A_NETBUF_LEN(skb
);
1868 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1869 aptcTR
.bytesTransmitted
+= a_netbuf_to_len(skb
);
1870 applyAPTCHeuristics(ar
);
1871 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1874 // TODO this needs to be looked at
1875 if ((ar
->arNetworkType
== ADHOC_NETWORK
) && ar
->arIbssPsEnable
1876 && (streamID
!= WMI_CONTROL_PRI
) && mapNo
)
1879 ar
->arNodeMap
[mapNo
].txPending
--;
1881 if (!ar
->arNodeMap
[mapNo
].txPending
&& (mapNo
== (ar
->arNodeNum
- 1))) {
1883 for (i
= ar
->arNodeNum
; i
> 0; i
--) {
1884 if (!ar
->arNodeMap
[i
- 1].txPending
) {
1885 A_MEMZERO(&ar
->arNodeMap
[i
- 1], sizeof(struct ar_node_mapping
));
1894 /* Freeing a cookie should not be contingent on either of */
1895 /* these flags, just if we have a cookie or not. */
1896 /* Can we even get here without a cookie? Fix later. */
1897 if (ar
->arWmiReady
== TRUE
|| (bypasswmi
))
1899 ar6000_free_cookie(ar
, cookie
);
1902 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1904 /* lock is released, we can freely call other kernel APIs */
1906 /* this indirectly frees the HTC_PACKET */
1915 * Receive event handler. This is called by HTC when a packet is received
1919 ar6000_rx(void *Context
, HTC_PACKET
*pPacket
)
1921 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Context
;
1922 struct sk_buff
*skb
= (struct sk_buff
*)pPacket
->pPktContext
;
1924 A_STATUS status
= pPacket
->Status
;
1925 WMI_PRI_STREAM_ID streamID
= arEndpoint2WMIStreamID(ar
,pPacket
->Endpoint
);
1926 HTC_ENDPOINT_ID ept
= pPacket
->Endpoint
;
1928 A_ASSERT((status
!= A_OK
) || (pPacket
->pBuffer
== (A_NETBUF_DATA(skb
) + HTC_HEADER_LEN
)));
1930 AR_DEBUG2_PRINTF("ar6000_rx ar=0x%x sid=%d, skb=0x%x, data=0x%x, len=0x%x ",
1931 (A_UINT32
)ar
, streamID
, (A_UINT32
)skb
, (A_UINT32
)pPacket
->pBuffer
,
1932 pPacket
->ActualLength
);
1933 if (status
!= A_OK
) {
1934 AR_DEBUG2_PRINTF("ERR\n");
1936 AR_DEBUG2_PRINTF("OK\n");
1939 /* take lock to protect buffer counts
1940 * and adaptive power throughput state */
1941 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1943 ar
->arRxBuffers
[streamID
]--;
1945 if (A_SUCCESS(status
)) {
1946 AR6000_STAT_INC(ar
, rx_packets
);
1947 ar
->arNetStats
.rx_bytes
+= pPacket
->ActualLength
;
1948 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1949 aptcTR
.bytesReceived
+= a_netbuf_to_len(skb
);
1950 applyAPTCHeuristics(ar
);
1951 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1953 A_NETBUF_PUT(skb
, pPacket
->ActualLength
+ HTC_HEADER_LEN
);
1954 A_NETBUF_PULL(skb
, HTC_HEADER_LEN
);
1957 if (debugdriver
>= 2) {
1958 ar6000_dump_skb(skb
);
1963 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1965 if (status
!= A_OK
) {
1966 AR6000_STAT_INC(ar
, rx_errors
);
1968 } else if (ar
->arWmiEnabled
== TRUE
) {
1969 if (streamID
== WMI_CONTROL_PRI
) {
1971 * this is a wmi control msg
1973 wmi_control_rx(ar
->arWmi
, skb
);
1975 WMI_DATA_HDR
*dhdr
= (WMI_DATA_HDR
*)A_NETBUF_DATA(skb
);
1976 if (WMI_DATA_HDR_IS_MSG_TYPE(dhdr
, CNTL_MSGTYPE
)) {
1978 * this is a wmi control msg
1980 /* strip off WMI hdr */
1981 wmi_data_hdr_remove(ar
->arWmi
, skb
);
1982 wmi_control_rx(ar
->arWmi
, skb
);
1985 * this is a wmi data packet
1987 minHdrLen
= sizeof (WMI_DATA_HDR
) + sizeof(ATH_MAC_HDR
) +
1988 sizeof(ATH_LLC_SNAP_HDR
);
1990 if ((pPacket
->ActualLength
< minHdrLen
) ||
1991 (pPacket
->ActualLength
> AR6000_BUFFER_SIZE
))
1994 * packet is too short or too long
1996 AR_DEBUG_PRINTF("TOO SHORT or TOO LONG\n");
1997 AR6000_STAT_INC(ar
, rx_errors
);
1998 AR6000_STAT_INC(ar
, rx_length_errors
);
2001 if (ar
->arWmmEnabled
) {
2002 wmi_implicit_create_pstream(ar
->arWmi
, skb
,
2003 DNLINK_TRAFFIC
, UNDEFINED_PRI
);
2006 /* Access RSSI values here */
2007 AR_DEBUG_PRINTF("RSSI %d\n",
2008 ((WMI_DATA_HDR
*) A_NETBUF_DATA(skb
))->rssi
);
2010 wmi_data_hdr_remove(ar
->arWmi
, skb
);
2011 wmi_dot3_2_dix(ar
->arWmi
, skb
);
2013 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
2015 * extra push and memcpy, for eth_type_trans() of 2.4 kernel
2016 * will pull out hard_header_len bytes of the skb.
2018 A_NETBUF_PUSH(skb
, sizeof(WMI_DATA_HDR
) + sizeof(ATH_LLC_SNAP_HDR
) + HTC_HEADER_LEN
);
2019 A_MEMCPY(A_NETBUF_DATA(skb
), A_NETBUF_DATA(skb
) + sizeof(WMI_DATA_HDR
) +
2020 sizeof(ATH_LLC_SNAP_HDR
) + HTC_HEADER_LEN
, sizeof(ATH_MAC_HDR
));
2022 if ((ar
->arNetDev
->flags
& IFF_UP
) == IFF_UP
)
2024 skb
->dev
= ar
->arNetDev
;
2025 skb
->protocol
= eth_type_trans(skb
, ar
->arNetDev
);
2036 if ((ar
->arNetDev
->flags
& IFF_UP
) == IFF_UP
)
2038 skb
->dev
= ar
->arNetDev
;
2039 skb
->protocol
= eth_type_trans(skb
, ar
->arNetDev
);
2048 if (status
!= A_ECANCELED
) {
2050 * HTC provides A_ECANCELED status when it doesn't want to be refilled
2051 * (probably due to a shutdown)
2053 ar6000_rx_refill(Context
, ept
);
2060 ar6000_rx_refill(void *Context
, HTC_ENDPOINT_ID Endpoint
)
2062 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Context
;
2065 int buffersToRefill
;
2066 HTC_PACKET
*pPacket
;
2067 WMI_PRI_STREAM_ID streamId
= arEndpoint2WMIStreamID(ar
,Endpoint
);
2069 buffersToRefill
= (int)AR6000_MAX_RX_BUFFERS
-
2070 (int)ar
->arRxBuffers
[streamId
];
2072 if (buffersToRefill
<= 0) {
2073 /* fast return, nothing to fill */
2077 AR_DEBUG2_PRINTF("ar6000_rx_refill: providing htc with %d buffers at eid=%d\n",
2078 buffersToRefill
, Endpoint
);
2080 for (RxBuffers
= 0; RxBuffers
< buffersToRefill
; RxBuffers
++) {
2081 osBuf
= A_NETBUF_ALLOC(AR6000_BUFFER_SIZE
);
2082 if (NULL
== osBuf
) {
2085 /* the HTC packet wrapper is at the head of the reserved area
2087 pPacket
= (HTC_PACKET
*)(A_NETBUF_HEAD(osBuf
));
2088 /* set re-fill info */
2089 SET_HTC_PACKET_INFO_RX_REFILL(pPacket
,osBuf
,A_NETBUF_DATA(osBuf
),AR6000_BUFFER_SIZE
,Endpoint
);
2090 /* add this packet */
2091 HTCAddReceivePkt(ar
->arHtcTarget
, pPacket
);
2095 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
2096 ar
->arRxBuffers
[streamId
] += RxBuffers
;
2097 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
2100 static struct net_device_stats
*
2101 ar6000_get_stats(struct net_device
*dev
)
2103 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
2104 return &ar
->arNetStats
;
2107 static struct iw_statistics
*
2108 ar6000_get_iwstats(struct net_device
* dev
)
2110 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
2111 TARGET_STATS
*pStats
= &ar
->arTargetStats
;
2112 struct iw_statistics
* pIwStats
= &ar
->arIwStats
;
2114 if ((ar
->arWmiReady
== FALSE
)
2116 * The in_atomic function is used to determine if the scheduling is
2117 * allowed in the current context or not. This was introduced in 2.6
2118 * From what I have read on the differences between 2.4 and 2.6, the
2119 * 2.4 kernel did not support preemption and so this check might not
2120 * be required for 2.4 kernels.
2122 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
2127 pIwStats
->status
= 0;
2128 pIwStats
->qual
.qual
= 0;
2129 pIwStats
->qual
.level
=0;
2130 pIwStats
->qual
.noise
= 0;
2131 pIwStats
->discard
.code
=0;
2132 pIwStats
->discard
.retries
=0;
2133 pIwStats
->miss
.beacon
=0;
2136 if (down_interruptible(&ar
->arSem
)) {
2137 pIwStats
->status
= 0;
2142 ar
->statsUpdatePending
= TRUE
;
2144 if(wmi_get_stats_cmd(ar
->arWmi
) != A_OK
) {
2146 pIwStats
->status
= 0;
2150 wait_event_interruptible_timeout(arEvent
, ar
->statsUpdatePending
== FALSE
, wmitimeout
* HZ
);
2152 if (signal_pending(current
)) {
2153 AR_DEBUG_PRINTF("ar6000 : WMI get stats timeout \n");
2155 pIwStats
->status
= 0;
2158 pIwStats
->status
= 1 ;
2159 pIwStats
->qual
.qual
= pStats
->cs_aveBeacon_rssi
;
2160 pIwStats
->qual
.level
=pStats
->cs_aveBeacon_rssi
+ 161; /* noise is -95 dBm */
2161 pIwStats
->qual
.noise
= pStats
->noise_floor_calibation
;
2162 pIwStats
->discard
.code
= pStats
->rx_decrypt_err
;
2163 pIwStats
->discard
.retries
= pStats
->tx_retry_cnt
;
2164 pIwStats
->miss
.beacon
= pStats
->cs_bmiss_cnt
;
2170 ar6000_ready_event(void *devt
, A_UINT8
*datap
, A_UINT8 phyCap
)
2172 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
2173 struct net_device
*dev
= ar
->arNetDev
;
2175 ar
->arWmiReady
= TRUE
;
2177 A_MEMCPY(dev
->dev_addr
, datap
, AR6000_ETH_ADDR_LEN
);
2178 AR_DEBUG_PRINTF("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
2179 dev
->dev_addr
[0], dev
->dev_addr
[1],
2180 dev
->dev_addr
[2], dev
->dev_addr
[3],
2181 dev
->dev_addr
[4], dev
->dev_addr
[5]);
2183 ar
->arPhyCapability
= phyCap
;
2187 ar6000_iptos_to_userPriority(A_UINT8
*pkt
)
2189 struct iphdr
*ipHdr
= (struct iphdr
*)pkt
;
2190 A_UINT8 userPriority
;
2194 * (Refer Pg 57 WMM-test-plan-v1.2)
2196 * : DSCP(6-bits) ECN(2-bits)
2197 * : DSCP - P2 P1 P0 X X X
2198 * where (P2 P1 P0) form 802.1D
2200 userPriority
= ipHdr
->tos
>> 5;
2201 return (userPriority
& 0x7);
2205 ar6000_connect_event(AR_SOFTC_T
*ar
, A_UINT16 channel
, A_UINT8
*bssid
,
2206 A_UINT16 listenInterval
, A_UINT16 beaconInterval
,
2207 NETWORK_TYPE networkType
, A_UINT8 beaconIeLen
,
2208 A_UINT8 assocReqLen
, A_UINT8 assocRespLen
,
2211 union iwreq_data wrqu
;
2212 int i
, beacon_ie_pos
, assoc_resp_ie_pos
, assoc_req_ie_pos
;
2213 static const char *tag1
= "ASSOCINFO(ReqIEs=";
2214 static const char *tag2
= "ASSOCRESPIE=";
2215 static const char *beaconIetag
= "BEACONIE=";
2216 char buf
[WMI_CONTROL_MSG_MAX_LEN
* 2 + sizeof(tag1
)];
2218 A_UINT8 key_op_ctrl
;
2220 A_MEMCPY(ar
->arBssid
, bssid
, sizeof(ar
->arBssid
));
2221 ar
->arBssChannel
= channel
;
2223 A_PRINTF("AR6000 connected event on freq %d ", channel
);
2224 A_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
2225 " listenInterval=%d, beaconInterval = %d, beaconIeLen = %d assocReqLen=%d"
2226 " assocRespLen =%d\n",
2227 bssid
[0], bssid
[1], bssid
[2],
2228 bssid
[3], bssid
[4], bssid
[5],
2229 listenInterval
, beaconInterval
,
2230 beaconIeLen
, assocReqLen
, assocRespLen
);
2231 if (networkType
& ADHOC_NETWORK
) {
2232 if (networkType
& ADHOC_CREATOR
) {
2233 A_PRINTF("Network: Adhoc (Creator)\n");
2235 A_PRINTF("Network: Adhoc (Joiner)\n");
2238 A_PRINTF("Network: Infrastructure\n");
2241 if (beaconIeLen
&& (sizeof(buf
) > (9 + beaconIeLen
* 2))) {
2242 AR_DEBUG_PRINTF("\nBeaconIEs= ");
2245 A_MEMZERO(buf
, sizeof(buf
));
2246 sprintf(buf
, "%s", beaconIetag
);
2248 for (i
= beacon_ie_pos
; i
< beacon_ie_pos
+ beaconIeLen
; i
++) {
2249 AR_DEBUG_PRINTF("%2.2x ", assocInfo
[i
]);
2250 sprintf(pos
, "%2.2x", assocInfo
[i
]);
2253 AR_DEBUG_PRINTF("\n");
2255 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2256 wrqu
.data
.length
= strlen(buf
);
2257 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2260 if (assocRespLen
&& (sizeof(buf
) > (12 + (assocRespLen
* 2))))
2262 assoc_resp_ie_pos
= beaconIeLen
+ assocReqLen
+
2263 sizeof(A_UINT16
) + /* capinfo*/
2264 sizeof(A_UINT16
) + /* status Code */
2265 sizeof(A_UINT16
) ; /* associd */
2266 A_MEMZERO(buf
, sizeof(buf
));
2267 sprintf(buf
, "%s", tag2
);
2269 AR_DEBUG_PRINTF("\nAssocRespIEs= ");
2271 * The Association Response Frame w.o. the WLAN header is delivered to
2272 * the host, so skip over to the IEs
2274 for (i
= assoc_resp_ie_pos
; i
< assoc_resp_ie_pos
+ assocRespLen
- 6; i
++)
2276 AR_DEBUG_PRINTF("%2.2x ", assocInfo
[i
]);
2277 sprintf(pos
, "%2.2x", assocInfo
[i
]);
2280 AR_DEBUG_PRINTF("\n");
2282 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2283 wrqu
.data
.length
= strlen(buf
);
2284 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2287 if (assocReqLen
&& (sizeof(buf
) > (17 + (assocReqLen
* 2)))) {
2289 * assoc Request includes capability and listen interval. Skip these.
2291 assoc_req_ie_pos
= beaconIeLen
+
2292 sizeof(A_UINT16
) + /* capinfo*/
2293 sizeof(A_UINT16
); /* listen interval */
2295 A_MEMZERO(buf
, sizeof(buf
));
2296 sprintf(buf
, "%s", tag1
);
2298 AR_DEBUG_PRINTF("AssocReqIEs= ");
2299 for (i
= assoc_req_ie_pos
; i
< assoc_req_ie_pos
+ assocReqLen
- 4; i
++) {
2300 AR_DEBUG_PRINTF("%2.2x ", assocInfo
[i
]);
2301 sprintf(pos
, "%2.2x", assocInfo
[i
]);
2304 AR_DEBUG_PRINTF("\n");
2306 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2307 wrqu
.data
.length
= strlen(buf
);
2308 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2312 if (ar
->user_savedkeys_stat
== USER_SAVEDKEYS_STAT_RUN
&&
2313 ar
->user_saved_keys
.keyOk
== TRUE
)
2316 key_op_ctrl
= KEY_OP_VALID_MASK
& ~KEY_OP_INIT_TSC
;
2317 if (ar
->user_key_ctrl
& AR6000_USER_SETKEYS_RSC_UNCHANGED
) {
2318 key_op_ctrl
&= ~KEY_OP_INIT_RSC
;
2320 key_op_ctrl
|= KEY_OP_INIT_RSC
;
2322 ar6000_reinstall_keys(ar
, key_op_ctrl
);
2324 #endif /* USER_KEYS */
2326 /* flush data queues */
2327 ar6000_TxDataCleanup(ar
);
2329 netif_start_queue(ar
->arNetDev
);
2331 if ((OPEN_AUTH
== ar
->arDot11AuthMode
) &&
2332 (NONE_AUTH
== ar
->arAuthMode
) &&
2333 (WEP_CRYPT
== ar
->arPairwiseCrypto
))
2335 if (!ar
->arConnected
) {
2336 ar6000_install_static_wep_keys(ar
);
2340 ar
->arConnected
= TRUE
;
2341 ar
->arConnectPending
= FALSE
;
2345 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2346 A_MEMCPY(wrqu
.addr
.sa_data
, bssid
, IEEE80211_ADDR_LEN
);
2347 wrqu
.addr
.sa_family
= ARPHRD_ETHER
;
2348 wireless_send_event(ar
->arNetDev
, SIOCGIWAP
, &wrqu
, NULL
);
2349 if ((ar
->arNetworkType
== ADHOC_NETWORK
) && ar
->arIbssPsEnable
) {
2350 A_MEMZERO(ar
->arNodeMap
, sizeof(ar
->arNodeMap
));
2352 ar
->arNexEpId
= ENDPOINT_2
;
2357 void ar6000_set_numdataendpts(AR_SOFTC_T
*ar
, A_UINT32 num
)
2359 A_ASSERT(num
<= (HTC_MAILBOX_NUM_MAX
- 1));
2360 ar
->arNumDataEndPts
= num
;
2364 ar6000_disconnect_event(AR_SOFTC_T
*ar
, A_UINT8 reason
, A_UINT8
*bssid
,
2365 A_UINT8 assocRespLen
, A_UINT8
*assocInfo
, A_UINT16 protocolReasonStatus
)
2369 A_PRINTF("AR6000 disconnected");
2370 if (bssid
[0] || bssid
[1] || bssid
[2] || bssid
[3] || bssid
[4] || bssid
[5]) {
2371 A_PRINTF(" from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
2372 bssid
[0], bssid
[1], bssid
[2], bssid
[3], bssid
[4], bssid
[5]);
2376 AR_DEBUG_PRINTF("\nDisconnect Reason is %d", reason
);
2377 AR_DEBUG_PRINTF("\nProtocol Reason/Status Code is %d", protocolReasonStatus
);
2378 AR_DEBUG_PRINTF("\nAssocResp Frame = %s",
2379 assocRespLen
? " " : "NULL");
2380 for (i
= 0; i
< assocRespLen
; i
++) {
2382 AR_DEBUG_PRINTF("\n");
2384 AR_DEBUG_PRINTF("%2.2x ", assocInfo
[i
]);
2386 AR_DEBUG_PRINTF("\n");
2388 * If the event is due to disconnect cmd from the host, only they the target
2389 * would stop trying to connect. Under any other condition, target would
2390 * keep trying to connect.
2393 if( reason
== DISCONNECT_CMD
)
2395 ar
->arConnectPending
= FALSE
;
2397 ar
->arConnectPending
= TRUE
;
2398 if (((reason
== ASSOC_FAILED
) && (protocolReasonStatus
== 0x11)) ||
2399 ((reason
== ASSOC_FAILED
) && (protocolReasonStatus
== 0x0) && (reconnect_flag
== 1))) {
2400 ar
->arConnected
= TRUE
;
2404 ar
->arConnected
= FALSE
;
2406 if( (reason
!= CSERV_DISCONNECT
) || (reconnect_flag
!= 1) ) {
2411 if (reason
!= CSERV_DISCONNECT
)
2413 ar
->user_savedkeys_stat
= USER_SAVEDKEYS_STAT_INIT
;
2414 ar
->user_key_ctrl
= 0;
2416 #endif /* USER_KEYS */
2418 netif_stop_queue(ar
->arNetDev
);
2419 A_MEMZERO(ar
->arBssid
, sizeof(ar
->arBssid
));
2420 ar
->arBssChannel
= 0;
2421 ar
->arBeaconInterval
= 0;
2423 ar6000_TxDataCleanup(ar
);
2427 ar6000_regDomain_event(AR_SOFTC_T
*ar
, A_UINT32 regCode
)
2429 A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode
);
2430 ar
->arRegCode
= regCode
;
2434 ar6000_neighborReport_event(AR_SOFTC_T
*ar
, int numAps
, WMI_NEIGHBOR_INFO
*info
)
2436 static const char *tag
= "PRE-AUTH";
2438 union iwreq_data wrqu
;
2441 AR_DEBUG_PRINTF("AR6000 Neighbor Report Event\n");
2442 for (i
=0; i
< numAps
; info
++, i
++) {
2443 AR_DEBUG_PRINTF("bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
2444 info
->bssid
[0], info
->bssid
[1], info
->bssid
[2],
2445 info
->bssid
[3], info
->bssid
[4], info
->bssid
[5]);
2446 if (info
->bssFlags
& WMI_PREAUTH_CAPABLE_BSS
) {
2447 AR_DEBUG_PRINTF("preauth-cap");
2449 if (info
->bssFlags
& WMI_PMKID_VALID_BSS
) {
2450 AR_DEBUG_PRINTF(" pmkid-valid\n");
2451 continue; /* we skip bss if the pmkid is already valid */
2453 AR_DEBUG_PRINTF("\n");
2454 snprintf(buf
, sizeof(buf
), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
2456 info
->bssid
[0], info
->bssid
[1], info
->bssid
[2],
2457 info
->bssid
[3], info
->bssid
[4], info
->bssid
[5],
2459 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2460 wrqu
.data
.length
= strlen(buf
);
2461 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2466 ar6000_tkip_micerr_event(AR_SOFTC_T
*ar
, A_UINT8 keyid
, A_BOOL ismcast
)
2468 static const char *tag
= "MLME-MICHAELMICFAILURE.indication";
2470 union iwreq_data wrqu
;
2472 A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n",
2473 keyid
, ismcast
? "multi": "uni");
2474 snprintf(buf
, sizeof(buf
), "%s(keyid=%d %scat)", tag
, keyid
,
2475 ismcast
? "multi" : "uni");
2476 memset(&wrqu
, 0, sizeof(wrqu
));
2477 wrqu
.data
.length
= strlen(buf
);
2478 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2482 ar6000_scanComplete_event(AR_SOFTC_T
*ar
, A_STATUS status
)
2484 AR_DEBUG_PRINTF("AR6000 scan complete: %d\n", status
);
2486 ar
->scan_complete
= 1;
2487 wake_up_interruptible(&ar6000_scan_queue
);
2491 ar6000_targetStats_event(AR_SOFTC_T
*ar
, WMI_TARGET_STATS
*pTarget
)
2493 TARGET_STATS
*pStats
= &ar
->arTargetStats
;
2496 /*A_PRINTF("AR6000 updating target stats\n");*/
2497 pStats
->tx_packets
+= pTarget
->txrxStats
.tx_stats
.tx_packets
;
2498 pStats
->tx_bytes
+= pTarget
->txrxStats
.tx_stats
.tx_bytes
;
2499 pStats
->tx_unicast_pkts
+= pTarget
->txrxStats
.tx_stats
.tx_unicast_pkts
;
2500 pStats
->tx_unicast_bytes
+= pTarget
->txrxStats
.tx_stats
.tx_unicast_bytes
;
2501 pStats
->tx_multicast_pkts
+= pTarget
->txrxStats
.tx_stats
.tx_multicast_pkts
;
2502 pStats
->tx_multicast_bytes
+= pTarget
->txrxStats
.tx_stats
.tx_multicast_bytes
;
2503 pStats
->tx_broadcast_pkts
+= pTarget
->txrxStats
.tx_stats
.tx_broadcast_pkts
;
2504 pStats
->tx_broadcast_bytes
+= pTarget
->txrxStats
.tx_stats
.tx_broadcast_bytes
;
2505 pStats
->tx_rts_success_cnt
+= pTarget
->txrxStats
.tx_stats
.tx_rts_success_cnt
;
2506 for(ac
= 0; ac
< WMM_NUM_AC
; ac
++)
2507 pStats
->tx_packet_per_ac
[ac
] += pTarget
->txrxStats
.tx_stats
.tx_packet_per_ac
[ac
];
2508 pStats
->tx_errors
+= pTarget
->txrxStats
.tx_stats
.tx_errors
;
2509 pStats
->tx_failed_cnt
+= pTarget
->txrxStats
.tx_stats
.tx_failed_cnt
;
2510 pStats
->tx_retry_cnt
+= pTarget
->txrxStats
.tx_stats
.tx_retry_cnt
;
2511 pStats
->tx_rts_fail_cnt
+= pTarget
->txrxStats
.tx_stats
.tx_rts_fail_cnt
;
2512 pStats
->tx_unicast_rate
= wmi_get_rate(pTarget
->txrxStats
.tx_stats
.tx_unicast_rate
);
2514 pStats
->rx_packets
+= pTarget
->txrxStats
.rx_stats
.rx_packets
;
2515 pStats
->rx_bytes
+= pTarget
->txrxStats
.rx_stats
.rx_bytes
;
2516 pStats
->rx_unicast_pkts
+= pTarget
->txrxStats
.rx_stats
.rx_unicast_pkts
;
2517 pStats
->rx_unicast_bytes
+= pTarget
->txrxStats
.rx_stats
.rx_unicast_bytes
;
2518 pStats
->rx_multicast_pkts
+= pTarget
->txrxStats
.rx_stats
.rx_multicast_pkts
;
2519 pStats
->rx_multicast_bytes
+= pTarget
->txrxStats
.rx_stats
.rx_multicast_bytes
;
2520 pStats
->rx_broadcast_pkts
+= pTarget
->txrxStats
.rx_stats
.rx_broadcast_pkts
;
2521 pStats
->rx_broadcast_bytes
+= pTarget
->txrxStats
.rx_stats
.rx_broadcast_bytes
;
2522 pStats
->rx_fragment_pkt
+= pTarget
->txrxStats
.rx_stats
.rx_fragment_pkt
;
2523 pStats
->rx_errors
+= pTarget
->txrxStats
.rx_stats
.rx_errors
;
2524 pStats
->rx_crcerr
+= pTarget
->txrxStats
.rx_stats
.rx_crcerr
;
2525 pStats
->rx_key_cache_miss
+= pTarget
->txrxStats
.rx_stats
.rx_key_cache_miss
;
2526 pStats
->rx_decrypt_err
+= pTarget
->txrxStats
.rx_stats
.rx_decrypt_err
;
2527 pStats
->rx_duplicate_frames
+= pTarget
->txrxStats
.rx_stats
.rx_duplicate_frames
;
2528 pStats
->rx_unicast_rate
= wmi_get_rate(pTarget
->txrxStats
.rx_stats
.rx_unicast_rate
);
2531 pStats
->tkip_local_mic_failure
2532 += pTarget
->txrxStats
.tkipCcmpStats
.tkip_local_mic_failure
;
2533 pStats
->tkip_counter_measures_invoked
2534 += pTarget
->txrxStats
.tkipCcmpStats
.tkip_counter_measures_invoked
;
2535 pStats
->tkip_replays
+= pTarget
->txrxStats
.tkipCcmpStats
.tkip_replays
;
2536 pStats
->tkip_format_errors
+= pTarget
->txrxStats
.tkipCcmpStats
.tkip_format_errors
;
2537 pStats
->ccmp_format_errors
+= pTarget
->txrxStats
.tkipCcmpStats
.ccmp_format_errors
;
2538 pStats
->ccmp_replays
+= pTarget
->txrxStats
.tkipCcmpStats
.ccmp_replays
;
2541 pStats
->power_save_failure_cnt
+= pTarget
->pmStats
.power_save_failure_cnt
;
2542 pStats
->noise_floor_calibation
= pTarget
->noise_floor_calibation
;
2544 pStats
->cs_bmiss_cnt
+= pTarget
->cservStats
.cs_bmiss_cnt
;
2545 pStats
->cs_lowRssi_cnt
+= pTarget
->cservStats
.cs_lowRssi_cnt
;
2546 pStats
->cs_connect_cnt
+= pTarget
->cservStats
.cs_connect_cnt
;
2547 pStats
->cs_disconnect_cnt
+= pTarget
->cservStats
.cs_disconnect_cnt
;
2548 pStats
->cs_aveBeacon_snr
= pTarget
->cservStats
.cs_aveBeacon_snr
;
2549 pStats
->cs_aveBeacon_rssi
= pTarget
->cservStats
.cs_aveBeacon_rssi
;
2550 pStats
->cs_lastRoam_msec
= pTarget
->cservStats
.cs_lastRoam_msec
;
2551 pStats
->cs_snr
= pTarget
->cservStats
.cs_snr
;
2552 pStats
->cs_rssi
= pTarget
->cservStats
.cs_rssi
;
2554 pStats
->lq_val
= pTarget
->lqVal
;
2556 pStats
->wow_num_pkts_dropped
+= pTarget
->wowStats
.wow_num_pkts_dropped
;
2557 pStats
->wow_num_host_pkt_wakeups
+= pTarget
->wowStats
.wow_num_host_pkt_wakeups
;
2558 pStats
->wow_num_host_event_wakeups
+= pTarget
->wowStats
.wow_num_host_event_wakeups
;
2559 pStats
->wow_num_events_discarded
+= pTarget
->wowStats
.wow_num_events_discarded
;
2561 ar
->statsUpdatePending
= FALSE
;
2566 ar6000_rssiThreshold_event(AR_SOFTC_T
*ar
, WMI_RSSI_THRESHOLD_VAL newThreshold
, A_INT16 rssi
)
2568 USER_RSSI_THOLD userRssiThold
;
2570 userRssiThold
.tag
= rssi_map
[newThreshold
].tag
;
2571 userRssiThold
.rssi
= rssi
;
2572 AR_DEBUG2_PRINTF("rssi Threshold range = %d tag = %d rssi = %d\n", newThreshold
, userRssiThold
.tag
, rssi
);
2573 #ifdef SEND_EVENT_TO_APP
2574 ar6000_send_event_to_app(ar
, WMI_RSSI_THRESHOLD_EVENTID
,(A_UINT8
*)&userRssiThold
, sizeof(USER_RSSI_THOLD
));
2580 ar6000_hbChallengeResp_event(AR_SOFTC_T
*ar
, A_UINT32 cookie
, A_UINT32 source
)
2582 if (source
== APP_HB_CHALLENGE
) {
2583 /* Report it to the app in case it wants a positive acknowledgement */
2584 #ifdef SEND_EVENT_TO_APP
2585 ar6000_send_event_to_app(ar
, WMIX_HB_CHALLENGE_RESP_EVENTID
,
2586 (A_UINT8
*)&cookie
, sizeof(cookie
));
2589 /* This would ignore the replys that come in after their due time */
2590 if (cookie
== ar
->arHBChallengeResp
.seqNum
) {
2591 ar
->arHBChallengeResp
.outstanding
= FALSE
;
2598 ar6000_reportError_event(AR_SOFTC_T
*ar
, WMI_TARGET_ERROR_VAL errorVal
)
2600 char *errString
[] = {
2601 [WMI_TARGET_PM_ERR_FAIL
] "WMI_TARGET_PM_ERR_FAIL",
2602 [WMI_TARGET_KEY_NOT_FOUND
] "WMI_TARGET_KEY_NOT_FOUND",
2603 [WMI_TARGET_DECRYPTION_ERR
] "WMI_TARGET_DECRYPTION_ERR",
2604 [WMI_TARGET_BMISS
] "WMI_TARGET_BMISS",
2605 [WMI_PSDISABLE_NODE_JOIN
] "WMI_PSDISABLE_NODE_JOIN"
2608 A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal
);
2610 /* One error is reported at a time, and errorval is a bitmask */
2611 if(errorVal
& (errorVal
- 1))
2614 A_PRINTF("AR6000 Error type = ");
2617 case WMI_TARGET_PM_ERR_FAIL
:
2618 case WMI_TARGET_KEY_NOT_FOUND
:
2619 case WMI_TARGET_DECRYPTION_ERR
:
2620 case WMI_TARGET_BMISS
:
2621 case WMI_PSDISABLE_NODE_JOIN
:
2622 A_PRINTF("%s\n", errString
[errorVal
]);
2625 A_PRINTF("INVALID\n");
2633 ar6000_cac_event(AR_SOFTC_T
*ar
, A_UINT8 ac
, A_UINT8 cacIndication
,
2634 A_UINT8 statusCode
, A_UINT8
*tspecSuggestion
)
2636 WMM_TSPEC_IE
*tspecIe
;
2639 * This is the TSPEC IE suggestion from AP.
2640 * Suggestion provided by AP under some error
2641 * cases, could be helpful for the host app.
2642 * Check documentation.
2644 tspecIe
= (WMM_TSPEC_IE
*)tspecSuggestion
;
2647 * What do we do, if we get TSPEC rejection? One thought
2648 * that comes to mind is implictly delete the pstream...
2650 A_PRINTF("AR6000 CAC notification. "
2651 "AC = %d, cacIndication = 0x%x, statusCode = 0x%x\n",
2652 ac
, cacIndication
, statusCode
);
2655 #define AR6000_PRINT_BSSID(_pBss) do { \
2656 A_PRINTF("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",\
2657 (_pBss)[0],(_pBss)[1],(_pBss)[2],(_pBss)[3],\
2658 (_pBss)[4],(_pBss)[5]); \
2662 ar6000_roam_tbl_event(AR_SOFTC_T
*ar
, WMI_TARGET_ROAM_TBL
*pTbl
)
2666 A_PRINTF("ROAM TABLE NO OF ENTRIES is %d ROAM MODE is %d\n",
2667 pTbl
->numEntries
, pTbl
->roamMode
);
2668 for (i
= 0; i
< pTbl
->numEntries
; i
++) {
2669 A_PRINTF("[%d]bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", i
,
2670 pTbl
->bssRoamInfo
[i
].bssid
[0], pTbl
->bssRoamInfo
[i
].bssid
[1],
2671 pTbl
->bssRoamInfo
[i
].bssid
[2],
2672 pTbl
->bssRoamInfo
[i
].bssid
[3],
2673 pTbl
->bssRoamInfo
[i
].bssid
[4],
2674 pTbl
->bssRoamInfo
[i
].bssid
[5]);
2675 A_PRINTF("RSSI %d RSSIDT %d LAST RSSI %d UTIL %d ROAM_UTIL %d"
2677 pTbl
->bssRoamInfo
[i
].rssi
,
2678 pTbl
->bssRoamInfo
[i
].rssidt
,
2679 pTbl
->bssRoamInfo
[i
].last_rssi
,
2680 pTbl
->bssRoamInfo
[i
].util
,
2681 pTbl
->bssRoamInfo
[i
].roam_util
,
2682 pTbl
->bssRoamInfo
[i
].bias
);
2687 ar6000_wow_list_event(struct ar6_softc
*ar
, A_UINT8 num_filters
, WMI_GET_WOW_LIST_REPLY
*wow_reply
)
2691 /*Each event now contains exactly one filter, see bug 26613*/
2692 A_PRINTF("WOW pattern %d of %d patterns\n", wow_reply
->this_filter_num
, wow_reply
->num_filters
);
2693 A_PRINTF("wow mode = %s host mode = %s\n",
2694 (wow_reply
->wow_mode
== 0? "disabled":"enabled"),
2695 (wow_reply
->host_mode
== 1 ? "awake":"asleep"));
2698 /*If there are no patterns, the reply will only contain generic
2699 WoW information. Pattern information will exist only if there are
2700 patterns present. Bug 26716*/
2702 /* If this event contains pattern information, display it*/
2703 if (wow_reply
->this_filter_num
) {
2705 A_PRINTF("id=%d size=%d offset=%d\n",
2706 wow_reply
->wow_filters
[i
].wow_filter_id
,
2707 wow_reply
->wow_filters
[i
].wow_filter_size
,
2708 wow_reply
->wow_filters
[i
].wow_filter_offset
);
2709 A_PRINTF("wow pattern = ");
2710 for (j
=0; j
< wow_reply
->wow_filters
[i
].wow_filter_size
; j
++) {
2711 A_PRINTF("%2.2x",wow_reply
->wow_filters
[i
].wow_filter_pattern
[j
]);
2714 A_PRINTF("\nwow mask = ");
2715 for (j
=0; j
< wow_reply
->wow_filters
[i
].wow_filter_size
; j
++) {
2716 A_PRINTF("%2.2x",wow_reply
->wow_filters
[i
].wow_filter_mask
[j
]);
2723 * Report the Roaming related data collected on the target
2726 ar6000_display_roam_time(WMI_TARGET_ROAM_TIME
*p
)
2728 A_PRINTF("Disconnect Data : BSSID: ");
2729 AR6000_PRINT_BSSID(p
->disassoc_bssid
);
2730 A_PRINTF(" RSSI %d DISASSOC Time %d NO_TXRX_TIME %d\n",
2731 p
->disassoc_bss_rssi
,p
->disassoc_time
,
2733 A_PRINTF("Connect Data: BSSID: ");
2734 AR6000_PRINT_BSSID(p
->assoc_bssid
);
2735 A_PRINTF(" RSSI %d ASSOC Time %d TXRX_TIME %d\n",
2736 p
->assoc_bss_rssi
,p
->assoc_time
,
2737 p
->allow_txrx_time
);
2738 A_PRINTF("Last Data Tx Time (b4 Disassoc) %d "\
2739 "First Data Tx Time (after Assoc) %d\n",
2740 p
->last_data_txrx_time
, p
->first_data_txrx_time
);
2744 ar6000_roam_data_event(AR_SOFTC_T
*ar
, WMI_TARGET_ROAM_DATA
*p
)
2746 switch (p
->roamDataType
) {
2747 case ROAM_DATA_TIME
:
2748 ar6000_display_roam_time(&p
->u
.roamTime
);
2756 ar6000_bssInfo_event_rx(AR_SOFTC_T
*ar
, A_UINT8
*datap
, int len
)
2758 struct sk_buff
*skb
;
2759 WMI_BSS_INFO_HDR
*bih
= (WMI_BSS_INFO_HDR
*)datap
;
2762 if (!ar
->arMgmtFilter
) {
2765 if (((ar
->arMgmtFilter
& IEEE80211_FILTER_TYPE_BEACON
) &&
2766 (bih
->frameType
!= BEACON_FTYPE
)) ||
2767 ((ar
->arMgmtFilter
& IEEE80211_FILTER_TYPE_PROBE_RESP
) &&
2768 (bih
->frameType
!= PROBERESP_FTYPE
)))
2773 if ((skb
= A_NETBUF_ALLOC_RAW(len
)) != NULL
) {
2775 A_NETBUF_PUT(skb
, len
);
2776 A_MEMCPY(A_NETBUF_DATA(skb
), datap
, len
);
2777 skb
->dev
= ar
->arNetDev
;
2778 printk("MAC RAW...\n");
2779 // skb->mac.raw = A_NETBUF_DATA(skb);
2780 skb
->ip_summed
= CHECKSUM_NONE
;
2781 skb
->pkt_type
= PACKET_OTHERHOST
;
2782 skb
->protocol
= __constant_htons(0x0019);
2787 A_UINT32 wmiSendCmdNum
;
2790 ar6000_control_tx(void *devt
, void *osbuf
, WMI_PRI_STREAM_ID streamID
)
2792 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
2793 A_STATUS status
= A_OK
;
2794 struct ar_cookie
*cookie
= NULL
;
2797 /* take lock to protect ar6000_alloc_cookie() */
2798 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
2802 AR_DEBUG2_PRINTF("ar_contrstatus = ol_tx: skb=0x%x, len=0x%x, sid=%d\n",
2803 (A_UINT32
)osbuf
, A_NETBUF_LEN(osbuf
), streamID
);
2805 if ((streamID
== WMI_CONTROL_PRI
) && (ar
->arWMIControlEpFull
)) {
2806 /* control endpoint is full, don't allocate resources, we
2807 * are just going to drop this packet */
2809 AR_DEBUG_PRINTF(" WMI Control EP full, dropping packet : 0x%X, len:%d \n",
2810 (A_UINT32
)osbuf
, A_NETBUF_LEN(osbuf
));
2812 cookie
= ar6000_alloc_cookie(ar
);
2815 if (cookie
== NULL
) {
2816 status
= A_NO_MEMORY
;
2821 A_PRINTF("WMI cmd send, msgNo %d :", wmiSendCmdNum
);
2822 for(i
= 0; i
< a_netbuf_to_len(osbuf
); i
++)
2823 A_PRINTF("%x ", ((A_UINT8
*)a_netbuf_to_data(osbuf
))[i
]);
2831 if (cookie
!= NULL
) {
2832 /* got a structure to send it out on */
2833 ar
->arTxPending
[streamID
]++;
2835 if (streamID
!= WMI_CONTROL_PRI
) {
2836 ar
->arTotalTxDataPending
++;
2840 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
2842 if (cookie
!= NULL
) {
2843 cookie
->arc_bp
[0] = (A_UINT32
)osbuf
;
2844 cookie
->arc_bp
[1] = 0;
2845 SET_HTC_PACKET_INFO_TX(&cookie
->HtcPkt
,
2847 A_NETBUF_DATA(osbuf
),
2848 A_NETBUF_LEN(osbuf
),
2849 arWMIStream2EndpointID(ar
,streamID
),
2850 AR6K_CONTROL_PKT_TAG
);
2851 /* this interface is asynchronous, if there is an error, cleanup will happen in the
2852 * TX completion callback */
2853 HTCSendPkt(ar
->arHtcTarget
, &cookie
->HtcPkt
);
2860 /* indicate tx activity or inactivity on a WMI stream */
2861 void ar6000_indicate_tx_activity(void *devt
, A_UINT8 TrafficClass
, A_BOOL Active
)
2863 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
2864 WMI_PRI_STREAM_ID streamid
;
2866 if (ar
->arWmiEnabled
) {
2867 streamid
= wmi_get_stream_id(ar
->arWmi
, TrafficClass
);
2869 /* for mbox ping testing, the traffic class is mapped directly as a stream ID,
2870 * see handling of AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE in ioctl.c */
2871 streamid
= (WMI_PRI_STREAM_ID
)TrafficClass
;
2874 /* notify HTC, this may cause credit distribution changes */
2876 HTCIndicateActivityChange(ar
->arHtcTarget
,
2877 arWMIStream2EndpointID(ar
,streamid
),
2882 module_init(ar6000_init_module
);
2883 module_exit(ar6000_cleanup_module
);
2885 /* Init cookie queue */
2887 ar6000_cookie_init(AR_SOFTC_T
*ar
)
2891 ar
->arCookieList
= NULL
;
2892 A_MEMZERO(s_ar_cookie_mem
, sizeof(s_ar_cookie_mem
));
2894 for (i
= 0; i
< MAX_COOKIE_NUM
; i
++) {
2895 ar6000_free_cookie(ar
, &s_ar_cookie_mem
[i
]);
2899 /* cleanup cookie queue */
2901 ar6000_cookie_cleanup(AR_SOFTC_T
*ar
)
2903 /* It is gone .... */
2904 ar
->arCookieList
= NULL
;
2907 /* Init cookie queue */
2909 ar6000_free_cookie(AR_SOFTC_T
*ar
, struct ar_cookie
* cookie
)
2912 A_ASSERT(ar
!= NULL
);
2913 A_ASSERT(cookie
!= NULL
);
2914 cookie
->arc_list_next
= ar
->arCookieList
;
2915 ar
->arCookieList
= cookie
;
2918 /* cleanup cookie queue */
2919 static struct ar_cookie
*
2920 ar6000_alloc_cookie(AR_SOFTC_T
*ar
)
2922 struct ar_cookie
*cookie
;
2924 cookie
= ar
->arCookieList
;
2927 ar
->arCookieList
= cookie
->arc_list_next
;
2933 #ifdef SEND_EVENT_TO_APP
2935 * This function is used to send event which come from taget to
2936 * the application. The buf which send to application is include
2937 * the event ID and event content.
2939 #define EVENT_ID_LEN 2
2940 void ar6000_send_event_to_app(AR_SOFTC_T
*ar
, A_UINT16 eventId
,
2941 A_UINT8
*datap
, int len
)
2944 #if (WIRELESS_EXT >= 15)
2946 /* note: IWEVCUSTOM only exists in wireless extensions after version 15 */
2950 union iwreq_data wrqu
;
2952 size
= len
+ EVENT_ID_LEN
;
2954 if (size
> IW_CUSTOM_MAX
) {
2955 AR_DEBUG_PRINTF("WMI event ID : 0x%4.4X, len = %d too big for IWEVCUSTOM (max=%d) \n",
2956 eventId
, size
, IW_CUSTOM_MAX
);
2960 buf
= A_MALLOC_NOWAIT(size
);
2961 A_MEMZERO(buf
, size
);
2962 A_MEMCPY(buf
, &eventId
, EVENT_ID_LEN
);
2963 A_MEMCPY(buf
+EVENT_ID_LEN
, datap
, len
);
2965 //AR_DEBUG_PRINTF("event ID = %d,len = %d\n",*(A_UINT16*)buf, size);
2966 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2967 wrqu
.data
.length
= size
;
2968 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2979 ar6000_tx_retry_err_event(void *devt
)
2981 AR_DEBUG2_PRINTF("Tx retries reach maximum!\n");
2985 ar6000_snrThresholdEvent_rx(void *devt
, WMI_SNR_THRESHOLD_VAL newThreshold
, A_UINT8 snr
)
2987 AR_DEBUG2_PRINTF("snr threshold range %d, snr %d\n", newThreshold
, snr
);
2991 ar6000_lqThresholdEvent_rx(void *devt
, WMI_LQ_THRESHOLD_VAL newThreshold
, A_UINT8 lq
)
2993 AR_DEBUG2_PRINTF("lq threshold range %d, lq %d\n", newThreshold
, lq
);
2999 a_copy_to_user(void *to
, const void *from
, A_UINT32 n
)
3001 return(copy_to_user(to
, from
, n
));
3005 a_copy_from_user(void *to
, const void *from
, A_UINT32 n
)
3007 return(copy_from_user(to
, from
, n
));
3012 ar6000_get_driver_cfg(struct net_device
*dev
,
3021 case AR6000_DRIVER_CFG_GET_WLANNODECACHING
:
3022 *((A_UINT32
*)result
) = wlanNodeCaching
;
3024 case AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS
:
3025 *((A_UINT32
*)result
) = logWmiRawMsgs
;
3036 ar6000_keepalive_rx(void *devt
, A_UINT8 configured
)
3038 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
3040 ar
->arKeepaliveConfigured
= configured
;
3045 ar6000_pmkid_list_event(void *devt
, A_UINT8 numPMKID
, WMI_PMKID
*pmkidList
)
3049 A_PRINTF("Number of Cached PMKIDs is %d\n", numPMKID
);
3051 for (i
= 0; i
< numPMKID
; i
++) {
3052 A_PRINTF("\nPMKID %d ", i
);
3053 for (j
= 0; j
< WMI_PMKID_LEN
; j
++) {
3054 A_PRINTF("%2.2x", pmkidList
->pmkid
[j
]);
3063 ar6000_reinstall_keys(AR_SOFTC_T
*ar
, A_UINT8 key_op_ctrl
)
3065 A_STATUS status
= A_OK
;
3066 struct ieee80211req_key
*uik
= &ar
->user_saved_keys
.ucast_ik
;
3067 struct ieee80211req_key
*bik
= &ar
->user_saved_keys
.bcast_ik
;
3068 CRYPTO_TYPE keyType
= ar
->user_saved_keys
.keyType
;
3070 if (IEEE80211_CIPHER_CCKM_KRK
!= uik
->ik_type
) {
3071 if (NONE_CRYPT
== keyType
) {
3072 goto _reinstall_keys_out
;
3075 if (uik
->ik_keylen
) {
3076 status
= wmi_addKey_cmd(ar
->arWmi
, uik
->ik_keyix
,
3077 ar
->user_saved_keys
.keyType
, PAIRWISE_USAGE
,
3078 uik
->ik_keylen
, (A_UINT8
*)&uik
->ik_keyrsc
,
3079 uik
->ik_keydata
, key_op_ctrl
, SYNC_BEFORE_WMIFLAG
);
3083 status
= wmi_add_krk_cmd(ar
->arWmi
, uik
->ik_keydata
);
3086 if (IEEE80211_CIPHER_CCKM_KRK
!= bik
->ik_type
) {
3087 if (NONE_CRYPT
== keyType
) {
3088 goto _reinstall_keys_out
;
3091 if (bik
->ik_keylen
) {
3092 status
= wmi_addKey_cmd(ar
->arWmi
, bik
->ik_keyix
,
3093 ar
->user_saved_keys
.keyType
, GROUP_USAGE
,
3094 bik
->ik_keylen
, (A_UINT8
*)&bik
->ik_keyrsc
,
3095 bik
->ik_keydata
, key_op_ctrl
, NO_SYNC_WMIFLAG
);
3098 status
= wmi_add_krk_cmd(ar
->arWmi
, bik
->ik_keydata
);
3101 _reinstall_keys_out
:
3102 ar
->user_savedkeys_stat
= USER_SAVEDKEYS_STAT_INIT
;
3103 ar
->user_key_ctrl
= 0;
3107 #endif /* USER_KEYS */
3111 ar6000_dset_open_req(
3114 A_UINT32 targHandle
,
3115 A_UINT32 targReplyFn
,
3116 A_UINT32 targReplyArg
)
3123 A_UINT32 access_cookie
)
3129 ar6000_dset_data_req(
3131 A_UINT32 accessCookie
,
3135 A_UINT32 targReplyFn
,
3136 A_UINT32 targReplyArg
)