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 void ar6000_init_control_info(AR_SOFTC_T
*ar
);
217 static int ar6000_data_tx(struct sk_buff
*skb
, struct net_device
*dev
);
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
);
225 * HTC service connection handlers
227 static void ar6000_avail_ev(HTC_HANDLE HTCHandle
);
229 static void ar6000_unavail_ev(void *Instance
);
231 static void ar6000_target_failure(void *Instance
, A_STATUS Status
);
233 static void ar6000_rx(void *Context
, HTC_PACKET
*pPacket
);
235 static void ar6000_rx_refill(void *Context
,HTC_ENDPOINT_ID Endpoint
);
237 static void ar6000_tx_complete(void *Context
, HTC_PACKET
*pPacket
);
239 static void ar6000_tx_queue_full(void *Context
, HTC_ENDPOINT_ID Endpoint
);
241 static void ar6000_tx_queue_avail(void *Context
, HTC_ENDPOINT_ID Endpoint
);
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
);
257 static A_STATUS
ar6000_reinstall_keys(AR_SOFTC_T
*ar
,A_UINT8 key_op_ctrl
);
261 static struct ar_cookie s_ar_cookie_mem
[MAX_COOKIE_NUM
];
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))
269 /* Debug log support */
272 * Flag to govern whether the debug logs should be parsed in the kernel
273 * or reported to the application.
276 #define REPORT_DEBUG_LOGS_TO_APP
280 ar6000_set_host_app_area(AR_SOFTC_T
*ar
)
282 A_UINT32 address
, data
;
283 struct host_app_area_s host_app_area
;
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
) {
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
)
303 dbglog_get_debug_hdr_ptr(AR_SOFTC_T
*ar
)
309 address
= HOST_INTEREST_ITEM_ADDRESS(ar
, hi_dbglog_hdr
);
310 if ((status
= ar6000_ReadDataDiag(ar
->arHifDevice
, address
,
311 (A_UCHAR
*)¶m
, 4)) != A_OK
)
320 * The dbglog module has been initialized. Its ok to access the relevant
321 * data stuctures over the diagnostic window.
324 ar6000_dbglog_init_done(AR_SOFTC_T
*ar
)
326 ar
->dbglog_init_done
= TRUE
;
330 dbglog_get_debug_fragment(A_INT8
*datap
, A_UINT32 len
, A_UINT32 limit
)
339 buffer
= (A_INT32
*)datap
;
340 length
= (limit
>> 2);
345 while (count
< length
) {
346 numargs
= DBGLOG_GET_NUMARGS(buffer
[count
]);
347 fraglen
= (count
<< 2);
348 count
+= numargs
+ 1;
356 dbglog_parse_debug_logs(A_INT8
*datap
, A_UINT32 len
)
367 buffer
= (A_INT32
*)datap
;
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
]);
376 AR_DEBUG_PRINTF("%d %d (%d)\n", moduleid
, debugid
, timestamp
);
380 AR_DEBUG_PRINTF("%d %d (%d): 0x%x\n", moduleid
, debugid
,
381 timestamp
, buffer
[count
+1]);
385 AR_DEBUG_PRINTF("%d %d (%d): 0x%x, 0x%x\n", moduleid
, debugid
,
386 timestamp
, buffer
[count
+1], buffer
[count
+2]);
390 AR_DEBUG_PRINTF("Invalid args: %d\n", numargs
);
392 count
+= numargs
+ 1;
397 ar6000_dbglog_get_debug_logs(AR_SOFTC_T
*ar
)
399 struct dbglog_hdr_s debug_hdr
;
400 struct dbglog_buf_s debug_buf
;
405 A_UINT32 debug_hdr_ptr
;
407 if (!ar
->dbglog_init_done
) return A_ERROR
;
409 #ifndef CONFIG_AR6000_WLAN_DEBUG
413 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
415 if (ar
->dbgLogFetchInProgress
) {
416 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
420 /* block out others */
421 ar
->dbgLogFetchInProgress
= TRUE
;
423 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
425 debug_hdr_ptr
= dbglog_get_debug_hdr_ptr(ar
);
426 printk("debug_hdr_ptr: 0x%x\n", debug_hdr_ptr
);
428 /* Get the contents of the ring buffer */
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
;
436 dropped
= debug_hdr
.dropped
;
437 length
= sizeof(struct dbglog_buf_s
);
438 ar6000_ReadDataDiag(ar
->arHifDevice
, address
,
439 (A_UCHAR
*)&debug_buf
, length
);
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
)) {
449 if(A_OK
!= ar6000_ReadDataDiag(ar
->arHifDevice
, address
,
450 (A_UCHAR
*)&ar
->log_buffer
[ar
->log_cnt
], length
))
454 ar6000_dbglog_event(ar
, dropped
, &ar
->log_buffer
[ar
->log_cnt
], length
);
455 ar
->log_cnt
+= length
;
457 AR_DEBUG_PRINTF("Length: %d (Total size: %d)\n",
458 debug_buf
.length
, debug_buf
.bufsize
);
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
))
469 } while (address
!= firstbuf
);
472 ar
->dbgLogFetchInProgress
= FALSE
;
478 ar6000_dbglog_event(AR_SOFTC_T
*ar
, A_UINT32 dropped
,
479 A_INT8
*buffer
, A_UINT32 length
)
481 #ifdef REPORT_DEBUG_LOGS_TO_APP
482 #define MAX_WIRELESS_EVENT_SIZE 252
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.
491 send
= dbglog_get_debug_fragment(&buffer
[sent
], length
- sent
,
492 MAX_WIRELESS_EVENT_SIZE
);
494 ar6000_send_event_to_app(ar
, WMIX_DBGLOG_EVENTID
, &buffer
[sent
], send
);
496 send
= dbglog_get_debug_fragment(&buffer
[sent
], length
- sent
,
497 MAX_WIRELESS_EVENT_SIZE
);
500 AR_DEBUG_PRINTF("Dropped logs: 0x%x\nDebug info length: %d\n",
503 /* Interpret the debug logs */
504 dbglog_parse_debug_logs(buffer
, length
);
505 #endif /* REPORT_DEBUG_LOGS_TO_APP */
511 ar6000_init_module(void)
513 static int probed
= 0;
515 HTC_INIT_INFO initInfo
;
517 A_MEMZERO(&initInfo
,sizeof(initInfo
));
518 initInfo
.AddInstance
= ar6000_avail_ev
;
519 initInfo
.DeleteInstance
= ar6000_unavail_ev
;
520 initInfo
.TargetFailure
= ar6000_target_failure
;
524 /* Set the debug flags if specified at load time */
527 g_dbg_flags
= debugflags
;
536 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
537 memset(&aptcTR
, 0, sizeof(APTC_TRAFFIC_RECORD
));
538 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
540 #ifdef CONFIG_HOST_GPIO_SUPPORT
542 #endif /* CONFIG_HOST_GPIO_SUPPORT */
544 status
= HTCInit(&initInfo
);
552 ar6000_cleanup_module(void)
555 struct net_device
*ar6000_netdev
;
557 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
558 /* Delete the Adaptive Power Control timer */
559 if (timer_pending(&aptcTimer
)) {
560 del_timer_sync(&aptcTimer
);
562 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
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);
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 */
577 AR_DEBUG_PRINTF("ar6000_cleanup: success\n");
580 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
582 aptcTimerHandler(unsigned long arg
)
589 ar
= (AR_SOFTC_T
*)arg
;
590 A_ASSERT(ar
!= NULL
);
591 A_ASSERT(!timer_pending(&aptcTimer
));
593 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
595 /* Get the number of bytes transferred */
596 numbytes
= aptcTR
.bytesTransmitted
+ aptcTR
.bytesReceived
;
597 aptcTR
.bytesTransmitted
= aptcTR
.bytesReceived
= 0;
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
;
610 A_TIMEOUT_MS(&aptcTimer
, APTC_TRAFFIC_SAMPLING_INTERVAL
, 0);
613 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
615 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
619 /* set HTC block size, assume BMI is already initialized */
620 A_STATUS
ar6000_SetHTCBlockSize(AR_SOFTC_T
*ar
)
623 A_UINT32 blocksizes
[HTC_MAILBOX_NUM_MAX
];
626 /* get the block sizes */
627 status
= HIFConfigureDevice(ar
->arHifDevice
, HIF_DEVICE_GET_MBOX_BLOCK_SIZE
,
628 blocksizes
, sizeof(blocksizes
));
630 if (A_FAILED(status
)) {
631 AR_DEBUG_PRINTF("Failed to get block size info from HIF layer...\n");
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);
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],
645 if (A_FAILED(status
)) {
646 AR_DEBUG_PRINTF("BMIWriteMemory for IO block size failed \n");
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
));
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
,
659 if (A_FAILED(status
)) {
660 AR_DEBUG_PRINTF("BMIWriteMemory for yield limit failed \n");
669 static void free_raw_buffers(AR_SOFTC_T
*ar
)
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
]);
681 static int alloc_raw_buffers(AR_SOFTC_T
*ar
)
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
);
691 ar
->raw_htc_read_buffer
[i
][j
] = b
;
693 for (j
= 0; j
!= RAW_HTC_WRITE_BUFFERS_NUM
; j
++) {
694 b
= kzalloc(sizeof(*b
), GFP_KERNEL
);
697 ar
->raw_htc_write_buffer
[i
][j
] = b
;
707 ar6000_avail_ev(HTC_HANDLE HTCHandle
)
710 struct net_device
*dev
;
712 int device_index
= 0;
714 AR_DEBUG_PRINTF("ar6000_available\n");
716 for (i
=0; i
< MAX_AR6000
; i
++) {
717 if (ar6000_devices
[i
] == NULL
) {
722 if (i
== MAX_AR6000
) {
723 AR_DEBUG_PRINTF("ar6000_available: max devices reached\n");
727 /* Save this. It gives a bit better readability especially since */
728 /* we use another local "i" variable below. */
731 A_ASSERT(HTCHandle
!= NULL
);
733 dev
= alloc_etherdev(sizeof(AR_SOFTC_T
));
735 AR_DEBUG_PRINTF("ar6000_available: can't alloc etherdev\n");
741 if (netdev_priv(dev
) == NULL
) {
742 printk(KERN_CRIT
"ar6000_available: Could not allocate memory\n");
746 A_MEMZERO(netdev_priv(dev
), sizeof(AR_SOFTC_T
));
748 ar
= (AR_SOFTC_T
*)netdev_priv(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
;
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
;
763 ar6000_init_control_info(ar
);
764 init_waitqueue_head(&arEvent
);
765 sema_init(&ar
->arSem
, 1);
767 if (alloc_raw_buffers(ar
)) {
768 free_raw_buffers(ar
);
770 * @@@ Clean up our own mess, but for anything else, cheerfully mimick
771 * the beautiful error non-handling of the rest of this function.
776 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
777 A_INIT_TIMER(&aptcTimer
, aptcTimerHandler
, ar
);
778 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
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
785 * This is intended to support recovery from a corrupted flash on Targets
786 * that support flash.
790 ar6000_reset_device_skipflash(ar
->arHifDevice
);
795 struct bmi_target_info targ_info
;
797 if (BMIGetTargetInfo(ar
->arHifDevice
, &targ_info
) != A_OK
) {
801 ar
->arVersion
.target_ver
= targ_info
.target_ver
;
802 ar
->arTargetType
= targ_info
.target_type
;
805 if (enableuartprint
) {
808 if (BMIWriteMemory(ar
->arHifDevice
,
809 HOST_INTEREST_ITEM_ADDRESS(ar
, hi_serial_enable
),
813 AR_DEBUG_PRINTF("BMIWriteMemory for enableuartprint failed \n");
816 AR_DEBUG_PRINTF("Serial console prints enabled\n");
818 #ifdef CONFIG_HOST_TCMD_SUPPORT
820 ar
->arTargetMode
= AR6000_TCMD_MODE
;
822 ar
->arTargetMode
= AR6000_WLAN_MODE
;
825 if (enabletimerwar
) {
828 if (BMIReadMemory(ar
->arHifDevice
,
829 HOST_INTEREST_ITEM_ADDRESS(ar
, hi_option_flag
),
833 AR_DEBUG_PRINTF("BMIReadMemory for enabletimerwar failed \n");
837 param
|= HI_OPTION_TIMER_WAR
;
839 if (BMIWriteMemory(ar
->arHifDevice
,
840 HOST_INTEREST_ITEM_ADDRESS(ar
, hi_option_flag
),
844 AR_DEBUG_PRINTF("BMIWriteMemory for enabletimerwar failed \n");
847 AR_DEBUG_PRINTF("Timer WAR enabled\n");
851 /* since BMIInit is called in the driver layer, we have to set the block
852 * size here for the target */
854 if (A_FAILED(ar6000_SetHTCBlockSize(ar
))) {
858 spin_lock_init(&ar
->arLock
);
860 /* Don't install the init function if BMI is requested */
863 dev
->init
= ar6000_init
;
865 AR_DEBUG_PRINTF(" BMI enabled \n");
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
;
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 */
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
884 dev
->hard_header_len
= ETH_HLEN
+ sizeof(ATH_LLC_SNAP_HDR
) +
885 sizeof(WMI_DATA_HDR
) + HTC_HEADER_LEN
;
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);
895 HTCSetInstance(ar
->arHtcTarget
, ar
);
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
;
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
,
907 static void ar6000_target_failure(void *Instance
, A_STATUS Status
)
909 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Instance
;
910 WMI_TARGET_ERROR_REPORT_EVENT errEvent
;
911 static A_BOOL sip
= FALSE
;
913 if (Status
!= A_OK
) {
914 if (timer_pending(&ar
->arHBChallengeResp
.timer
)) {
915 A_UNTIMEOUT(&ar
->arHBChallengeResp
.timer
);
918 /* try dumping target assertion information (if any) */
919 ar6000_dump_target_assert_info(ar
->arHifDevice
,ar
->arTargetType
);
922 * Fetch the logs from the target via the diagnostic
925 ar6000_dbglog_get_debug_logs(ar
);
927 /* Report the error only once */
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
));
942 ar6000_unavail_ev(void *Instance
)
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);
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.
965 ar6000_destroy(struct net_device
*dev
, unsigned int unregister
)
969 AR_DEBUG_PRINTF("+ar6000_destroy \n");
971 if((dev
== NULL
) || ((ar
= netdev_priv(dev
)) == NULL
))
973 AR_DEBUG_PRINTF("%s(): Failed to get device structure.\n", __func__
);
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
));
982 /* Free up the device data structure */
984 unregister_netdev(dev
);
989 free_raw_buffers(ar
);
997 AR_DEBUG_PRINTF("-ar6000_destroy \n");
1000 static void ar6000_detect_error(unsigned long ptr
)
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
;
1006 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1008 if (ar
->arHBChallengeResp
.outstanding
) {
1009 ar
->arHBChallengeResp
.missCnt
++;
1011 ar
->arHBChallengeResp
.missCnt
= 0;
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
));
1028 /* Generate the sequence number for the next challenge */
1029 ar
->arHBChallengeResp
.seqNum
++;
1030 ar
->arHBChallengeResp
.outstanding
= TRUE
;
1032 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
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");
1040 /* Reschedule the timer for the next challenge */
1041 A_TIMEOUT_MS(&ar
->arHBChallengeResp
.timer
, ar
->arHBChallengeResp
.frequency
* 1000, 0);
1044 void ar6000_init_profile_info(AR_SOFTC_T
*ar
)
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;
1062 ar6000_init_control_info(AR_SOFTC_T
*ar
)
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
;
1073 ar
->arTxPwrSet
= FALSE
;
1075 ar
->arBeaconInterval
= 0;
1077 ar
->arMaxRetries
= 0;
1078 ar
->arWmmEnabled
= TRUE
;
1082 ar6000_open(struct net_device
*dev
)
1084 /* Wake up the queues */
1085 netif_start_queue(dev
);
1091 ar6000_close(struct net_device
*dev
)
1093 AR_SOFTC_T
*ar
= netdev_priv(dev
);
1095 /* Stop the transmit queues */
1096 netif_stop_queue(dev
);
1098 /* Disable the target and the interrupts associated with it */
1099 if (ar
->arWmiReady
== TRUE
)
1103 if (ar
->arConnected
== TRUE
|| ar
->arConnectPending
== TRUE
)
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
);
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
;
1119 ar
->arWlanState
= WLAN_ENABLED
;
1121 ar
->user_savedkeys_stat
= USER_SAVEDKEYS_STAT_INIT
;
1122 ar
->user_key_ctrl
= 0;
1126 AR_DEBUG_PRINTF("%s(): WMI stopped\n", __func__
);
1130 AR_DEBUG_PRINTF("%s(): WMI not ready 0x%08x 0x%08x\n",
1131 __func__
, (unsigned int) ar
, (unsigned int) ar
->arWmi
);
1133 /* Shut down WMI if we have started it */
1134 if(ar
->arWmiEnabled
== TRUE
)
1136 AR_DEBUG_PRINTF("%s(): Shut down WMI\n", __func__
);
1137 wmi_shutdown(ar
->arWmi
);
1138 ar
->arWmiEnabled
= FALSE
;
1144 HTCStop(ar
->arHtcTarget
);
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
);
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
);
1157 AR_DEBUG_PRINTF(" Host does not want target reset. \n");
1160 /* Done with cookies */
1161 ar6000_cookie_cleanup(ar
);
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
,
1176 HTC_SERVICE_CONNECT_RESP response
;
1180 A_MEMZERO(&response
,sizeof(response
));
1182 status
= HTCConnectService(ar
->arHtcTarget
,
1186 if (A_FAILED(status
)) {
1187 AR_DEBUG_PRINTF(" Failed to connect to %s service status:%d \n", pDesc
, status
);
1191 if (WmiStreamID
== WMI_NOT_MAPPED
) {
1196 /* set endpoint mapping for the WMI stream in the driver layer */
1197 arSetWMIStream2EndpointIDMap(ar
,WmiStreamID
,response
.Endpoint
);
1204 static void ar6000_TxDataCleanup(AR_SOFTC_T
*ar
)
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
),
1212 HTCFlushEndpoint(ar
->arHtcTarget
,
1213 arWMIStream2EndpointID(ar
,WMI_LOW_PRI
),
1215 HTCFlushEndpoint(ar
->arHtcTarget
,
1216 arWMIStream2EndpointID(ar
,WMI_HIGH_PRI
),
1218 HTCFlushEndpoint(ar
->arHtcTarget
,
1219 arWMIStream2EndpointID(ar
,WMI_HIGHEST_PRI
),
1223 /* This function does one time initialization for the lifetime of the device */
1224 int ar6000_init(struct net_device
*dev
)
1230 if((ar
= netdev_priv(dev
)) == NULL
)
1235 /* Do we need to finish the BMI phase */
1236 if(BMIDone(ar
->arHifDevice
) != A_OK
)
1244 if (ar
->arVersion
.host_ver
!= ar
->arVersion
.target_ver
) {
1245 A_PRINTF("WARNING: Host version 0x%x does not match Target "
1247 ar
->arVersion
.host_ver
, ar
->arVersion
.target_ver
);
1251 /* Indicate that WMI is enabled (although not ready yet) */
1252 ar
->arWmiEnabled
= TRUE
;
1253 if ((ar
->arWmi
= wmi_init((void *) ar
)) == NULL
)
1255 AR_DEBUG_PRINTF("%s() Failed to initialize WMI.\n", __func__
);
1259 AR_DEBUG_PRINTF("%s() Got WMI @ 0x%08x.\n", __func__
,
1260 (unsigned int) ar
->arWmi
);
1264 HTC_SERVICE_CONNECT_REQ connect
;
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,
1269 status
= HTCWaitTarget(ar
->arHtcTarget
);
1271 if (A_FAILED(status
)) {
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;
1295 /* connect to control service */
1296 connect
.ServiceID
= WMI_CONTROL_SVC
;
1297 status
= ar6000_connectservice(ar
,
1301 if (A_FAILED(status
)) {
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
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
;
1315 /* connect to best-effort service */
1316 connect
.ServiceID
= WMI_DATA_BE_SVC
;
1318 status
= ar6000_connectservice(ar
,
1320 WMI_BEST_EFFORT_PRI
,
1322 if (A_FAILED(status
)) {
1326 /* connect to back-ground
1327 * map this to WMI LOW_PRI */
1328 connect
.ServiceID
= WMI_DATA_BK_SVC
;
1329 status
= ar6000_connectservice(ar
,
1333 if (A_FAILED(status
)) {
1337 /* connect to Video service, map this to
1339 connect
.ServiceID
= WMI_DATA_VI_SVC
;
1340 status
= ar6000_connectservice(ar
,
1344 if (A_FAILED(status
)) {
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
,
1358 if (A_FAILED(status
)) {
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);
1369 if (A_FAILED(status
)) {
1374 * give our connected endpoints some buffers
1376 ar6000_rx_refill(ar
, arWMIStream2EndpointID(ar
,WMI_CONTROL_PRI
));
1378 ar6000_rx_refill(ar
, arWMIStream2EndpointID(ar
,WMI_BEST_EFFORT_PRI
));
1381 * We will post the receive buffers only for SPE testing and so we are
1382 * making it conditional on the 'bypasswmi' flag.
1385 ar6000_rx_refill(ar
,arWMIStream2EndpointID(ar
,WMI_LOW_PRI
));
1386 ar6000_rx_refill(ar
,arWMIStream2EndpointID(ar
,WMI_HIGH_PRI
));
1389 /* setup credit distribution */
1390 ar6000_setup_credit_dist(ar
->arHtcTarget
, &ar
->arCreditStateInfo
);
1392 /* Since cookies are used for HTC transports, they should be */
1393 /* initialized prior to enabling HTC. */
1394 ar6000_cookie_init(ar
);
1397 status
= HTCStart(ar
->arHtcTarget
);
1399 if (status
!= A_OK
) {
1400 if (ar
->arWmiEnabled
== TRUE
) {
1401 wmi_shutdown(ar
->arWmi
);
1402 ar
->arWmiEnabled
= FALSE
;
1405 ar6000_cookie_cleanup(ar
);
1410 /* Wait for Wmi event to be ready */
1411 timeleft
= wait_event_interruptible_timeout(arEvent
,
1412 (ar
->arWmiReady
== TRUE
), wmitimeout
* HZ
);
1414 if(!timeleft
|| signal_pending(current
))
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");
1424 AR_DEBUG_PRINTF("%s() WMI is ready\n", __func__
);
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");
1432 ar
->arNumDataEndPts
= 1;
1439 ar6000_bitrate_rx(void *devt
, A_INT32 rateKbps
)
1441 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
1443 ar
->arBitRate
= rateKbps
;
1448 ar6000_ratemask_rx(void *devt
, A_UINT16 ratemask
)
1450 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
1452 ar
->arRateMask
= ratemask
;
1457 ar6000_txPwr_rx(void *devt
, A_UINT8 txPwr
)
1459 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
1461 ar
->arTxPwr
= txPwr
;
1467 ar6000_channelList_rx(void *devt
, A_INT8 numChan
, A_UINT16
*chanList
)
1469 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
1471 A_MEMCPY(ar
->arChannelList
, chanList
, numChan
* sizeof (A_UINT16
));
1472 ar
->arNumChannels
= numChan
;
1478 ar6000_ibss_map_epid(struct sk_buff
*skb
, struct net_device
*dev
, A_UINT32
* mapNo
)
1480 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1482 ATH_MAC_HDR
*macHdr
;
1486 datap
= A_NETBUF_DATA(skb
);
1487 macHdr
= (ATH_MAC_HDR
*)(datap
+ sizeof(WMI_DATA_HDR
));
1488 if (IEEE80211_IS_MULTICAST(macHdr
->dstMac
)) {
1493 for (i
= 0; i
< ar
->arNodeNum
; i
++) {
1494 if (IEEE80211_ADDR_EQ(macHdr
->dstMac
, ar
->arNodeMap
[i
].macAddress
)) {
1496 ar
->arNodeMap
[i
].txPending
++;
1497 return ar
->arNodeMap
[i
].epId
;
1500 if ((eptMap
== -1) && !ar
->arNodeMap
[i
].txPending
) {
1506 eptMap
= ar
->arNodeNum
;
1508 A_ASSERT(ar
->arNodeNum
<= MAX_NODE_NUM
);
1511 A_MEMCPY(ar
->arNodeMap
[eptMap
].macAddress
, macHdr
->dstMac
, IEEE80211_ADDR_LEN
);
1513 for (i
= ENDPOINT_2
; i
<= ENDPOINT_5
; i
++) {
1514 if (!ar
->arTxPending
[i
]) {
1515 ar
->arNodeMap
[eptMap
].epId
= i
;
1518 // No free endpoint is available, start redistribution on the inuse endpoints.
1519 if (i
== ENDPOINT_5
) {
1520 ar
->arNodeMap
[eptMap
].epId
= ar
->arNexEpId
;
1522 if (ar
->arNexEpId
> ENDPOINT_5
) {
1523 ar
->arNexEpId
= ENDPOINT_2
;
1528 (*mapNo
) = eptMap
+ 1;
1529 ar
->arNodeMap
[eptMap
].txPending
++;
1531 return ar
->arNodeMap
[eptMap
].epId
;
1535 static void ar6000_dump_skb(struct sk_buff
*skb
)
1538 for (ch
= A_NETBUF_DATA(skb
);
1539 (A_UINT32
)ch
< ((A_UINT32
)A_NETBUF_DATA(skb
) +
1540 A_NETBUF_LEN(skb
)); ch
++)
1542 AR_DEBUG_PRINTF("%2.2x ", *ch
);
1544 AR_DEBUG_PRINTF("\n");
1549 ar6000_data_tx(struct sk_buff
*skb
, struct net_device
*dev
)
1551 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1552 WMI_PRI_STREAM_ID streamID
= WMI_NOT_MAPPED
;
1555 struct ar_cookie
*cookie
;
1556 A_BOOL checkAdHocPsMapping
= FALSE
;
1558 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
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
),
1565 #ifdef CONFIG_HOST_TCMD_SUPPORT
1566 /* TCMD doesnt support any data, free the buf and return */
1567 if(ar
->arTargetMode
== AR6000_TCMD_MODE
) {
1574 if (ar
->arWmiReady
== FALSE
&& bypasswmi
== 0) {
1578 #ifdef BLOCK_TX_PATH_FLAG
1582 #endif /* BLOCK_TX_PATH_FLAG */
1584 if (ar
->arWmiEnabled
) {
1585 if (A_NETBUF_HEADROOM(skb
) < dev
->hard_header_len
) {
1586 struct sk_buff
*newbuf
;
1588 * We really should have gotten enough headroom but sometimes
1589 * we still get packets with not enough headroom. Copy the packet.
1591 len
= A_NETBUF_LEN(skb
);
1592 newbuf
= A_NETBUF_ALLOC(len
);
1593 if (newbuf
== NULL
) {
1596 A_NETBUF_PUT(newbuf
, len
);
1597 A_MEMCPY(A_NETBUF_DATA(newbuf
), A_NETBUF_DATA(skb
), len
);
1600 /* fall through and assemble header */
1603 if (wmi_dix_2_dot3(ar
->arWmi
, skb
) != A_OK
) {
1604 AR_DEBUG_PRINTF("ar6000_data_tx - wmi_dix_2_dot3 failed\n");
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");
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
;
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
));
1624 streamID
= WMI_BEST_EFFORT_PRI
;
1629 struct iphdr
*ipHdr
;
1631 * the endpoint is directly based on the TOS field in the IP
1632 * header **** only for testing ******
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
);
1642 /* did we succeed ? */
1643 if ((streamID
== WMI_NOT_MAPPED
) && !checkAdHocPsMapping
) {
1644 /* cleanup and exit */
1646 AR6000_STAT_INC(ar
, tx_dropped
);
1647 AR6000_STAT_INC(ar
, tx_aborted_errors
);
1653 /* take the lock to protect driver data */
1654 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1658 if (checkAdHocPsMapping
) {
1659 streamID
= ar6000_ibss_map_epid(skb
, dev
, &mapNo
);
1662 A_ASSERT(streamID
!= WMI_NOT_MAPPED
);
1664 /* validate that the endpoint is connected */
1665 if (arWMIStream2EndpointID(ar
,streamID
) == 0) {
1666 AR_DEBUG_PRINTF("Stream %d is NOT mapped!\n",streamID
);
1669 /* allocate resource for this packet */
1670 cookie
= ar6000_alloc_cookie(ar
);
1672 if (cookie
!= NULL
) {
1673 /* update counts while the lock is held */
1674 ar
->arTxPending
[streamID
]++;
1675 ar
->arTotalTxDataPending
++;
1680 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
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
,
1689 arWMIStream2EndpointID(ar
,streamID
),
1693 if (debugdriver
>= 3) {
1694 ar6000_dump_skb(skb
);
1697 /* HTC interface is asynchronous, if this fails, cleanup will happen in
1698 * the ar6000_tx_complete callback */
1699 HTCSendPkt(ar
->arHtcTarget
, &cookie
->HtcPkt
);
1701 /* no packet to send, cleanup */
1703 AR6000_STAT_INC(ar
, tx_dropped
);
1704 AR6000_STAT_INC(ar
, tx_aborted_errors
);
1710 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1712 tvsub(register struct timeval
*out
, register struct timeval
*in
)
1714 if((out
->tv_usec
-= in
->tv_usec
) < 0) {
1716 out
->tv_usec
+= 1000000;
1718 out
->tv_sec
-= in
->tv_sec
;
1722 applyAPTCHeuristics(AR_SOFTC_T
*ar
)
1726 A_UINT32 throughput
;
1730 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
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
;
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
);
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
;
1757 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1759 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1762 ar6000_tx_queue_full(void *Context
, HTC_ENDPOINT_ID Endpoint
)
1764 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*) Context
;
1766 if (Endpoint
== arWMIStream2EndpointID(ar
,WMI_CONTROL_PRI
)) {
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 */
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");
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
);
1786 ar6000_tx_queue_avail(void *Context
, HTC_ENDPOINT_ID Endpoint
)
1788 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Context
;
1790 if (Endpoint
== arWMIStream2EndpointID(ar
,WMI_CONTROL_PRI
)) {
1791 /* FIXME: what do for it? */
1793 /* Wake up interface, rescheduling prevented. */
1794 if (ar
->arConnected
== TRUE
|| bypasswmi
)
1795 netif_wake_queue(ar
->arNetDev
);
1800 ar6000_tx_complete(void *Context
, HTC_PACKET
*pPacket
)
1802 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Context
;
1803 void *cookie
= (void *)pPacket
->pPktContext
;
1804 struct sk_buff
*skb
= NULL
;
1807 struct ar_cookie
* ar_cookie
;
1808 WMI_PRI_STREAM_ID streamID
;
1809 A_BOOL wakeEvent
= FALSE
;
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];
1818 A_ASSERT(pPacket
->pBuffer
== A_NETBUF_DATA(skb
));
1820 if (A_SUCCESS(status
)) {
1821 A_ASSERT(pPacket
->ActualLength
== A_NETBUF_LEN(skb
));
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
,
1829 /* lock the driver as we update internal state */
1830 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1832 ar
->arTxPending
[streamID
]--;
1834 if ((streamID
!= WMI_CONTROL_PRI
) || bypasswmi
) {
1835 ar
->arTotalTxDataPending
--;
1838 if (streamID
== WMI_CONTROL_PRI
)
1840 if (ar
->arWMIControlEpFull
) {
1841 /* since this packet completed, the WMI EP is no longer full */
1842 ar
->arWMIControlEpFull
= FALSE
;
1845 if (ar
->arTxPending
[streamID
] == 0) {
1850 if (A_FAILED(status
)) {
1851 AR_DEBUG_PRINTF("%s() -TX ERROR, status: 0x%x\n", __func__
,
1853 AR6000_STAT_INC(ar
, tx_errors
);
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 */
1864 // TODO this needs to be looked at
1865 if ((ar
->arNetworkType
== ADHOC_NETWORK
) && ar
->arIbssPsEnable
1866 && (streamID
!= WMI_CONTROL_PRI
) && mapNo
)
1869 ar
->arNodeMap
[mapNo
].txPending
--;
1871 if (!ar
->arNodeMap
[mapNo
].txPending
&& (mapNo
== (ar
->arNodeNum
- 1))) {
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
));
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
))
1889 ar6000_free_cookie(ar
, cookie
);
1892 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1894 /* lock is released, we can freely call other kernel APIs */
1896 /* this indirectly frees the HTC_PACKET */
1905 * Receive event handler. This is called by HTC when a packet is received
1909 ar6000_rx(void *Context
, HTC_PACKET
*pPacket
)
1911 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Context
;
1912 struct sk_buff
*skb
= (struct sk_buff
*)pPacket
->pPktContext
;
1914 A_STATUS status
= pPacket
->Status
;
1915 WMI_PRI_STREAM_ID streamID
= arEndpoint2WMIStreamID(ar
,pPacket
->Endpoint
);
1916 HTC_ENDPOINT_ID ept
= pPacket
->Endpoint
;
1918 A_ASSERT((status
!= A_OK
) || (pPacket
->pBuffer
== (A_NETBUF_DATA(skb
) + HTC_HEADER_LEN
)));
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");
1926 AR_DEBUG2_PRINTF("OK\n");
1929 /* take lock to protect buffer counts
1930 * and adaptive power throughput state */
1931 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1933 ar
->arRxBuffers
[streamID
]--;
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 */
1943 A_NETBUF_PUT(skb
, pPacket
->ActualLength
+ HTC_HEADER_LEN
);
1944 A_NETBUF_PULL(skb
, HTC_HEADER_LEN
);
1947 if (debugdriver
>= 2) {
1948 ar6000_dump_skb(skb
);
1953 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1955 if (status
!= A_OK
) {
1956 AR6000_STAT_INC(ar
, rx_errors
);
1958 } else if (ar
->arWmiEnabled
== TRUE
) {
1959 if (streamID
== WMI_CONTROL_PRI
) {
1961 * this is a wmi control msg
1963 wmi_control_rx(ar
->arWmi
, skb
);
1965 WMI_DATA_HDR
*dhdr
= (WMI_DATA_HDR
*)A_NETBUF_DATA(skb
);
1966 if (WMI_DATA_HDR_IS_MSG_TYPE(dhdr
, CNTL_MSGTYPE
)) {
1968 * this is a wmi control msg
1970 /* strip off WMI hdr */
1971 wmi_data_hdr_remove(ar
->arWmi
, skb
);
1972 wmi_control_rx(ar
->arWmi
, skb
);
1975 * this is a wmi data packet
1977 minHdrLen
= sizeof (WMI_DATA_HDR
) + sizeof(ATH_MAC_HDR
) +
1978 sizeof(ATH_LLC_SNAP_HDR
);
1980 if ((pPacket
->ActualLength
< minHdrLen
) ||
1981 (pPacket
->ActualLength
> AR6000_BUFFER_SIZE
))
1984 * packet is too short or too long
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
);
1991 if (ar
->arWmmEnabled
) {
1992 wmi_implicit_create_pstream(ar
->arWmi
, skb
,
1993 DNLINK_TRAFFIC
, UNDEFINED_PRI
);
1996 /* Access RSSI values here */
1997 AR_DEBUG_PRINTF("RSSI %d\n",
1998 ((WMI_DATA_HDR
*) A_NETBUF_DATA(skb
))->rssi
);
2000 wmi_data_hdr_remove(ar
->arWmi
, skb
);
2001 wmi_dot3_2_dix(ar
->arWmi
, skb
);
2003 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
2005 * extra push and memcpy, for eth_type_trans() of 2.4 kernel
2006 * will pull out hard_header_len bytes of the skb.
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
));
2012 if ((ar
->arNetDev
->flags
& IFF_UP
) == IFF_UP
)
2014 skb
->dev
= ar
->arNetDev
;
2015 skb
->protocol
= eth_type_trans(skb
, ar
->arNetDev
);
2026 if ((ar
->arNetDev
->flags
& IFF_UP
) == IFF_UP
)
2028 skb
->dev
= ar
->arNetDev
;
2029 skb
->protocol
= eth_type_trans(skb
, ar
->arNetDev
);
2038 if (status
!= A_ECANCELED
) {
2040 * HTC provides A_ECANCELED status when it doesn't want to be refilled
2041 * (probably due to a shutdown)
2043 ar6000_rx_refill(Context
, ept
);
2050 ar6000_rx_refill(void *Context
, HTC_ENDPOINT_ID Endpoint
)
2052 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Context
;
2055 int buffersToRefill
;
2056 HTC_PACKET
*pPacket
;
2057 WMI_PRI_STREAM_ID streamId
= arEndpoint2WMIStreamID(ar
,Endpoint
);
2059 buffersToRefill
= (int)AR6000_MAX_RX_BUFFERS
-
2060 (int)ar
->arRxBuffers
[streamId
];
2062 if (buffersToRefill
<= 0) {
2063 /* fast return, nothing to fill */
2067 AR_DEBUG2_PRINTF("ar6000_rx_refill: providing htc with %d buffers at eid=%d\n",
2068 buffersToRefill
, Endpoint
);
2070 for (RxBuffers
= 0; RxBuffers
< buffersToRefill
; RxBuffers
++) {
2071 osBuf
= A_NETBUF_ALLOC(AR6000_BUFFER_SIZE
);
2072 if (NULL
== osBuf
) {
2075 /* the HTC packet wrapper is at the head of the reserved area
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
);
2085 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
2086 ar
->arRxBuffers
[streamId
] += RxBuffers
;
2087 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
2090 static struct net_device_stats
*
2091 ar6000_get_stats(struct net_device
*dev
)
2093 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
2094 return &ar
->arNetStats
;
2097 static struct iw_statistics
*
2098 ar6000_get_iwstats(struct net_device
* dev
)
2100 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
2101 TARGET_STATS
*pStats
= &ar
->arTargetStats
;
2102 struct iw_statistics
* pIwStats
= &ar
->arIwStats
;
2104 if ((ar
->arWmiReady
== FALSE
)
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.
2112 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
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;
2126 if (down_interruptible(&ar
->arSem
)) {
2127 pIwStats
->status
= 0;
2132 ar
->statsUpdatePending
= TRUE
;
2134 if(wmi_get_stats_cmd(ar
->arWmi
) != A_OK
) {
2136 pIwStats
->status
= 0;
2140 wait_event_interruptible_timeout(arEvent
, ar
->statsUpdatePending
== FALSE
, wmitimeout
* HZ
);
2142 if (signal_pending(current
)) {
2143 AR_DEBUG_PRINTF("ar6000 : WMI get stats timeout \n");
2145 pIwStats
->status
= 0;
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
;
2160 ar6000_ready_event(void *devt
, A_UINT8
*datap
, A_UINT8 phyCap
)
2162 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
2163 struct net_device
*dev
= ar
->arNetDev
;
2165 ar
->arWmiReady
= TRUE
;
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]);
2173 ar
->arPhyCapability
= phyCap
;
2177 ar6000_iptos_to_userPriority(A_UINT8
*pkt
)
2179 struct iphdr
*ipHdr
= (struct iphdr
*)pkt
;
2180 A_UINT8 userPriority
;
2184 * (Refer Pg 57 WMM-test-plan-v1.2)
2186 * : DSCP(6-bits) ECN(2-bits)
2187 * : DSCP - P2 P1 P0 X X X
2188 * where (P2 P1 P0) form 802.1D
2190 userPriority
= ipHdr
->tos
>> 5;
2191 return (userPriority
& 0x7);
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
,
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
)];
2208 A_UINT8 key_op_ctrl
;
2210 A_MEMCPY(ar
->arBssid
, bssid
, sizeof(ar
->arBssid
));
2211 ar
->arBssChannel
= channel
;
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");
2225 A_PRINTF("Network: Adhoc (Joiner)\n");
2228 A_PRINTF("Network: Infrastructure\n");
2231 if (beaconIeLen
&& (sizeof(buf
) > (9 + beaconIeLen
* 2))) {
2232 AR_DEBUG_PRINTF("\nBeaconIEs= ");
2235 A_MEMZERO(buf
, sizeof(buf
));
2236 sprintf(buf
, "%s", beaconIetag
);
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
]);
2243 AR_DEBUG_PRINTF("\n");
2245 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2246 wrqu
.data
.length
= strlen(buf
);
2247 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2250 if (assocRespLen
&& (sizeof(buf
) > (12 + (assocRespLen
* 2))))
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
);
2259 AR_DEBUG_PRINTF("\nAssocRespIEs= ");
2261 * The Association Response Frame w.o. the WLAN header is delivered to
2262 * the host, so skip over to the IEs
2264 for (i
= assoc_resp_ie_pos
; i
< assoc_resp_ie_pos
+ assocRespLen
- 6; i
++)
2266 AR_DEBUG_PRINTF("%2.2x ", assocInfo
[i
]);
2267 sprintf(pos
, "%2.2x", assocInfo
[i
]);
2270 AR_DEBUG_PRINTF("\n");
2272 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2273 wrqu
.data
.length
= strlen(buf
);
2274 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2277 if (assocReqLen
&& (sizeof(buf
) > (17 + (assocReqLen
* 2)))) {
2279 * assoc Request includes capability and listen interval. Skip these.
2281 assoc_req_ie_pos
= beaconIeLen
+
2282 sizeof(A_UINT16
) + /* capinfo*/
2283 sizeof(A_UINT16
); /* listen interval */
2285 A_MEMZERO(buf
, sizeof(buf
));
2286 sprintf(buf
, "%s", tag1
);
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
]);
2294 AR_DEBUG_PRINTF("\n");
2296 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2297 wrqu
.data
.length
= strlen(buf
);
2298 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2302 if (ar
->user_savedkeys_stat
== USER_SAVEDKEYS_STAT_RUN
&&
2303 ar
->user_saved_keys
.keyOk
== TRUE
)
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
;
2310 key_op_ctrl
|= KEY_OP_INIT_RSC
;
2312 ar6000_reinstall_keys(ar
, key_op_ctrl
);
2314 #endif /* USER_KEYS */
2316 /* flush data queues */
2317 ar6000_TxDataCleanup(ar
);
2319 netif_start_queue(ar
->arNetDev
);
2321 if ((OPEN_AUTH
== ar
->arDot11AuthMode
) &&
2322 (NONE_AUTH
== ar
->arAuthMode
) &&
2323 (WEP_CRYPT
== ar
->arPairwiseCrypto
))
2325 if (!ar
->arConnected
) {
2326 ar6000_install_static_wep_keys(ar
);
2330 ar
->arConnected
= TRUE
;
2331 ar
->arConnectPending
= FALSE
;
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
));
2342 ar
->arNexEpId
= ENDPOINT_2
;
2347 void ar6000_set_numdataendpts(AR_SOFTC_T
*ar
, A_UINT32 num
)
2349 A_ASSERT(num
<= (HTC_MAILBOX_NUM_MAX
- 1));
2350 ar
->arNumDataEndPts
= num
;
2354 ar6000_disconnect_event(AR_SOFTC_T
*ar
, A_UINT8 reason
, A_UINT8
*bssid
,
2355 A_UINT8 assocRespLen
, A_UINT8
*assocInfo
, A_UINT16 protocolReasonStatus
)
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]);
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
++) {
2372 AR_DEBUG_PRINTF("\n");
2374 AR_DEBUG_PRINTF("%2.2x ", assocInfo
[i
]);
2376 AR_DEBUG_PRINTF("\n");
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.
2383 if( reason
== DISCONNECT_CMD
)
2385 ar
->arConnectPending
= FALSE
;
2387 ar
->arConnectPending
= TRUE
;
2388 if (((reason
== ASSOC_FAILED
) && (protocolReasonStatus
== 0x11)) ||
2389 ((reason
== ASSOC_FAILED
) && (protocolReasonStatus
== 0x0) && (reconnect_flag
== 1))) {
2390 ar
->arConnected
= TRUE
;
2394 ar
->arConnected
= FALSE
;
2396 if( (reason
!= CSERV_DISCONNECT
) || (reconnect_flag
!= 1) ) {
2401 if (reason
!= CSERV_DISCONNECT
)
2403 ar
->user_savedkeys_stat
= USER_SAVEDKEYS_STAT_INIT
;
2404 ar
->user_key_ctrl
= 0;
2406 #endif /* USER_KEYS */
2408 netif_stop_queue(ar
->arNetDev
);
2409 A_MEMZERO(ar
->arBssid
, sizeof(ar
->arBssid
));
2410 ar
->arBssChannel
= 0;
2411 ar
->arBeaconInterval
= 0;
2413 ar6000_TxDataCleanup(ar
);
2417 ar6000_regDomain_event(AR_SOFTC_T
*ar
, A_UINT32 regCode
)
2419 A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode
);
2420 ar
->arRegCode
= regCode
;
2424 ar6000_neighborReport_event(AR_SOFTC_T
*ar
, int numAps
, WMI_NEIGHBOR_INFO
*info
)
2426 static const char *tag
= "PRE-AUTH";
2428 union iwreq_data wrqu
;
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");
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 */
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",
2446 info
->bssid
[0], info
->bssid
[1], info
->bssid
[2],
2447 info
->bssid
[3], info
->bssid
[4], info
->bssid
[5],
2449 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2450 wrqu
.data
.length
= strlen(buf
);
2451 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2456 ar6000_tkip_micerr_event(AR_SOFTC_T
*ar
, A_UINT8 keyid
, A_BOOL ismcast
)
2458 static const char *tag
= "MLME-MICHAELMICFAILURE.indication";
2460 union iwreq_data wrqu
;
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
);
2472 ar6000_scanComplete_event(AR_SOFTC_T
*ar
, A_STATUS status
)
2474 AR_DEBUG_PRINTF("AR6000 scan complete: %d\n", status
);
2476 ar
->scan_complete
= 1;
2477 wake_up_interruptible(&ar6000_scan_queue
);
2481 ar6000_targetStats_event(AR_SOFTC_T
*ar
, WMI_TARGET_STATS
*pTarget
)
2483 TARGET_STATS
*pStats
= &ar
->arTargetStats
;
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
);
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
);
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
;
2531 pStats
->power_save_failure_cnt
+= pTarget
->pmStats
.power_save_failure_cnt
;
2532 pStats
->noise_floor_calibation
= pTarget
->noise_floor_calibation
;
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
;
2544 pStats
->lq_val
= pTarget
->lqVal
;
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
;
2551 ar
->statsUpdatePending
= FALSE
;
2556 ar6000_rssiThreshold_event(AR_SOFTC_T
*ar
, WMI_RSSI_THRESHOLD_VAL newThreshold
, A_INT16 rssi
)
2558 USER_RSSI_THOLD userRssiThold
;
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
));
2570 ar6000_hbChallengeResp_event(AR_SOFTC_T
*ar
, A_UINT32 cookie
, A_UINT32 source
)
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
));
2579 /* This would ignore the replys that come in after their due time */
2580 if (cookie
== ar
->arHBChallengeResp
.seqNum
) {
2581 ar
->arHBChallengeResp
.outstanding
= FALSE
;
2588 ar6000_reportError_event(AR_SOFTC_T
*ar
, WMI_TARGET_ERROR_VAL errorVal
)
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"
2598 A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal
);
2600 /* One error is reported at a time, and errorval is a bitmask */
2601 if(errorVal
& (errorVal
- 1))
2604 A_PRINTF("AR6000 Error type = ");
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
]);
2615 A_PRINTF("INVALID\n");
2623 ar6000_cac_event(AR_SOFTC_T
*ar
, A_UINT8 ac
, A_UINT8 cacIndication
,
2624 A_UINT8 statusCode
, A_UINT8
*tspecSuggestion
)
2626 WMM_TSPEC_IE
*tspecIe
;
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.
2634 tspecIe
= (WMM_TSPEC_IE
*)tspecSuggestion
;
2637 * What do we do, if we get TSPEC rejection? One thought
2638 * that comes to mind is implictly delete the pstream...
2640 A_PRINTF("AR6000 CAC notification. "
2641 "AC = %d, cacIndication = 0x%x, statusCode = 0x%x\n",
2642 ac
, cacIndication
, statusCode
);
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]); \
2652 ar6000_roam_tbl_event(AR_SOFTC_T
*ar
, WMI_TARGET_ROAM_TBL
*pTbl
)
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"
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
);
2677 ar6000_wow_list_event(struct ar6_softc
*ar
, A_UINT8 num_filters
, WMI_GET_WOW_LIST_REPLY
*wow_reply
)
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"));
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*/
2692 /* If this event contains pattern information, display it*/
2693 if (wow_reply
->this_filter_num
) {
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
]);
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
]);
2713 * Report the Roaming related data collected on the target
2716 ar6000_display_roam_time(WMI_TARGET_ROAM_TIME
*p
)
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
,
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
);
2734 ar6000_roam_data_event(AR_SOFTC_T
*ar
, WMI_TARGET_ROAM_DATA
*p
)
2736 switch (p
->roamDataType
) {
2737 case ROAM_DATA_TIME
:
2738 ar6000_display_roam_time(&p
->u
.roamTime
);
2746 ar6000_bssInfo_event_rx(AR_SOFTC_T
*ar
, A_UINT8
*datap
, int len
)
2748 struct sk_buff
*skb
;
2749 WMI_BSS_INFO_HDR
*bih
= (WMI_BSS_INFO_HDR
*)datap
;
2752 if (!ar
->arMgmtFilter
) {
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
)))
2763 if ((skb
= A_NETBUF_ALLOC_RAW(len
)) != NULL
) {
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);
2777 A_UINT32 wmiSendCmdNum
;
2780 ar6000_control_tx(void *devt
, void *osbuf
, WMI_PRI_STREAM_ID streamID
)
2782 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
2783 A_STATUS status
= A_OK
;
2784 struct ar_cookie
*cookie
= NULL
;
2787 /* take lock to protect ar6000_alloc_cookie() */
2788 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
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
);
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 */
2799 AR_DEBUG_PRINTF(" WMI Control EP full, dropping packet : 0x%X, len:%d \n",
2800 (A_UINT32
)osbuf
, A_NETBUF_LEN(osbuf
));
2802 cookie
= ar6000_alloc_cookie(ar
);
2805 if (cookie
== NULL
) {
2806 status
= A_NO_MEMORY
;
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
]);
2821 if (cookie
!= NULL
) {
2822 /* got a structure to send it out on */
2823 ar
->arTxPending
[streamID
]++;
2825 if (streamID
!= WMI_CONTROL_PRI
) {
2826 ar
->arTotalTxDataPending
++;
2830 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
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
,
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
);
2850 /* indicate tx activity or inactivity on a WMI stream */
2851 void ar6000_indicate_tx_activity(void *devt
, A_UINT8 TrafficClass
, A_BOOL Active
)
2853 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
2854 WMI_PRI_STREAM_ID streamid
;
2856 if (ar
->arWmiEnabled
) {
2857 streamid
= wmi_get_stream_id(ar
->arWmi
, TrafficClass
);
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
;
2864 /* notify HTC, this may cause credit distribution changes */
2866 HTCIndicateActivityChange(ar
->arHtcTarget
,
2867 arWMIStream2EndpointID(ar
,streamid
),
2872 module_init(ar6000_init_module
);
2873 module_exit(ar6000_cleanup_module
);
2875 /* Init cookie queue */
2877 ar6000_cookie_init(AR_SOFTC_T
*ar
)
2881 ar
->arCookieList
= NULL
;
2882 A_MEMZERO(s_ar_cookie_mem
, sizeof(s_ar_cookie_mem
));
2884 for (i
= 0; i
< MAX_COOKIE_NUM
; i
++) {
2885 ar6000_free_cookie(ar
, &s_ar_cookie_mem
[i
]);
2889 /* cleanup cookie queue */
2891 ar6000_cookie_cleanup(AR_SOFTC_T
*ar
)
2893 /* It is gone .... */
2894 ar
->arCookieList
= NULL
;
2897 /* Init cookie queue */
2899 ar6000_free_cookie(AR_SOFTC_T
*ar
, struct ar_cookie
* cookie
)
2902 A_ASSERT(ar
!= NULL
);
2903 A_ASSERT(cookie
!= NULL
);
2904 cookie
->arc_list_next
= ar
->arCookieList
;
2905 ar
->arCookieList
= cookie
;
2908 /* cleanup cookie queue */
2909 static struct ar_cookie
*
2910 ar6000_alloc_cookie(AR_SOFTC_T
*ar
)
2912 struct ar_cookie
*cookie
;
2914 cookie
= ar
->arCookieList
;
2917 ar
->arCookieList
= cookie
->arc_list_next
;
2923 #ifdef SEND_EVENT_TO_APP
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.
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
)
2934 #if (WIRELESS_EXT >= 15)
2936 /* note: IWEVCUSTOM only exists in wireless extensions after version 15 */
2940 union iwreq_data wrqu
;
2942 size
= len
+ EVENT_ID_LEN
;
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
);
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
);
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
);
2969 ar6000_tx_retry_err_event(void *devt
)
2971 AR_DEBUG2_PRINTF("Tx retries reach maximum!\n");
2975 ar6000_snrThresholdEvent_rx(void *devt
, WMI_SNR_THRESHOLD_VAL newThreshold
, A_UINT8 snr
)
2977 AR_DEBUG2_PRINTF("snr threshold range %d, snr %d\n", newThreshold
, snr
);
2981 ar6000_lqThresholdEvent_rx(void *devt
, WMI_LQ_THRESHOLD_VAL newThreshold
, A_UINT8 lq
)
2983 AR_DEBUG2_PRINTF("lq threshold range %d, lq %d\n", newThreshold
, lq
);
2989 a_copy_to_user(void *to
, const void *from
, A_UINT32 n
)
2991 return(copy_to_user(to
, from
, n
));
2995 a_copy_from_user(void *to
, const void *from
, A_UINT32 n
)
2997 return(copy_from_user(to
, from
, n
));
3002 ar6000_get_driver_cfg(struct net_device
*dev
,
3011 case AR6000_DRIVER_CFG_GET_WLANNODECACHING
:
3012 *((A_UINT32
*)result
) = wlanNodeCaching
;
3014 case AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS
:
3015 *((A_UINT32
*)result
) = logWmiRawMsgs
;
3026 ar6000_keepalive_rx(void *devt
, A_UINT8 configured
)
3028 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
3030 ar
->arKeepaliveConfigured
= configured
;
3035 ar6000_pmkid_list_event(void *devt
, A_UINT8 numPMKID
, WMI_PMKID
*pmkidList
)
3039 A_PRINTF("Number of Cached PMKIDs is %d\n", numPMKID
);
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
]);
3053 ar6000_reinstall_keys(AR_SOFTC_T
*ar
, A_UINT8 key_op_ctrl
)
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
;
3060 if (IEEE80211_CIPHER_CCKM_KRK
!= uik
->ik_type
) {
3061 if (NONE_CRYPT
== keyType
) {
3062 goto _reinstall_keys_out
;
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
);
3073 status
= wmi_add_krk_cmd(ar
->arWmi
, uik
->ik_keydata
);
3076 if (IEEE80211_CIPHER_CCKM_KRK
!= bik
->ik_type
) {
3077 if (NONE_CRYPT
== keyType
) {
3078 goto _reinstall_keys_out
;
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
);
3088 status
= wmi_add_krk_cmd(ar
->arWmi
, bik
->ik_keydata
);
3091 _reinstall_keys_out
:
3092 ar
->user_savedkeys_stat
= USER_SAVEDKEYS_STAT_INIT
;
3093 ar
->user_key_ctrl
= 0;
3097 #endif /* USER_KEYS */
3101 ar6000_dset_open_req(
3104 A_UINT32 targHandle
,
3105 A_UINT32 targReplyFn
,
3106 A_UINT32 targReplyArg
)
3113 A_UINT32 access_cookie
)
3119 ar6000_dset_data_req(
3121 A_UINT32 accessCookie
,
3125 A_UINT32 targReplyFn
,
3126 A_UINT32 targReplyArg
)