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 */
51 unsigned int bypasswmi
= 0;
52 unsigned int debuglevel
= 0;
53 int tspecCompliance
= 1;
54 unsigned int busspeedlow
= 0;
55 unsigned int onebitmode
= 0;
56 unsigned int skipflash
= 0;
57 unsigned int wmitimeout
= 2;
58 unsigned int wlanNodeCaching
= 1;
59 unsigned int enableuartprint
= 0;
60 unsigned int logWmiRawMsgs
= 0;
61 unsigned int enabletimerwar
= 0;
62 unsigned int mbox_yield_limit
= 99;
63 int reduce_credit_dribble
= 1 + HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF
;
64 int allow_trace_signal
= 0;
65 #ifdef CONFIG_HOST_TCMD_SUPPORT
66 unsigned int testmode
=0;
69 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
70 module_param(bypasswmi
, int, 0644);
71 module_param(debuglevel
, int, 0644);
72 module_param(tspecCompliance
, int, 0644);
73 module_param(onebitmode
, int, 0644);
74 module_param(busspeedlow
, int, 0644);
75 module_param(skipflash
, int, 0644);
76 module_param(wmitimeout
, int, 0644);
77 module_param(wlanNodeCaching
, int, 0644);
78 module_param(logWmiRawMsgs
, int, 0644);
79 module_param(enableuartprint
, int, 0644);
80 module_param(enabletimerwar
, int, 0644);
81 module_param(mbox_yield_limit
, int, 0644);
82 module_param(reduce_credit_dribble
, int, 0644);
83 module_param(allow_trace_signal
, int, 0644);
84 #ifdef CONFIG_HOST_TCMD_SUPPORT
85 module_param(testmode
, int, 0644);
90 /* for linux 2.4 and lower */
91 MODULE_PARM(bypasswmi
,"i");
92 MODULE_PARM(debuglevel
, "i");
93 MODULE_PARM(onebitmode
,"i");
94 MODULE_PARM(busspeedlow
, "i");
95 MODULE_PARM(skipflash
, "i");
96 MODULE_PARM(wmitimeout
, "i");
97 MODULE_PARM(wlanNodeCaching
, "i");
98 MODULE_PARM(enableuartprint
,"i");
99 MODULE_PARM(logWmiRawMsgs
, "i");
100 MODULE_PARM(enabletimerwar
,"i");
101 MODULE_PARM(mbox_yield_limit
,"i");
102 MODULE_PARM(reduce_credit_dribble
,"i");
103 MODULE_PARM(allow_trace_signal
,"i");
104 #ifdef CONFIG_HOST_TCMD_SUPPORT
105 MODULE_PARM(testmode
, "i");
109 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
110 /* in 2.6.10 and later this is now a pointer to a uint */
111 unsigned int _mboxnum
= HTC_MAILBOX_NUM_MAX
;
112 #define mboxnum &_mboxnum
114 unsigned int mboxnum
= HTC_MAILBOX_NUM_MAX
;
117 #ifdef CONFIG_AR6000_WLAN_RESET
118 unsigned int resetok
= 1;
120 unsigned int resetok
= 0;
124 A_UINT32 g_dbg_flags
= DBG_DEFAULTS
;
125 unsigned int debugflags
= 0;
127 unsigned int debughtc
= 128;
128 unsigned int debugbmi
= 1;
129 unsigned int debughif
= 2;
130 unsigned int txcreditsavailable
[HTC_MAILBOX_NUM_MAX
] = {0};
131 unsigned int txcreditsconsumed
[HTC_MAILBOX_NUM_MAX
] = {0};
132 unsigned int txcreditintrenable
[HTC_MAILBOX_NUM_MAX
] = {0};
133 unsigned int txcreditintrenableaggregate
[HTC_MAILBOX_NUM_MAX
] = {0};
135 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
136 module_param(debugflags
, int, 0644);
137 module_param(debugdriver
, int, 0644);
138 module_param(debughtc
, int, 0644);
139 module_param(debugbmi
, int, 0644);
140 module_param(debughif
, int, 0644);
141 module_param(resetok
, int, 0644);
142 module_param_array(txcreditsavailable
, int, mboxnum
, 0644);
143 module_param_array(txcreditsconsumed
, int, mboxnum
, 0644);
144 module_param_array(txcreditintrenable
, int, mboxnum
, 0644);
145 module_param_array(txcreditintrenableaggregate
, int, mboxnum
, 0644);
147 /* linux 2.4 and lower */
148 MODULE_PARM(debugflags
,"i");
149 MODULE_PARM(debugdriver
, "i");
150 MODULE_PARM(debughtc
, "i");
151 MODULE_PARM(debugbmi
, "i");
152 MODULE_PARM(debughif
, "i");
153 MODULE_PARM(resetok
, "i");
154 MODULE_PARM(txcreditsavailable
, "0-3i");
155 MODULE_PARM(txcreditsconsumed
, "0-3i");
156 MODULE_PARM(txcreditintrenable
, "0-3i");
157 MODULE_PARM(txcreditintrenableaggregate
, "0-3i");
162 unsigned int tx_attempt
[HTC_MAILBOX_NUM_MAX
] = {0};
163 unsigned int tx_post
[HTC_MAILBOX_NUM_MAX
] = {0};
164 unsigned int tx_complete
[HTC_MAILBOX_NUM_MAX
] = {0};
165 unsigned int hifBusRequestNumMax
= 40;
166 unsigned int war23838_disabled
= 0;
167 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
168 unsigned int enableAPTCHeuristics
= 1;
169 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
170 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
171 module_param_array(tx_attempt
, int, mboxnum
, 0644);
172 module_param_array(tx_post
, int, mboxnum
, 0644);
173 module_param_array(tx_complete
, int, mboxnum
, 0644);
174 module_param(hifBusRequestNumMax
, int, 0644);
175 module_param(war23838_disabled
, int, 0644);
176 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
177 module_param(enableAPTCHeuristics
, int, 0644);
178 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
180 MODULE_PARM(tx_attempt
, "0-3i");
181 MODULE_PARM(tx_post
, "0-3i");
182 MODULE_PARM(tx_complete
, "0-3i");
183 MODULE_PARM(hifBusRequestNumMax
, "i");
184 MODULE_PARM(war23838_disabled
, "i");
185 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
186 MODULE_PARM(enableAPTCHeuristics
, "i");
187 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
190 #ifdef BLOCK_TX_PATH_FLAG
192 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
193 module_param(blocktx
, int, 0644);
195 MODULE_PARM(blocktx
, "i");
197 #endif /* BLOCK_TX_PATH_FLAG */
199 // TODO move to arsoft_c
200 USER_RSSI_THOLD rssi_map
[12];
202 int reconnect_flag
= 0;
204 DECLARE_WAIT_QUEUE_HEAD(ar6000_scan_queue
);
206 /* Function declarations */
207 static int ar6000_init_module(void);
208 static void ar6000_cleanup_module(void);
210 int ar6000_init(struct net_device
*dev
);
211 static int ar6000_open(struct net_device
*dev
);
212 static int ar6000_close(struct net_device
*dev
);
213 static int ar6000_cleanup(struct net_device
*dev
);
214 static void ar6000_init_control_info(AR_SOFTC_T
*ar
);
215 static int ar6000_data_tx(struct sk_buff
*skb
, struct net_device
*dev
);
217 static void ar6000_destroy(struct net_device
*dev
, unsigned int unregister
);
218 static void ar6000_detect_error(unsigned long ptr
);
219 static struct net_device_stats
*ar6000_get_stats(struct net_device
*dev
);
220 static struct iw_statistics
*ar6000_get_iwstats(struct net_device
* dev
);
223 * HTC service connection handlers
225 static void ar6000_avail_ev(HTC_HANDLE HTCHandle
);
227 static void ar6000_unavail_ev(void *Instance
);
229 static void ar6000_target_failure(void *Instance
, A_STATUS Status
);
231 static void ar6000_rx(void *Context
, HTC_PACKET
*pPacket
);
233 static void ar6000_rx_refill(void *Context
,HTC_ENDPOINT_ID Endpoint
);
235 static void ar6000_tx_complete(void *Context
, HTC_PACKET
*pPacket
);
237 static void ar6000_tx_queue_full(void *Context
, HTC_ENDPOINT_ID Endpoint
);
239 static void ar6000_tx_queue_avail(void *Context
, HTC_ENDPOINT_ID Endpoint
);
245 static struct net_device
*ar6000_devices
[MAX_AR6000
];
246 extern struct iw_handler_def ath_iw_handler_def
;
247 DECLARE_WAIT_QUEUE_HEAD(arEvent
);
248 static void ar6000_cookie_init(AR_SOFTC_T
*ar
);
249 static void ar6000_cookie_cleanup(AR_SOFTC_T
*ar
);
250 static void ar6000_free_cookie(AR_SOFTC_T
*ar
, struct ar_cookie
* cookie
);
251 static struct ar_cookie
*ar6000_alloc_cookie(AR_SOFTC_T
*ar
);
252 static void ar6000_TxDataCleanup(AR_SOFTC_T
*ar
);
255 static A_STATUS
ar6000_reinstall_keys(AR_SOFTC_T
*ar
,A_UINT8 key_op_ctrl
);
259 static struct ar_cookie s_ar_cookie_mem
[MAX_COOKIE_NUM
];
261 #define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
262 ((ar->arTargetType == TARGET_TYPE_AR6001) ? \
263 AR6001_HOST_INTEREST_ITEM_ADDRESS(item) : \
264 AR6002_HOST_INTEREST_ITEM_ADDRESS(item))
267 /* Debug log support */
270 * Flag to govern whether the debug logs should be parsed in the kernel
271 * or reported to the application.
274 #define REPORT_DEBUG_LOGS_TO_APP
278 ar6000_set_host_app_area(AR_SOFTC_T
*ar
)
280 A_UINT32 address
, data
;
281 struct host_app_area_s host_app_area
;
283 /* Fetch the address of the host_app_area_s instance in the host interest area */
284 address
= HOST_INTEREST_ITEM_ADDRESS(ar
, hi_app_host_interest
);
285 if (ar6000_ReadRegDiag(ar
->arHifDevice
, &address
, &data
) != A_OK
) {
289 host_app_area
.wmi_protocol_ver
= WMI_PROTOCOL_VERSION
;
290 if (ar6000_WriteDataDiag(ar
->arHifDevice
, address
,
291 (A_UCHAR
*)&host_app_area
,
292 sizeof(struct host_app_area_s
)) != A_OK
)
301 dbglog_get_debug_hdr_ptr(AR_SOFTC_T
*ar
)
307 address
= HOST_INTEREST_ITEM_ADDRESS(ar
, hi_dbglog_hdr
);
308 if ((status
= ar6000_ReadDataDiag(ar
->arHifDevice
, address
,
309 (A_UCHAR
*)¶m
, 4)) != A_OK
)
318 * The dbglog module has been initialized. Its ok to access the relevant
319 * data stuctures over the diagnostic window.
322 ar6000_dbglog_init_done(AR_SOFTC_T
*ar
)
324 ar
->dbglog_init_done
= TRUE
;
328 dbglog_get_debug_fragment(A_INT8
*datap
, A_UINT32 len
, A_UINT32 limit
)
337 buffer
= (A_INT32
*)datap
;
338 length
= (limit
>> 2);
343 while (count
< length
) {
344 numargs
= DBGLOG_GET_NUMARGS(buffer
[count
]);
345 fraglen
= (count
<< 2);
346 count
+= numargs
+ 1;
354 dbglog_parse_debug_logs(A_INT8
*datap
, A_UINT32 len
)
365 buffer
= (A_INT32
*)datap
;
367 while (count
< length
) {
368 debugid
= DBGLOG_GET_DBGID(buffer
[count
]);
369 moduleid
= DBGLOG_GET_MODULEID(buffer
[count
]);
370 numargs
= DBGLOG_GET_NUMARGS(buffer
[count
]);
371 timestamp
= DBGLOG_GET_TIMESTAMP(buffer
[count
]);
374 AR_DEBUG_PRINTF("%d %d (%d)\n", moduleid
, debugid
, timestamp
);
378 AR_DEBUG_PRINTF("%d %d (%d): 0x%x\n", moduleid
, debugid
,
379 timestamp
, buffer
[count
+1]);
383 AR_DEBUG_PRINTF("%d %d (%d): 0x%x, 0x%x\n", moduleid
, debugid
,
384 timestamp
, buffer
[count
+1], buffer
[count
+2]);
388 AR_DEBUG_PRINTF("Invalid args: %d\n", numargs
);
390 count
+= numargs
+ 1;
395 ar6000_dbglog_get_debug_logs(AR_SOFTC_T
*ar
)
397 struct dbglog_hdr_s debug_hdr
;
398 struct dbglog_buf_s debug_buf
;
403 A_UINT32 debug_hdr_ptr
;
405 if (!ar
->dbglog_init_done
) return A_ERROR
;
407 #ifndef CONFIG_AR6000_WLAN_DEBUG
411 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
413 if (ar
->dbgLogFetchInProgress
) {
414 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
418 /* block out others */
419 ar
->dbgLogFetchInProgress
= TRUE
;
421 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
423 debug_hdr_ptr
= dbglog_get_debug_hdr_ptr(ar
);
424 printk("debug_hdr_ptr: 0x%x\n", debug_hdr_ptr
);
426 /* Get the contents of the ring buffer */
428 address
= debug_hdr_ptr
;
429 length
= sizeof(struct dbglog_hdr_s
);
430 ar6000_ReadDataDiag(ar
->arHifDevice
, address
,
431 (A_UCHAR
*)&debug_hdr
, length
);
432 address
= (A_UINT32
)debug_hdr
.dbuf
;
434 dropped
= debug_hdr
.dropped
;
435 length
= sizeof(struct dbglog_buf_s
);
436 ar6000_ReadDataDiag(ar
->arHifDevice
, address
,
437 (A_UCHAR
*)&debug_buf
, length
);
440 address
= (A_UINT32
)debug_buf
.buffer
;
441 length
= debug_buf
.length
;
442 if ((length
) && (debug_buf
.length
<= debug_buf
.bufsize
)) {
443 /* Rewind the index if it is about to overrun the buffer */
444 if (ar
->log_cnt
> (DBGLOG_HOST_LOG_BUFFER_SIZE
- length
)) {
447 if(A_OK
!= ar6000_ReadDataDiag(ar
->arHifDevice
, address
,
448 (A_UCHAR
*)&ar
->log_buffer
[ar
->log_cnt
], length
))
452 ar6000_dbglog_event(ar
, dropped
, &ar
->log_buffer
[ar
->log_cnt
], length
);
453 ar
->log_cnt
+= length
;
455 AR_DEBUG_PRINTF("Length: %d (Total size: %d)\n",
456 debug_buf
.length
, debug_buf
.bufsize
);
459 address
= (A_UINT32
)debug_buf
.next
;
460 length
= sizeof(struct dbglog_buf_s
);
461 if(A_OK
!= ar6000_ReadDataDiag(ar
->arHifDevice
, address
,
462 (A_UCHAR
*)&debug_buf
, length
))
467 } while (address
!= firstbuf
);
470 ar
->dbgLogFetchInProgress
= FALSE
;
476 ar6000_dbglog_event(AR_SOFTC_T
*ar
, A_UINT32 dropped
,
477 A_INT8
*buffer
, A_UINT32 length
)
479 #ifdef REPORT_DEBUG_LOGS_TO_APP
480 #define MAX_WIRELESS_EVENT_SIZE 252
482 * Break it up into chunks of MAX_WIRELESS_EVENT_SIZE bytes of messages.
483 * There seems to be a limitation on the length of message that could be
484 * transmitted to the user app via this mechanism.
489 send
= dbglog_get_debug_fragment(&buffer
[sent
], length
- sent
,
490 MAX_WIRELESS_EVENT_SIZE
);
492 ar6000_send_event_to_app(ar
, WMIX_DBGLOG_EVENTID
, &buffer
[sent
], send
);
494 send
= dbglog_get_debug_fragment(&buffer
[sent
], length
- sent
,
495 MAX_WIRELESS_EVENT_SIZE
);
498 AR_DEBUG_PRINTF("Dropped logs: 0x%x\nDebug info length: %d\n",
501 /* Interpret the debug logs */
502 dbglog_parse_debug_logs(buffer
, length
);
503 #endif /* REPORT_DEBUG_LOGS_TO_APP */
509 ar6000_init_module(void)
511 static int probed
= 0;
513 HTC_INIT_INFO initInfo
;
515 A_MEMZERO(&initInfo
,sizeof(initInfo
));
516 initInfo
.AddInstance
= ar6000_avail_ev
;
517 initInfo
.DeleteInstance
= ar6000_unavail_ev
;
518 initInfo
.TargetFailure
= ar6000_target_failure
;
522 /* Set the debug flags if specified at load time */
525 g_dbg_flags
= debugflags
;
534 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
535 memset(&aptcTR
, 0, sizeof(APTC_TRAFFIC_RECORD
));
536 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
538 #ifdef CONFIG_HOST_GPIO_SUPPORT
540 #endif /* CONFIG_HOST_GPIO_SUPPORT */
542 status
= HTCInit(&initInfo
);
550 ar6000_cleanup_module(void)
553 struct net_device
*ar6000_netdev
;
555 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
556 /* Delete the Adaptive Power Control timer */
557 if (timer_pending(&aptcTimer
)) {
558 del_timer_sync(&aptcTimer
);
560 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
562 for (i
=0; i
< MAX_AR6000
; i
++) {
563 if (ar6000_devices
[i
] != NULL
) {
564 ar6000_netdev
= ar6000_devices
[i
];
565 ar6000_devices
[i
] = NULL
;
566 ar6000_destroy(ar6000_netdev
, 1);
570 /* shutting down HTC will cause the HIF layer to detach from the
571 * underlying bus driver which will cause the subsequent deletion of
572 * all HIF and HTC instances */
575 AR_DEBUG_PRINTF("ar6000_cleanup: success\n");
578 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
580 aptcTimerHandler(unsigned long arg
)
587 ar
= (AR_SOFTC_T
*)arg
;
588 A_ASSERT(ar
!= NULL
);
589 A_ASSERT(!timer_pending(&aptcTimer
));
591 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
593 /* Get the number of bytes transferred */
594 numbytes
= aptcTR
.bytesTransmitted
+ aptcTR
.bytesReceived
;
595 aptcTR
.bytesTransmitted
= aptcTR
.bytesReceived
= 0;
597 /* Calculate and decide based on throughput thresholds */
598 throughput
= ((numbytes
* 8)/APTC_TRAFFIC_SAMPLING_INTERVAL
); /* Kbps */
599 if (throughput
< APTC_LOWER_THROUGHPUT_THRESHOLD
) {
600 /* Enable Sleep and delete the timer */
601 A_ASSERT(ar
->arWmiReady
== TRUE
);
602 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
603 status
= wmi_powermode_cmd(ar
->arWmi
, REC_POWER
);
604 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
605 A_ASSERT(status
== A_OK
);
606 aptcTR
.timerScheduled
= FALSE
;
608 A_TIMEOUT_MS(&aptcTimer
, APTC_TRAFFIC_SAMPLING_INTERVAL
, 0);
611 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
613 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
617 /* set HTC block size, assume BMI is already initialized */
618 A_STATUS
ar6000_SetHTCBlockSize(AR_SOFTC_T
*ar
)
621 A_UINT32 blocksizes
[HTC_MAILBOX_NUM_MAX
];
624 /* get the block sizes */
625 status
= HIFConfigureDevice(ar
->arHifDevice
, HIF_DEVICE_GET_MBOX_BLOCK_SIZE
,
626 blocksizes
, sizeof(blocksizes
));
628 if (A_FAILED(status
)) {
629 AR_DEBUG_PRINTF("Failed to get block size info from HIF layer...\n");
632 /* note: we actually get the block size for mailbox 1, for SDIO the block
633 * size on mailbox 0 is artificially set to 1 */
634 /* must be a power of 2 */
635 A_ASSERT((blocksizes
[1] & (blocksizes
[1] - 1)) == 0);
637 /* set the host interest area for the block size */
638 status
= BMIWriteMemory(ar
->arHifDevice
,
639 HOST_INTEREST_ITEM_ADDRESS(ar
, hi_mbox_io_block_sz
),
640 (A_UCHAR
*)&blocksizes
[1],
643 if (A_FAILED(status
)) {
644 AR_DEBUG_PRINTF("BMIWriteMemory for IO block size failed \n");
648 AR_DEBUG_PRINTF("Block Size Set: %d (target address:0x%X)\n",
649 blocksizes
[1], HOST_INTEREST_ITEM_ADDRESS(ar
, hi_mbox_io_block_sz
));
651 /* set the host interest area for the mbox ISR yield limit */
652 status
= BMIWriteMemory(ar
->arHifDevice
,
653 HOST_INTEREST_ITEM_ADDRESS(ar
, hi_mbox_isr_yield_limit
),
654 (A_UCHAR
*)&mbox_yield_limit
,
657 if (A_FAILED(status
)) {
658 AR_DEBUG_PRINTF("BMIWriteMemory for yield limit failed \n");
667 static void free_raw_buffers(AR_SOFTC_T
*ar
)
671 for (i
= 0; i
!= HTC_RAW_STREAM_NUM_MAX
; i
++) {
672 for (j
= 0; j
!= RAW_HTC_READ_BUFFERS_NUM
; j
++)
673 kfree(ar
->raw_htc_read_buffer
[i
][j
]);
674 for (j
= 0; j
!= RAW_HTC_WRITE_BUFFERS_NUM
; j
++)
675 kfree(ar
->raw_htc_write_buffer
[i
][j
]);
679 static int alloc_raw_buffers(AR_SOFTC_T
*ar
)
684 for (i
= 0; i
!= HTC_RAW_STREAM_NUM_MAX
; i
++) {
685 for (j
= 0; j
!= RAW_HTC_READ_BUFFERS_NUM
; j
++) {
686 b
= kzalloc(sizeof(*b
), GFP_KERNEL
);
689 ar
->raw_htc_read_buffer
[i
][j
] = b
;
691 for (j
= 0; j
!= RAW_HTC_WRITE_BUFFERS_NUM
; j
++) {
692 b
= kzalloc(sizeof(*b
), GFP_KERNEL
);
695 ar
->raw_htc_write_buffer
[i
][j
] = b
;
701 static const struct net_device_ops ar6000_netdev_ops
= {
702 .ndo_init
= &ar6000_init
,
703 .ndo_open
= &ar6000_open
,
704 .ndo_stop
= &ar6000_close
,
705 .ndo_start_xmit
= &ar6000_data_tx
,
706 .ndo_get_stats
= &ar6000_get_stats
,
707 .ndo_do_ioctl
= &ar6000_ioctl
,
713 ar6000_avail_ev(HTC_HANDLE HTCHandle
)
716 struct net_device
*dev
;
718 int device_index
= 0;
720 AR_DEBUG_PRINTF("ar6000_available\n");
722 for (i
=0; i
< MAX_AR6000
; i
++) {
723 if (ar6000_devices
[i
] == NULL
) {
728 if (i
== MAX_AR6000
) {
729 AR_DEBUG_PRINTF("ar6000_available: max devices reached\n");
733 /* Save this. It gives a bit better readability especially since */
734 /* we use another local "i" variable below. */
737 A_ASSERT(HTCHandle
!= NULL
);
739 dev
= alloc_etherdev(sizeof(AR_SOFTC_T
));
741 AR_DEBUG_PRINTF("ar6000_available: can't alloc etherdev\n");
747 if (netdev_priv(dev
) == NULL
) {
748 printk(KERN_CRIT
"ar6000_available: Could not allocate memory\n");
752 A_MEMZERO(netdev_priv(dev
), sizeof(AR_SOFTC_T
));
754 ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
756 ar
->arHtcTarget
= HTCHandle
;
757 ar
->arHifDevice
= HTCGetHifDevice(HTCHandle
);
758 ar
->arWlanState
= WLAN_ENABLED
;
759 ar
->arRadioSwitch
= WLAN_ENABLED
;
760 ar
->arDeviceIndex
= device_index
;
762 A_INIT_TIMER(&ar
->arHBChallengeResp
.timer
, ar6000_detect_error
, dev
);
763 ar
->arHBChallengeResp
.seqNum
= 0;
764 ar
->arHBChallengeResp
.outstanding
= FALSE
;
765 ar
->arHBChallengeResp
.missCnt
= 0;
766 ar
->arHBChallengeResp
.frequency
= AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT
;
767 ar
->arHBChallengeResp
.missThres
= AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT
;
769 ar6000_init_control_info(ar
);
770 init_waitqueue_head(&arEvent
);
771 sema_init(&ar
->arSem
, 1);
773 if (alloc_raw_buffers(ar
)) {
774 free_raw_buffers(ar
);
776 * @@@ Clean up our own mess, but for anything else, cheerfully mimick
777 * the beautiful error non-handling of the rest of this function.
782 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
783 A_INIT_TIMER(&aptcTimer
, aptcTimerHandler
, ar
);
784 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
787 * If requested, perform some magic which requires no cooperation from
788 * the Target. It causes the Target to ignore flash and execute to the
791 * This is intended to support recovery from a corrupted flash on Targets
792 * that support flash.
796 ar6000_reset_device_skipflash(ar
->arHifDevice
);
801 struct bmi_target_info targ_info
;
803 if (BMIGetTargetInfo(ar
->arHifDevice
, &targ_info
) != A_OK
) {
807 ar
->arVersion
.target_ver
= targ_info
.target_ver
;
808 ar
->arTargetType
= targ_info
.target_type
;
811 if (enableuartprint
) {
814 if (BMIWriteMemory(ar
->arHifDevice
,
815 HOST_INTEREST_ITEM_ADDRESS(ar
, hi_serial_enable
),
819 AR_DEBUG_PRINTF("BMIWriteMemory for enableuartprint failed \n");
822 AR_DEBUG_PRINTF("Serial console prints enabled\n");
824 #ifdef CONFIG_HOST_TCMD_SUPPORT
826 ar
->arTargetMode
= AR6000_TCMD_MODE
;
828 ar
->arTargetMode
= AR6000_WLAN_MODE
;
831 if (enabletimerwar
) {
834 if (BMIReadMemory(ar
->arHifDevice
,
835 HOST_INTEREST_ITEM_ADDRESS(ar
, hi_option_flag
),
839 AR_DEBUG_PRINTF("BMIReadMemory for enabletimerwar failed \n");
843 param
|= HI_OPTION_TIMER_WAR
;
845 if (BMIWriteMemory(ar
->arHifDevice
,
846 HOST_INTEREST_ITEM_ADDRESS(ar
, hi_option_flag
),
850 AR_DEBUG_PRINTF("BMIWriteMemory for enabletimerwar failed \n");
853 AR_DEBUG_PRINTF("Timer WAR enabled\n");
857 /* since BMIInit is called in the driver layer, we have to set the block
858 * size here for the target */
860 if (A_FAILED(ar6000_SetHTCBlockSize(ar
))) {
864 spin_lock_init(&ar
->arLock
);
866 dev
->netdev_ops
= &ar6000_netdev_ops
;
867 dev
->watchdog_timeo
= AR6000_TX_TIMEOUT
;
868 ar6000_ioctl_iwsetup(&ath_iw_handler_def
);
869 dev
->wireless_handlers
= &ath_iw_handler_def
;
870 ath_iw_handler_def
.get_wireless_stats
= ar6000_get_iwstats
; /*Displayed via proc fs */
873 * We need the OS to provide us with more headroom in order to
874 * perform dix to 802.3, WMI header encap, and the HTC header
876 dev
->hard_header_len
= ETH_HLEN
+ sizeof(ATH_LLC_SNAP_HDR
) +
877 sizeof(WMI_DATA_HDR
) + HTC_HEADER_LEN
;
879 /* This runs the init function */
880 SET_NETDEV_DEV(dev
, HIFGetOSDevice(ar
->arHifDevice
));
881 if (register_netdev(dev
)) {
882 AR_DEBUG_PRINTF("ar6000_avail: register_netdev failed\n");
883 ar6000_destroy(dev
, 0);
887 HTCSetInstance(ar
->arHtcTarget
, ar
);
889 /* We only register the device in the global list if we succeed. */
890 /* If the device is in the global list, it will be destroyed */
891 /* when the module is unloaded. */
892 ar6000_devices
[device_index
] = dev
;
894 AR_DEBUG_PRINTF("ar6000_avail: name=%s htcTarget=0x%x, dev=0x%x (%d), ar=0x%x\n",
895 dev
->name
, (A_UINT32
)HTCHandle
, (A_UINT32
)dev
, device_index
,
899 static void ar6000_target_failure(void *Instance
, A_STATUS Status
)
901 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Instance
;
902 WMI_TARGET_ERROR_REPORT_EVENT errEvent
;
903 static A_BOOL sip
= FALSE
;
905 if (Status
!= A_OK
) {
906 if (timer_pending(&ar
->arHBChallengeResp
.timer
)) {
907 A_UNTIMEOUT(&ar
->arHBChallengeResp
.timer
);
910 /* try dumping target assertion information (if any) */
911 ar6000_dump_target_assert_info(ar
->arHifDevice
,ar
->arTargetType
);
914 * Fetch the logs from the target via the diagnostic
917 ar6000_dbglog_get_debug_logs(ar
);
919 /* Report the error only once */
922 errEvent
.errorVal
= WMI_TARGET_COM_ERR
|
923 WMI_TARGET_FATAL_ERR
;
924 #ifdef SEND_EVENT_TO_APP
925 ar6000_send_event_to_app(ar
, WMI_ERROR_REPORT_EVENTID
,
926 (A_UINT8
*)&errEvent
,
927 sizeof(WMI_TARGET_ERROR_REPORT_EVENT
));
934 ar6000_unavail_ev(void *Instance
)
936 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Instance
;
937 /* NULL out it's entry in the global list */
938 ar6000_devices
[ar
->arDeviceIndex
] = NULL
;
939 ar6000_destroy(ar
->arNetDev
, 1);
943 * We need to differentiate between the surprise and planned removal of the
944 * device because of the following consideration:
945 * - In case of surprise removal, the hcd already frees up the pending
946 * for the device and hence there is no need to unregister the function
947 * driver inorder to get these requests. For planned removal, the function
948 * driver has to explictly unregister itself to have the hcd return all the
949 * pending requests before the data structures for the devices are freed up.
950 * Note that as per the current implementation, the function driver will
951 * end up releasing all the devices since there is no API to selectively
952 * release a particular device.
953 * - Certain commands issued to the target can be skipped for surprise
954 * removal since they will anyway not go through.
957 ar6000_destroy(struct net_device
*dev
, unsigned int unregister
)
961 AR_DEBUG_PRINTF("+ar6000_destroy \n");
963 if((dev
== NULL
) || ((ar
= netdev_priv(dev
)) == NULL
))
965 AR_DEBUG_PRINTF("%s(): Failed to get device structure.\n", __func__
);
969 /* Clear the tx counters */
970 memset(tx_attempt
, 0, sizeof(tx_attempt
));
971 memset(tx_post
, 0, sizeof(tx_post
));
972 memset(tx_complete
, 0, sizeof(tx_complete
));
974 /* Free up the device data structure */
976 unregister_netdev(dev
);
982 free_raw_buffers(ar
);
990 AR_DEBUG_PRINTF("-ar6000_destroy \n");
993 static void ar6000_detect_error(unsigned long ptr
)
995 struct net_device
*dev
= (struct net_device
*)ptr
;
996 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
997 WMI_TARGET_ERROR_REPORT_EVENT errEvent
;
999 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1001 if (ar
->arHBChallengeResp
.outstanding
) {
1002 ar
->arHBChallengeResp
.missCnt
++;
1004 ar
->arHBChallengeResp
.missCnt
= 0;
1007 if (ar
->arHBChallengeResp
.missCnt
> ar
->arHBChallengeResp
.missThres
) {
1008 /* Send Error Detect event to the application layer and do not reschedule the error detection module timer */
1009 ar
->arHBChallengeResp
.missCnt
= 0;
1010 ar
->arHBChallengeResp
.seqNum
= 0;
1011 errEvent
.errorVal
= WMI_TARGET_COM_ERR
| WMI_TARGET_FATAL_ERR
;
1012 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1013 #ifdef SEND_EVENT_TO_APP
1014 ar6000_send_event_to_app(ar
, WMI_ERROR_REPORT_EVENTID
,
1015 (A_UINT8
*)&errEvent
,
1016 sizeof(WMI_TARGET_ERROR_REPORT_EVENT
));
1021 /* Generate the sequence number for the next challenge */
1022 ar
->arHBChallengeResp
.seqNum
++;
1023 ar
->arHBChallengeResp
.outstanding
= TRUE
;
1025 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1027 /* Send the challenge on the control channel */
1028 if (wmi_get_challenge_resp_cmd(ar
->arWmi
, ar
->arHBChallengeResp
.seqNum
, DRV_HB_CHALLENGE
) != A_OK
) {
1029 AR_DEBUG_PRINTF("Unable to send heart beat challenge\n");
1033 /* Reschedule the timer for the next challenge */
1034 A_TIMEOUT_MS(&ar
->arHBChallengeResp
.timer
, ar
->arHBChallengeResp
.frequency
* 1000, 0);
1037 void ar6000_init_profile_info(AR_SOFTC_T
*ar
)
1040 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
1041 ar
->arNetworkType
= INFRA_NETWORK
;
1042 ar
->arDot11AuthMode
= OPEN_AUTH
;
1043 ar
->arAuthMode
= NONE_AUTH
;
1044 ar
->arPairwiseCrypto
= NONE_CRYPT
;
1045 ar
->arPairwiseCryptoLen
= 0;
1046 ar
->arGroupCrypto
= NONE_CRYPT
;
1047 ar
->arGroupCryptoLen
= 0;
1048 A_MEMZERO(ar
->arWepKeyList
, sizeof(ar
->arWepKeyList
));
1049 A_MEMZERO(ar
->arReqBssid
, sizeof(ar
->arReqBssid
));
1050 A_MEMZERO(ar
->arBssid
, sizeof(ar
->arBssid
));
1051 ar
->arBssChannel
= 0;
1055 ar6000_init_control_info(AR_SOFTC_T
*ar
)
1057 ar
->arWmiEnabled
= FALSE
;
1058 ar6000_init_profile_info(ar
);
1059 ar
->arDefTxKeyIndex
= 0;
1060 A_MEMZERO(ar
->arWepKeyList
, sizeof(ar
->arWepKeyList
));
1061 ar
->arChannelHint
= 0;
1062 ar
->arListenInterval
= MAX_LISTEN_INTERVAL
;
1063 ar
->arVersion
.host_ver
= AR6K_SW_VERSION
;
1066 ar
->arTxPwrSet
= FALSE
;
1068 ar
->arBeaconInterval
= 0;
1070 ar
->arMaxRetries
= 0;
1071 ar
->arWmmEnabled
= TRUE
;
1075 ar6000_open(struct net_device
*dev
)
1077 /* Wake up the queues */
1078 netif_start_queue(dev
);
1084 ar6000_close(struct net_device
*dev
)
1086 /* Stop the transmit queues */
1087 netif_stop_queue(dev
);
1092 ar6000_cleanup(struct net_device
*dev
)
1094 AR_SOFTC_T
*ar
= netdev_priv(dev
);
1096 /* Stop the transmit queues */
1097 netif_stop_queue(dev
);
1099 /* Disable the target and the interrupts associated with it */
1100 if (ar
->arWmiReady
== TRUE
)
1104 if (ar
->arConnected
== TRUE
|| ar
->arConnectPending
== TRUE
)
1106 AR_DEBUG_PRINTF("%s(): Disconnect\n", __func__
);
1107 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1108 ar6000_init_profile_info(ar
);
1109 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1110 wmi_disconnect_cmd(ar
->arWmi
);
1113 ar6000_dbglog_get_debug_logs(ar
);
1114 ar
->arWmiReady
= FALSE
;
1115 ar
->arConnected
= FALSE
;
1116 ar
->arConnectPending
= FALSE
;
1117 wmi_shutdown(ar
->arWmi
);
1118 ar
->arWmiEnabled
= FALSE
;
1120 ar
->arWlanState
= WLAN_ENABLED
;
1122 ar
->user_savedkeys_stat
= USER_SAVEDKEYS_STAT_INIT
;
1123 ar
->user_key_ctrl
= 0;
1127 AR_DEBUG_PRINTF("%s(): WMI stopped\n", __func__
);
1131 AR_DEBUG_PRINTF("%s(): WMI not ready 0x%08x 0x%08x\n",
1132 __func__
, (unsigned int) ar
, (unsigned int) ar
->arWmi
);
1134 /* Shut down WMI if we have started it */
1135 if(ar
->arWmiEnabled
== TRUE
)
1137 AR_DEBUG_PRINTF("%s(): Shut down WMI\n", __func__
);
1138 wmi_shutdown(ar
->arWmi
);
1139 ar
->arWmiEnabled
= FALSE
;
1145 HTCStop(ar
->arHtcTarget
);
1147 /* set the instance to NULL so we do not get called back on remove incase we
1148 * we're explicity destroyed by module unload */
1149 HTCSetInstance(ar
->arHtcTarget
, NULL
);
1152 /* try to reset the device if we can
1153 * The driver may have been configure NOT to reset the target during
1154 * a debug session */
1155 AR_DEBUG_PRINTF(" Attempting to reset target on instance destroy.... \n");
1156 ar6000_reset_device(ar
->arHifDevice
, ar
->arTargetType
);
1158 AR_DEBUG_PRINTF(" Host does not want target reset. \n");
1161 /* Done with cookies */
1162 ar6000_cookie_cleanup(ar
);
1170 /* connect to a service */
1171 static A_STATUS
ar6000_connectservice(AR_SOFTC_T
*ar
,
1172 HTC_SERVICE_CONNECT_REQ
*pConnect
,
1173 WMI_PRI_STREAM_ID WmiStreamID
,
1177 HTC_SERVICE_CONNECT_RESP response
;
1181 A_MEMZERO(&response
,sizeof(response
));
1183 status
= HTCConnectService(ar
->arHtcTarget
,
1187 if (A_FAILED(status
)) {
1188 AR_DEBUG_PRINTF(" Failed to connect to %s service status:%d \n", pDesc
, status
);
1192 if (WmiStreamID
== WMI_NOT_MAPPED
) {
1197 /* set endpoint mapping for the WMI stream in the driver layer */
1198 arSetWMIStream2EndpointIDMap(ar
,WmiStreamID
,response
.Endpoint
);
1205 static void ar6000_TxDataCleanup(AR_SOFTC_T
*ar
)
1207 /* flush all the data (non-control) streams
1208 * we only flush packets that are tagged as data, we leave any control packets that
1209 * were in the TX queues alone */
1210 HTCFlushEndpoint(ar
->arHtcTarget
,
1211 arWMIStream2EndpointID(ar
,WMI_BEST_EFFORT_PRI
),
1213 HTCFlushEndpoint(ar
->arHtcTarget
,
1214 arWMIStream2EndpointID(ar
,WMI_LOW_PRI
),
1216 HTCFlushEndpoint(ar
->arHtcTarget
,
1217 arWMIStream2EndpointID(ar
,WMI_HIGH_PRI
),
1219 HTCFlushEndpoint(ar
->arHtcTarget
,
1220 arWMIStream2EndpointID(ar
,WMI_HIGHEST_PRI
),
1224 /* This function does one time initialization for the lifetime of the device */
1225 int ar6000_init(struct net_device
*dev
)
1231 if((ar
= netdev_priv(dev
)) == NULL
)
1236 /* Do we need to finish the BMI phase */
1237 if(BMIDone(ar
->arHifDevice
) != A_OK
)
1245 if (ar
->arVersion
.host_ver
!= ar
->arVersion
.target_ver
) {
1246 A_PRINTF("WARNING: Host version 0x%x does not match Target "
1248 ar
->arVersion
.host_ver
, ar
->arVersion
.target_ver
);
1252 /* Indicate that WMI is enabled (although not ready yet) */
1253 ar
->arWmiEnabled
= TRUE
;
1254 if ((ar
->arWmi
= wmi_init((void *) ar
)) == NULL
)
1256 AR_DEBUG_PRINTF("%s() Failed to initialize WMI.\n", __func__
);
1260 AR_DEBUG_PRINTF("%s() Got WMI @ 0x%08x.\n", __func__
,
1261 (unsigned int) ar
->arWmi
);
1265 HTC_SERVICE_CONNECT_REQ connect
;
1267 /* the reason we have to wait for the target here is that the driver layer
1268 * has to init BMI in order to set the host block size,
1270 status
= HTCWaitTarget(ar
->arHtcTarget
);
1272 if (A_FAILED(status
)) {
1276 A_MEMZERO(&connect
,sizeof(connect
));
1277 /* meta data is unused for now */
1278 connect
.pMetaData
= NULL
;
1279 connect
.MetaDataLength
= 0;
1280 /* these fields are the same for all service endpoints */
1281 connect
.EpCallbacks
.pContext
= ar
;
1282 connect
.EpCallbacks
.EpTxComplete
= ar6000_tx_complete
;
1283 connect
.EpCallbacks
.EpRecv
= ar6000_rx
;
1284 connect
.EpCallbacks
.EpRecvRefill
= ar6000_rx_refill
;
1285 connect
.EpCallbacks
.EpSendFull
= ar6000_tx_queue_full
;
1286 connect
.EpCallbacks
.EpSendAvail
= ar6000_tx_queue_avail
;
1287 /* set the max queue depth so that our ar6000_tx_queue_full handler gets called.
1288 * Linux has the peculiarity of not providing flow control between the
1289 * NIC and the network stack. There is no API to indicate that a TX packet
1290 * was sent which could provide some back pressure to the network stack.
1291 * Under linux you would have to wait till the network stack consumed all sk_buffs
1292 * before any back-flow kicked in. Which isn't very friendly.
1293 * So we have to manage this ourselves */
1294 connect
.MaxSendQueueDepth
= 32;
1296 /* connect to control service */
1297 connect
.ServiceID
= WMI_CONTROL_SVC
;
1298 status
= ar6000_connectservice(ar
,
1302 if (A_FAILED(status
)) {
1306 /* for the remaining data services set the connection flag to reduce dribbling,
1307 * if configured to do so */
1308 if (reduce_credit_dribble
) {
1309 connect
.ConnectionFlags
|= HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE
;
1310 /* the credit dribble trigger threshold is (reduce_credit_dribble - 1) for a value
1312 connect
.ConnectionFlags
&= ~HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK
;
1313 connect
.ConnectionFlags
|=
1314 ((A_UINT16
)reduce_credit_dribble
- 1) & HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK
;
1316 /* connect to best-effort service */
1317 connect
.ServiceID
= WMI_DATA_BE_SVC
;
1319 status
= ar6000_connectservice(ar
,
1321 WMI_BEST_EFFORT_PRI
,
1323 if (A_FAILED(status
)) {
1327 /* connect to back-ground
1328 * map this to WMI LOW_PRI */
1329 connect
.ServiceID
= WMI_DATA_BK_SVC
;
1330 status
= ar6000_connectservice(ar
,
1334 if (A_FAILED(status
)) {
1338 /* connect to Video service, map this to
1340 connect
.ServiceID
= WMI_DATA_VI_SVC
;
1341 status
= ar6000_connectservice(ar
,
1345 if (A_FAILED(status
)) {
1349 /* connect to VO service, this is currently not
1350 * mapped to a WMI priority stream due to historical reasons.
1351 * WMI originally defined 3 priorities over 3 mailboxes
1352 * We can change this when WMI is reworked so that priorities are not
1353 * dependent on mailboxes */
1354 connect
.ServiceID
= WMI_DATA_VO_SVC
;
1355 status
= ar6000_connectservice(ar
,
1359 if (A_FAILED(status
)) {
1363 A_ASSERT(arWMIStream2EndpointID(ar
,WMI_CONTROL_PRI
) != 0);
1364 A_ASSERT(arWMIStream2EndpointID(ar
,WMI_BEST_EFFORT_PRI
) != 0);
1365 A_ASSERT(arWMIStream2EndpointID(ar
,WMI_LOW_PRI
) != 0);
1366 A_ASSERT(arWMIStream2EndpointID(ar
,WMI_HIGH_PRI
) != 0);
1367 A_ASSERT(arWMIStream2EndpointID(ar
,WMI_HIGHEST_PRI
) != 0);
1370 if (A_FAILED(status
)) {
1375 * give our connected endpoints some buffers
1377 ar6000_rx_refill(ar
, arWMIStream2EndpointID(ar
,WMI_CONTROL_PRI
));
1379 ar6000_rx_refill(ar
, arWMIStream2EndpointID(ar
,WMI_BEST_EFFORT_PRI
));
1382 * We will post the receive buffers only for SPE testing and so we are
1383 * making it conditional on the 'bypasswmi' flag.
1386 ar6000_rx_refill(ar
,arWMIStream2EndpointID(ar
,WMI_LOW_PRI
));
1387 ar6000_rx_refill(ar
,arWMIStream2EndpointID(ar
,WMI_HIGH_PRI
));
1390 /* setup credit distribution */
1391 ar6000_setup_credit_dist(ar
->arHtcTarget
, &ar
->arCreditStateInfo
);
1393 /* Since cookies are used for HTC transports, they should be */
1394 /* initialized prior to enabling HTC. */
1395 ar6000_cookie_init(ar
);
1398 status
= HTCStart(ar
->arHtcTarget
);
1400 if (status
!= A_OK
) {
1401 if (ar
->arWmiEnabled
== TRUE
) {
1402 wmi_shutdown(ar
->arWmi
);
1403 ar
->arWmiEnabled
= FALSE
;
1406 ar6000_cookie_cleanup(ar
);
1411 /* Wait for Wmi event to be ready */
1412 timeleft
= wait_event_interruptible_timeout(arEvent
,
1413 (ar
->arWmiReady
== TRUE
), wmitimeout
* HZ
);
1415 if(!timeleft
|| signal_pending(current
))
1417 AR_DEBUG_PRINTF("WMI is not ready or wait was interrupted\n");
1418 #if defined(DWSIM) /* TBDXXX */
1419 AR_DEBUG_PRINTF(".....but proceed anyway.\n");
1425 AR_DEBUG_PRINTF("%s() WMI is ready\n", __func__
);
1427 /* Communicate the wmi protocol verision to the target */
1428 if ((ar6000_set_host_app_area(ar
)) != A_OK
) {
1429 AR_DEBUG_PRINTF("Unable to set the host app area\n");
1433 ar
->arNumDataEndPts
= 1;
1440 ar6000_bitrate_rx(void *devt
, A_INT32 rateKbps
)
1442 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
1444 ar
->arBitRate
= rateKbps
;
1449 ar6000_ratemask_rx(void *devt
, A_UINT16 ratemask
)
1451 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
1453 ar
->arRateMask
= ratemask
;
1458 ar6000_txPwr_rx(void *devt
, A_UINT8 txPwr
)
1460 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
1462 ar
->arTxPwr
= txPwr
;
1468 ar6000_channelList_rx(void *devt
, A_INT8 numChan
, A_UINT16
*chanList
)
1470 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
1472 A_MEMCPY(ar
->arChannelList
, chanList
, numChan
* sizeof (A_UINT16
));
1473 ar
->arNumChannels
= numChan
;
1479 ar6000_ibss_map_epid(struct sk_buff
*skb
, struct net_device
*dev
, A_UINT32
* mapNo
)
1481 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1483 ATH_MAC_HDR
*macHdr
;
1487 datap
= A_NETBUF_DATA(skb
);
1488 macHdr
= (ATH_MAC_HDR
*)(datap
+ sizeof(WMI_DATA_HDR
));
1489 if (IEEE80211_IS_MULTICAST(macHdr
->dstMac
)) {
1494 for (i
= 0; i
< ar
->arNodeNum
; i
++) {
1495 if (IEEE80211_ADDR_EQ(macHdr
->dstMac
, ar
->arNodeMap
[i
].macAddress
)) {
1497 ar
->arNodeMap
[i
].txPending
++;
1498 return ar
->arNodeMap
[i
].epId
;
1501 if ((eptMap
== -1) && !ar
->arNodeMap
[i
].txPending
) {
1507 eptMap
= ar
->arNodeNum
;
1509 A_ASSERT(ar
->arNodeNum
<= MAX_NODE_NUM
);
1512 A_MEMCPY(ar
->arNodeMap
[eptMap
].macAddress
, macHdr
->dstMac
, IEEE80211_ADDR_LEN
);
1514 for (i
= ENDPOINT_2
; i
<= ENDPOINT_5
; i
++) {
1515 if (!ar
->arTxPending
[i
]) {
1516 ar
->arNodeMap
[eptMap
].epId
= i
;
1519 // No free endpoint is available, start redistribution on the inuse endpoints.
1520 if (i
== ENDPOINT_5
) {
1521 ar
->arNodeMap
[eptMap
].epId
= ar
->arNexEpId
;
1523 if (ar
->arNexEpId
> ENDPOINT_5
) {
1524 ar
->arNexEpId
= ENDPOINT_2
;
1529 (*mapNo
) = eptMap
+ 1;
1530 ar
->arNodeMap
[eptMap
].txPending
++;
1532 return ar
->arNodeMap
[eptMap
].epId
;
1536 static void ar6000_dump_skb(struct sk_buff
*skb
)
1539 for (ch
= A_NETBUF_DATA(skb
);
1540 (A_UINT32
)ch
< ((A_UINT32
)A_NETBUF_DATA(skb
) +
1541 A_NETBUF_LEN(skb
)); ch
++)
1543 AR_DEBUG_PRINTF("%2.2x ", *ch
);
1545 AR_DEBUG_PRINTF("\n");
1550 ar6000_data_tx(struct sk_buff
*skb
, struct net_device
*dev
)
1552 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1553 WMI_PRI_STREAM_ID streamID
= WMI_NOT_MAPPED
;
1556 struct ar_cookie
*cookie
;
1557 A_BOOL checkAdHocPsMapping
= FALSE
;
1559 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
1563 AR_DEBUG2_PRINTF("ar6000_data_tx start - skb=0x%x, data=0x%x, len=0x%x\n",
1564 (A_UINT32
)skb
, (A_UINT32
)A_NETBUF_DATA(skb
),
1566 #ifdef CONFIG_HOST_TCMD_SUPPORT
1567 /* TCMD doesnt support any data, free the buf and return */
1568 if(ar
->arTargetMode
== AR6000_TCMD_MODE
) {
1575 if (ar
->arWmiReady
== FALSE
&& bypasswmi
== 0) {
1579 #ifdef BLOCK_TX_PATH_FLAG
1583 #endif /* BLOCK_TX_PATH_FLAG */
1585 if (ar
->arWmiEnabled
) {
1586 if (A_NETBUF_HEADROOM(skb
) < dev
->hard_header_len
) {
1587 struct sk_buff
*newbuf
;
1589 * We really should have gotten enough headroom but sometimes
1590 * we still get packets with not enough headroom. Copy the packet.
1592 len
= A_NETBUF_LEN(skb
);
1593 newbuf
= A_NETBUF_ALLOC(len
);
1594 if (newbuf
== NULL
) {
1597 A_NETBUF_PUT(newbuf
, len
);
1598 A_MEMCPY(A_NETBUF_DATA(newbuf
), A_NETBUF_DATA(skb
), len
);
1601 /* fall through and assemble header */
1604 if (wmi_dix_2_dot3(ar
->arWmi
, skb
) != A_OK
) {
1605 AR_DEBUG_PRINTF("ar6000_data_tx - wmi_dix_2_dot3 failed\n");
1609 if (wmi_data_hdr_add(ar
->arWmi
, skb
, DATA_MSGTYPE
) != A_OK
) {
1610 AR_DEBUG_PRINTF("ar6000_data_tx - wmi_data_hdr_add failed\n");
1614 if ((ar
->arNetworkType
== ADHOC_NETWORK
) &&
1615 ar
->arIbssPsEnable
&& ar
->arConnected
) {
1616 /* flag to check adhoc mapping once we take the lock below: */
1617 checkAdHocPsMapping
= TRUE
;
1620 /* get the stream mapping */
1621 if (ar
->arWmmEnabled
) {
1622 streamID
= wmi_get_stream_id(ar
->arWmi
,
1623 wmi_implicit_create_pstream(ar
->arWmi
, skb
, UPLINK_TRAFFIC
, UNDEFINED_PRI
));
1625 streamID
= WMI_BEST_EFFORT_PRI
;
1630 struct iphdr
*ipHdr
;
1632 * the endpoint is directly based on the TOS field in the IP
1633 * header **** only for testing ******
1635 ipHdr
= A_NETBUF_DATA(skb
) + sizeof(ATH_MAC_HDR
);
1636 /* here we map the TOS field to an endpoint number, this is for
1637 * the endpointping test application */
1638 streamID
= IP_TOS_TO_WMI_PRI(ipHdr
->tos
);
1643 /* did we succeed ? */
1644 if ((streamID
== WMI_NOT_MAPPED
) && !checkAdHocPsMapping
) {
1645 /* cleanup and exit */
1647 AR6000_STAT_INC(ar
, tx_dropped
);
1648 AR6000_STAT_INC(ar
, tx_aborted_errors
);
1654 /* take the lock to protect driver data */
1655 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1659 if (checkAdHocPsMapping
) {
1660 streamID
= ar6000_ibss_map_epid(skb
, dev
, &mapNo
);
1663 A_ASSERT(streamID
!= WMI_NOT_MAPPED
);
1665 /* validate that the endpoint is connected */
1666 if (arWMIStream2EndpointID(ar
,streamID
) == 0) {
1667 AR_DEBUG_PRINTF("Stream %d is NOT mapped!\n",streamID
);
1670 /* allocate resource for this packet */
1671 cookie
= ar6000_alloc_cookie(ar
);
1673 if (cookie
!= NULL
) {
1674 /* update counts while the lock is held */
1675 ar
->arTxPending
[streamID
]++;
1676 ar
->arTotalTxDataPending
++;
1681 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1683 if (cookie
!= NULL
) {
1684 cookie
->arc_bp
[0] = (A_UINT32
)skb
;
1685 cookie
->arc_bp
[1] = mapNo
;
1686 SET_HTC_PACKET_INFO_TX(&cookie
->HtcPkt
,
1690 arWMIStream2EndpointID(ar
,streamID
),
1694 if (debugdriver
>= 3) {
1695 ar6000_dump_skb(skb
);
1698 /* HTC interface is asynchronous, if this fails, cleanup will happen in
1699 * the ar6000_tx_complete callback */
1700 HTCSendPkt(ar
->arHtcTarget
, &cookie
->HtcPkt
);
1702 /* no packet to send, cleanup */
1704 AR6000_STAT_INC(ar
, tx_dropped
);
1705 AR6000_STAT_INC(ar
, tx_aborted_errors
);
1711 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1713 tvsub(register struct timeval
*out
, register struct timeval
*in
)
1715 if((out
->tv_usec
-= in
->tv_usec
) < 0) {
1717 out
->tv_usec
+= 1000000;
1719 out
->tv_sec
-= in
->tv_sec
;
1723 applyAPTCHeuristics(AR_SOFTC_T
*ar
)
1727 A_UINT32 throughput
;
1731 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1733 if ((enableAPTCHeuristics
) && (!aptcTR
.timerScheduled
)) {
1734 do_gettimeofday(&ts
);
1735 tvsub(&ts
, &aptcTR
.samplingTS
);
1736 duration
= ts
.tv_sec
* 1000 + ts
.tv_usec
/ 1000; /* ms */
1737 numbytes
= aptcTR
.bytesTransmitted
+ aptcTR
.bytesReceived
;
1739 if (duration
> APTC_TRAFFIC_SAMPLING_INTERVAL
) {
1740 /* Initialize the time stamp and byte count */
1741 aptcTR
.bytesTransmitted
= aptcTR
.bytesReceived
= 0;
1742 do_gettimeofday(&aptcTR
.samplingTS
);
1744 /* Calculate and decide based on throughput thresholds */
1745 throughput
= ((numbytes
* 8) / duration
);
1746 if (throughput
> APTC_UPPER_THROUGHPUT_THRESHOLD
) {
1747 /* Disable Sleep and schedule a timer */
1748 A_ASSERT(ar
->arWmiReady
== TRUE
);
1749 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1750 status
= wmi_powermode_cmd(ar
->arWmi
, MAX_PERF_POWER
);
1751 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1752 A_TIMEOUT_MS(&aptcTimer
, APTC_TRAFFIC_SAMPLING_INTERVAL
, 0);
1753 aptcTR
.timerScheduled
= TRUE
;
1758 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1760 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1763 ar6000_tx_queue_full(void *Context
, HTC_ENDPOINT_ID Endpoint
)
1765 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*) Context
;
1767 if (Endpoint
== arWMIStream2EndpointID(ar
,WMI_CONTROL_PRI
)) {
1769 /* under normal WMI if this is getting full, then something is running rampant
1770 * the host should not be exhausting the WMI queue with too many commands
1771 * the only exception to this is during testing using endpointping */
1773 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1774 /* set flag to handle subsequent messages */
1775 ar
->arWMIControlEpFull
= TRUE
;
1776 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1777 AR_DEBUG_PRINTF("WMI Control Endpoint is FULL!!! \n");
1780 /* one of the data endpoints queues is getting full..need to stop network stack
1781 * the queue will resume after credits received */
1782 netif_stop_queue(ar
->arNetDev
);
1787 ar6000_tx_queue_avail(void *Context
, HTC_ENDPOINT_ID Endpoint
)
1789 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Context
;
1791 if (Endpoint
== arWMIStream2EndpointID(ar
,WMI_CONTROL_PRI
)) {
1792 /* FIXME: what do for it? */
1794 /* Wake up interface, rescheduling prevented. */
1795 if (ar
->arConnected
== TRUE
|| bypasswmi
)
1796 netif_wake_queue(ar
->arNetDev
);
1801 ar6000_tx_complete(void *Context
, HTC_PACKET
*pPacket
)
1803 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Context
;
1804 void *cookie
= (void *)pPacket
->pPktContext
;
1805 struct sk_buff
*skb
= NULL
;
1808 struct ar_cookie
* ar_cookie
;
1809 WMI_PRI_STREAM_ID streamID
;
1810 A_BOOL wakeEvent
= FALSE
;
1812 status
= pPacket
->Status
;
1813 ar_cookie
= (struct ar_cookie
*)cookie
;
1814 skb
= (struct sk_buff
*)ar_cookie
->arc_bp
[0];
1815 streamID
= arEndpoint2WMIStreamID(ar
,pPacket
->Endpoint
);
1816 mapNo
= ar_cookie
->arc_bp
[1];
1819 A_ASSERT(pPacket
->pBuffer
== A_NETBUF_DATA(skb
));
1821 if (A_SUCCESS(status
)) {
1822 A_ASSERT(pPacket
->ActualLength
== A_NETBUF_LEN(skb
));
1825 AR_DEBUG2_PRINTF("ar6000_tx_complete skb=0x%x data=0x%x len=0x%x sid=%d ",
1826 (A_UINT32
)skb
, (A_UINT32
)pPacket
->pBuffer
,
1827 pPacket
->ActualLength
,
1830 /* lock the driver as we update internal state */
1831 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1833 ar
->arTxPending
[streamID
]--;
1835 if ((streamID
!= WMI_CONTROL_PRI
) || bypasswmi
) {
1836 ar
->arTotalTxDataPending
--;
1839 if (streamID
== WMI_CONTROL_PRI
)
1841 if (ar
->arWMIControlEpFull
) {
1842 /* since this packet completed, the WMI EP is no longer full */
1843 ar
->arWMIControlEpFull
= FALSE
;
1846 if (ar
->arTxPending
[streamID
] == 0) {
1851 if (A_FAILED(status
)) {
1852 AR_DEBUG_PRINTF("%s() -TX ERROR, status: 0x%x\n", __func__
,
1854 AR6000_STAT_INC(ar
, tx_errors
);
1856 AR_DEBUG2_PRINTF("OK\n");
1857 AR6000_STAT_INC(ar
, tx_packets
);
1858 ar
->arNetStats
.tx_bytes
+= A_NETBUF_LEN(skb
);
1859 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1860 aptcTR
.bytesTransmitted
+= a_netbuf_to_len(skb
);
1861 applyAPTCHeuristics(ar
);
1862 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1865 // TODO this needs to be looked at
1866 if ((ar
->arNetworkType
== ADHOC_NETWORK
) && ar
->arIbssPsEnable
1867 && (streamID
!= WMI_CONTROL_PRI
) && mapNo
)
1870 ar
->arNodeMap
[mapNo
].txPending
--;
1872 if (!ar
->arNodeMap
[mapNo
].txPending
&& (mapNo
== (ar
->arNodeNum
- 1))) {
1874 for (i
= ar
->arNodeNum
; i
> 0; i
--) {
1875 if (!ar
->arNodeMap
[i
- 1].txPending
) {
1876 A_MEMZERO(&ar
->arNodeMap
[i
- 1], sizeof(struct ar_node_mapping
));
1885 /* Freeing a cookie should not be contingent on either of */
1886 /* these flags, just if we have a cookie or not. */
1887 /* Can we even get here without a cookie? Fix later. */
1888 if (ar
->arWmiReady
== TRUE
|| (bypasswmi
))
1890 ar6000_free_cookie(ar
, cookie
);
1893 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1895 /* lock is released, we can freely call other kernel APIs */
1897 /* this indirectly frees the HTC_PACKET */
1906 * Receive event handler. This is called by HTC when a packet is received
1910 ar6000_rx(void *Context
, HTC_PACKET
*pPacket
)
1912 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Context
;
1913 struct sk_buff
*skb
= (struct sk_buff
*)pPacket
->pPktContext
;
1915 A_STATUS status
= pPacket
->Status
;
1916 WMI_PRI_STREAM_ID streamID
= arEndpoint2WMIStreamID(ar
,pPacket
->Endpoint
);
1917 HTC_ENDPOINT_ID ept
= pPacket
->Endpoint
;
1919 A_ASSERT((status
!= A_OK
) || (pPacket
->pBuffer
== (A_NETBUF_DATA(skb
) + HTC_HEADER_LEN
)));
1921 AR_DEBUG2_PRINTF("ar6000_rx ar=0x%x sid=%d, skb=0x%x, data=0x%x, len=0x%x ",
1922 (A_UINT32
)ar
, streamID
, (A_UINT32
)skb
, (A_UINT32
)pPacket
->pBuffer
,
1923 pPacket
->ActualLength
);
1924 if (status
!= A_OK
) {
1925 AR_DEBUG2_PRINTF("ERR\n");
1927 AR_DEBUG2_PRINTF("OK\n");
1930 /* take lock to protect buffer counts
1931 * and adaptive power throughput state */
1932 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
1934 ar
->arRxBuffers
[streamID
]--;
1936 if (A_SUCCESS(status
)) {
1937 AR6000_STAT_INC(ar
, rx_packets
);
1938 ar
->arNetStats
.rx_bytes
+= pPacket
->ActualLength
;
1939 #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1940 aptcTR
.bytesReceived
+= a_netbuf_to_len(skb
);
1941 applyAPTCHeuristics(ar
);
1942 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1944 A_NETBUF_PUT(skb
, pPacket
->ActualLength
+ HTC_HEADER_LEN
);
1945 A_NETBUF_PULL(skb
, HTC_HEADER_LEN
);
1948 if (debugdriver
>= 2) {
1949 ar6000_dump_skb(skb
);
1954 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
1956 if (status
!= A_OK
) {
1957 AR6000_STAT_INC(ar
, rx_errors
);
1959 } else if (ar
->arWmiEnabled
== TRUE
) {
1960 if (streamID
== WMI_CONTROL_PRI
) {
1962 * this is a wmi control msg
1964 wmi_control_rx(ar
->arWmi
, skb
);
1966 WMI_DATA_HDR
*dhdr
= (WMI_DATA_HDR
*)A_NETBUF_DATA(skb
);
1967 if (WMI_DATA_HDR_IS_MSG_TYPE(dhdr
, CNTL_MSGTYPE
)) {
1969 * this is a wmi control msg
1971 /* strip off WMI hdr */
1972 wmi_data_hdr_remove(ar
->arWmi
, skb
);
1973 wmi_control_rx(ar
->arWmi
, skb
);
1976 * this is a wmi data packet
1978 minHdrLen
= sizeof (WMI_DATA_HDR
) + sizeof(ATH_MAC_HDR
) +
1979 sizeof(ATH_LLC_SNAP_HDR
);
1981 if ((pPacket
->ActualLength
< minHdrLen
) ||
1982 (pPacket
->ActualLength
> AR6000_BUFFER_SIZE
))
1985 * packet is too short or too long
1987 AR_DEBUG_PRINTF("TOO SHORT or TOO LONG\n");
1988 AR6000_STAT_INC(ar
, rx_errors
);
1989 AR6000_STAT_INC(ar
, rx_length_errors
);
1992 if (ar
->arWmmEnabled
) {
1993 wmi_implicit_create_pstream(ar
->arWmi
, skb
,
1994 DNLINK_TRAFFIC
, UNDEFINED_PRI
);
1997 /* Access RSSI values here */
1998 AR_DEBUG_PRINTF("RSSI %d\n",
1999 ((WMI_DATA_HDR
*) A_NETBUF_DATA(skb
))->rssi
);
2001 wmi_data_hdr_remove(ar
->arWmi
, skb
);
2002 wmi_dot3_2_dix(ar
->arWmi
, skb
);
2004 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
2006 * extra push and memcpy, for eth_type_trans() of 2.4 kernel
2007 * will pull out hard_header_len bytes of the skb.
2009 A_NETBUF_PUSH(skb
, sizeof(WMI_DATA_HDR
) + sizeof(ATH_LLC_SNAP_HDR
) + HTC_HEADER_LEN
);
2010 A_MEMCPY(A_NETBUF_DATA(skb
), A_NETBUF_DATA(skb
) + sizeof(WMI_DATA_HDR
) +
2011 sizeof(ATH_LLC_SNAP_HDR
) + HTC_HEADER_LEN
, sizeof(ATH_MAC_HDR
));
2013 if ((ar
->arNetDev
->flags
& IFF_UP
) == IFF_UP
)
2015 skb
->dev
= ar
->arNetDev
;
2016 skb
->protocol
= eth_type_trans(skb
, ar
->arNetDev
);
2027 if ((ar
->arNetDev
->flags
& IFF_UP
) == IFF_UP
)
2029 skb
->dev
= ar
->arNetDev
;
2030 skb
->protocol
= eth_type_trans(skb
, ar
->arNetDev
);
2039 if (status
!= A_ECANCELED
) {
2041 * HTC provides A_ECANCELED status when it doesn't want to be refilled
2042 * (probably due to a shutdown)
2044 ar6000_rx_refill(Context
, ept
);
2051 ar6000_rx_refill(void *Context
, HTC_ENDPOINT_ID Endpoint
)
2053 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)Context
;
2056 int buffersToRefill
;
2057 HTC_PACKET
*pPacket
;
2058 WMI_PRI_STREAM_ID streamId
= arEndpoint2WMIStreamID(ar
,Endpoint
);
2060 buffersToRefill
= (int)AR6000_MAX_RX_BUFFERS
-
2061 (int)ar
->arRxBuffers
[streamId
];
2063 if (buffersToRefill
<= 0) {
2064 /* fast return, nothing to fill */
2068 AR_DEBUG2_PRINTF("ar6000_rx_refill: providing htc with %d buffers at eid=%d\n",
2069 buffersToRefill
, Endpoint
);
2071 for (RxBuffers
= 0; RxBuffers
< buffersToRefill
; RxBuffers
++) {
2072 osBuf
= A_NETBUF_ALLOC(AR6000_BUFFER_SIZE
);
2073 if (NULL
== osBuf
) {
2076 /* the HTC packet wrapper is at the head of the reserved area
2078 pPacket
= (HTC_PACKET
*)(A_NETBUF_HEAD(osBuf
));
2079 /* set re-fill info */
2080 SET_HTC_PACKET_INFO_RX_REFILL(pPacket
,osBuf
,A_NETBUF_DATA(osBuf
),AR6000_BUFFER_SIZE
,Endpoint
);
2081 /* add this packet */
2082 HTCAddReceivePkt(ar
->arHtcTarget
, pPacket
);
2086 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
2087 ar
->arRxBuffers
[streamId
] += RxBuffers
;
2088 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
2091 static struct net_device_stats
*
2092 ar6000_get_stats(struct net_device
*dev
)
2094 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
2095 return &ar
->arNetStats
;
2098 static struct iw_statistics
*
2099 ar6000_get_iwstats(struct net_device
* dev
)
2101 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
2102 TARGET_STATS
*pStats
= &ar
->arTargetStats
;
2103 struct iw_statistics
* pIwStats
= &ar
->arIwStats
;
2105 if ((ar
->arWmiReady
== FALSE
)
2107 * The in_atomic function is used to determine if the scheduling is
2108 * allowed in the current context or not. This was introduced in 2.6
2109 * From what I have read on the differences between 2.4 and 2.6, the
2110 * 2.4 kernel did not support preemption and so this check might not
2111 * be required for 2.4 kernels.
2113 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
2118 pIwStats
->status
= 0;
2119 pIwStats
->qual
.qual
= 0;
2120 pIwStats
->qual
.level
=0;
2121 pIwStats
->qual
.noise
= 0;
2122 pIwStats
->discard
.code
=0;
2123 pIwStats
->discard
.retries
=0;
2124 pIwStats
->miss
.beacon
=0;
2127 if (down_interruptible(&ar
->arSem
)) {
2128 pIwStats
->status
= 0;
2133 ar
->statsUpdatePending
= TRUE
;
2135 if(wmi_get_stats_cmd(ar
->arWmi
) != A_OK
) {
2137 pIwStats
->status
= 0;
2141 wait_event_interruptible_timeout(arEvent
, ar
->statsUpdatePending
== FALSE
, wmitimeout
* HZ
);
2143 if (signal_pending(current
)) {
2144 AR_DEBUG_PRINTF("ar6000 : WMI get stats timeout \n");
2146 pIwStats
->status
= 0;
2149 pIwStats
->status
= 1 ;
2150 pIwStats
->qual
.qual
= pStats
->cs_aveBeacon_rssi
;
2151 pIwStats
->qual
.level
=pStats
->cs_aveBeacon_rssi
+ 161; /* noise is -95 dBm */
2152 pIwStats
->qual
.noise
= pStats
->noise_floor_calibation
;
2153 pIwStats
->discard
.code
= pStats
->rx_decrypt_err
;
2154 pIwStats
->discard
.retries
= pStats
->tx_retry_cnt
;
2155 pIwStats
->miss
.beacon
= pStats
->cs_bmiss_cnt
;
2161 ar6000_ready_event(void *devt
, A_UINT8
*datap
, A_UINT8 phyCap
)
2163 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
2164 struct net_device
*dev
= ar
->arNetDev
;
2166 ar
->arWmiReady
= TRUE
;
2168 A_MEMCPY(dev
->dev_addr
, datap
, AR6000_ETH_ADDR_LEN
);
2169 AR_DEBUG_PRINTF("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
2170 dev
->dev_addr
[0], dev
->dev_addr
[1],
2171 dev
->dev_addr
[2], dev
->dev_addr
[3],
2172 dev
->dev_addr
[4], dev
->dev_addr
[5]);
2174 ar
->arPhyCapability
= phyCap
;
2178 ar6000_iptos_to_userPriority(A_UINT8
*pkt
)
2180 struct iphdr
*ipHdr
= (struct iphdr
*)pkt
;
2181 A_UINT8 userPriority
;
2185 * (Refer Pg 57 WMM-test-plan-v1.2)
2187 * : DSCP(6-bits) ECN(2-bits)
2188 * : DSCP - P2 P1 P0 X X X
2189 * where (P2 P1 P0) form 802.1D
2191 userPriority
= ipHdr
->tos
>> 5;
2192 return (userPriority
& 0x7);
2196 ar6000_connect_event(AR_SOFTC_T
*ar
, A_UINT16 channel
, A_UINT8
*bssid
,
2197 A_UINT16 listenInterval
, A_UINT16 beaconInterval
,
2198 NETWORK_TYPE networkType
, A_UINT8 beaconIeLen
,
2199 A_UINT8 assocReqLen
, A_UINT8 assocRespLen
,
2202 union iwreq_data wrqu
;
2203 int i
, beacon_ie_pos
, assoc_resp_ie_pos
, assoc_req_ie_pos
;
2204 static const char *tag1
= "ASSOCINFO(ReqIEs=";
2205 static const char *tag2
= "ASSOCRESPIE=";
2206 static const char *beaconIetag
= "BEACONIE=";
2207 char buf
[WMI_CONTROL_MSG_MAX_LEN
* 2 + sizeof(tag1
)];
2209 A_UINT8 key_op_ctrl
;
2211 A_MEMCPY(ar
->arBssid
, bssid
, sizeof(ar
->arBssid
));
2212 ar
->arBssChannel
= channel
;
2214 A_PRINTF("AR6000 connected event on freq %d ", channel
);
2215 A_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
2216 " listenInterval=%d, beaconInterval = %d, beaconIeLen = %d assocReqLen=%d"
2217 " assocRespLen =%d\n",
2218 bssid
[0], bssid
[1], bssid
[2],
2219 bssid
[3], bssid
[4], bssid
[5],
2220 listenInterval
, beaconInterval
,
2221 beaconIeLen
, assocReqLen
, assocRespLen
);
2222 if (networkType
& ADHOC_NETWORK
) {
2223 if (networkType
& ADHOC_CREATOR
) {
2224 A_PRINTF("Network: Adhoc (Creator)\n");
2226 A_PRINTF("Network: Adhoc (Joiner)\n");
2229 A_PRINTF("Network: Infrastructure\n");
2232 if (beaconIeLen
&& (sizeof(buf
) > (9 + beaconIeLen
* 2))) {
2233 AR_DEBUG_PRINTF("\nBeaconIEs= ");
2236 A_MEMZERO(buf
, sizeof(buf
));
2237 sprintf(buf
, "%s", beaconIetag
);
2239 for (i
= beacon_ie_pos
; i
< beacon_ie_pos
+ beaconIeLen
; i
++) {
2240 AR_DEBUG_PRINTF("%2.2x ", assocInfo
[i
]);
2241 sprintf(pos
, "%2.2x", assocInfo
[i
]);
2244 AR_DEBUG_PRINTF("\n");
2246 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2247 wrqu
.data
.length
= strlen(buf
);
2248 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2251 if (assocRespLen
&& (sizeof(buf
) > (12 + (assocRespLen
* 2))))
2253 assoc_resp_ie_pos
= beaconIeLen
+ assocReqLen
+
2254 sizeof(A_UINT16
) + /* capinfo*/
2255 sizeof(A_UINT16
) + /* status Code */
2256 sizeof(A_UINT16
) ; /* associd */
2257 A_MEMZERO(buf
, sizeof(buf
));
2258 sprintf(buf
, "%s", tag2
);
2260 AR_DEBUG_PRINTF("\nAssocRespIEs= ");
2262 * The Association Response Frame w.o. the WLAN header is delivered to
2263 * the host, so skip over to the IEs
2265 for (i
= assoc_resp_ie_pos
; i
< assoc_resp_ie_pos
+ assocRespLen
- 6; i
++)
2267 AR_DEBUG_PRINTF("%2.2x ", assocInfo
[i
]);
2268 sprintf(pos
, "%2.2x", assocInfo
[i
]);
2271 AR_DEBUG_PRINTF("\n");
2273 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2274 wrqu
.data
.length
= strlen(buf
);
2275 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2278 if (assocReqLen
&& (sizeof(buf
) > (17 + (assocReqLen
* 2)))) {
2280 * assoc Request includes capability and listen interval. Skip these.
2282 assoc_req_ie_pos
= beaconIeLen
+
2283 sizeof(A_UINT16
) + /* capinfo*/
2284 sizeof(A_UINT16
); /* listen interval */
2286 A_MEMZERO(buf
, sizeof(buf
));
2287 sprintf(buf
, "%s", tag1
);
2289 AR_DEBUG_PRINTF("AssocReqIEs= ");
2290 for (i
= assoc_req_ie_pos
; i
< assoc_req_ie_pos
+ assocReqLen
- 4; i
++) {
2291 AR_DEBUG_PRINTF("%2.2x ", assocInfo
[i
]);
2292 sprintf(pos
, "%2.2x", assocInfo
[i
]);
2295 AR_DEBUG_PRINTF("\n");
2297 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2298 wrqu
.data
.length
= strlen(buf
);
2299 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2303 if (ar
->user_savedkeys_stat
== USER_SAVEDKEYS_STAT_RUN
&&
2304 ar
->user_saved_keys
.keyOk
== TRUE
)
2307 key_op_ctrl
= KEY_OP_VALID_MASK
& ~KEY_OP_INIT_TSC
;
2308 if (ar
->user_key_ctrl
& AR6000_USER_SETKEYS_RSC_UNCHANGED
) {
2309 key_op_ctrl
&= ~KEY_OP_INIT_RSC
;
2311 key_op_ctrl
|= KEY_OP_INIT_RSC
;
2313 ar6000_reinstall_keys(ar
, key_op_ctrl
);
2315 #endif /* USER_KEYS */
2317 /* flush data queues */
2318 ar6000_TxDataCleanup(ar
);
2320 netif_start_queue(ar
->arNetDev
);
2322 if ((OPEN_AUTH
== ar
->arDot11AuthMode
) &&
2323 (NONE_AUTH
== ar
->arAuthMode
) &&
2324 (WEP_CRYPT
== ar
->arPairwiseCrypto
))
2326 if (!ar
->arConnected
) {
2327 ar6000_install_static_wep_keys(ar
);
2331 ar
->arConnected
= TRUE
;
2332 ar
->arConnectPending
= FALSE
;
2336 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2337 A_MEMCPY(wrqu
.addr
.sa_data
, bssid
, IEEE80211_ADDR_LEN
);
2338 wrqu
.addr
.sa_family
= ARPHRD_ETHER
;
2339 wireless_send_event(ar
->arNetDev
, SIOCGIWAP
, &wrqu
, NULL
);
2340 if ((ar
->arNetworkType
== ADHOC_NETWORK
) && ar
->arIbssPsEnable
) {
2341 A_MEMZERO(ar
->arNodeMap
, sizeof(ar
->arNodeMap
));
2343 ar
->arNexEpId
= ENDPOINT_2
;
2348 void ar6000_set_numdataendpts(AR_SOFTC_T
*ar
, A_UINT32 num
)
2350 A_ASSERT(num
<= (HTC_MAILBOX_NUM_MAX
- 1));
2351 ar
->arNumDataEndPts
= num
;
2355 ar6000_disconnect_event(AR_SOFTC_T
*ar
, A_UINT8 reason
, A_UINT8
*bssid
,
2356 A_UINT8 assocRespLen
, A_UINT8
*assocInfo
, A_UINT16 protocolReasonStatus
)
2360 A_PRINTF("AR6000 disconnected");
2361 if (bssid
[0] || bssid
[1] || bssid
[2] || bssid
[3] || bssid
[4] || bssid
[5]) {
2362 A_PRINTF(" from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
2363 bssid
[0], bssid
[1], bssid
[2], bssid
[3], bssid
[4], bssid
[5]);
2367 AR_DEBUG_PRINTF("\nDisconnect Reason is %d", reason
);
2368 AR_DEBUG_PRINTF("\nProtocol Reason/Status Code is %d", protocolReasonStatus
);
2369 AR_DEBUG_PRINTF("\nAssocResp Frame = %s",
2370 assocRespLen
? " " : "NULL");
2371 for (i
= 0; i
< assocRespLen
; i
++) {
2373 AR_DEBUG_PRINTF("\n");
2375 AR_DEBUG_PRINTF("%2.2x ", assocInfo
[i
]);
2377 AR_DEBUG_PRINTF("\n");
2379 * If the event is due to disconnect cmd from the host, only they the target
2380 * would stop trying to connect. Under any other condition, target would
2381 * keep trying to connect.
2384 if( reason
== DISCONNECT_CMD
)
2386 ar
->arConnectPending
= FALSE
;
2388 ar
->arConnectPending
= TRUE
;
2389 if (((reason
== ASSOC_FAILED
) && (protocolReasonStatus
== 0x11)) ||
2390 ((reason
== ASSOC_FAILED
) && (protocolReasonStatus
== 0x0) && (reconnect_flag
== 1))) {
2391 ar
->arConnected
= TRUE
;
2395 ar
->arConnected
= FALSE
;
2397 if( (reason
!= CSERV_DISCONNECT
) || (reconnect_flag
!= 1) ) {
2402 if (reason
!= CSERV_DISCONNECT
)
2404 ar
->user_savedkeys_stat
= USER_SAVEDKEYS_STAT_INIT
;
2405 ar
->user_key_ctrl
= 0;
2407 #endif /* USER_KEYS */
2409 netif_stop_queue(ar
->arNetDev
);
2410 A_MEMZERO(ar
->arBssid
, sizeof(ar
->arBssid
));
2411 ar
->arBssChannel
= 0;
2412 ar
->arBeaconInterval
= 0;
2414 ar6000_TxDataCleanup(ar
);
2418 ar6000_regDomain_event(AR_SOFTC_T
*ar
, A_UINT32 regCode
)
2420 A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode
);
2421 ar
->arRegCode
= regCode
;
2425 ar6000_neighborReport_event(AR_SOFTC_T
*ar
, int numAps
, WMI_NEIGHBOR_INFO
*info
)
2427 static const char *tag
= "PRE-AUTH";
2429 union iwreq_data wrqu
;
2432 AR_DEBUG_PRINTF("AR6000 Neighbor Report Event\n");
2433 for (i
=0; i
< numAps
; info
++, i
++) {
2434 AR_DEBUG_PRINTF("bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
2435 info
->bssid
[0], info
->bssid
[1], info
->bssid
[2],
2436 info
->bssid
[3], info
->bssid
[4], info
->bssid
[5]);
2437 if (info
->bssFlags
& WMI_PREAUTH_CAPABLE_BSS
) {
2438 AR_DEBUG_PRINTF("preauth-cap");
2440 if (info
->bssFlags
& WMI_PMKID_VALID_BSS
) {
2441 AR_DEBUG_PRINTF(" pmkid-valid\n");
2442 continue; /* we skip bss if the pmkid is already valid */
2444 AR_DEBUG_PRINTF("\n");
2445 snprintf(buf
, sizeof(buf
), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
2447 info
->bssid
[0], info
->bssid
[1], info
->bssid
[2],
2448 info
->bssid
[3], info
->bssid
[4], info
->bssid
[5],
2450 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2451 wrqu
.data
.length
= strlen(buf
);
2452 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2457 ar6000_tkip_micerr_event(AR_SOFTC_T
*ar
, A_UINT8 keyid
, A_BOOL ismcast
)
2459 static const char *tag
= "MLME-MICHAELMICFAILURE.indication";
2461 union iwreq_data wrqu
;
2463 A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n",
2464 keyid
, ismcast
? "multi": "uni");
2465 snprintf(buf
, sizeof(buf
), "%s(keyid=%d %scat)", tag
, keyid
,
2466 ismcast
? "multi" : "uni");
2467 memset(&wrqu
, 0, sizeof(wrqu
));
2468 wrqu
.data
.length
= strlen(buf
);
2469 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2473 ar6000_scanComplete_event(AR_SOFTC_T
*ar
, A_STATUS status
)
2475 AR_DEBUG_PRINTF("AR6000 scan complete: %d\n", status
);
2477 ar
->scan_complete
= 1;
2478 wake_up_interruptible(&ar6000_scan_queue
);
2482 ar6000_targetStats_event(AR_SOFTC_T
*ar
, WMI_TARGET_STATS
*pTarget
)
2484 TARGET_STATS
*pStats
= &ar
->arTargetStats
;
2487 /*A_PRINTF("AR6000 updating target stats\n");*/
2488 pStats
->tx_packets
+= pTarget
->txrxStats
.tx_stats
.tx_packets
;
2489 pStats
->tx_bytes
+= pTarget
->txrxStats
.tx_stats
.tx_bytes
;
2490 pStats
->tx_unicast_pkts
+= pTarget
->txrxStats
.tx_stats
.tx_unicast_pkts
;
2491 pStats
->tx_unicast_bytes
+= pTarget
->txrxStats
.tx_stats
.tx_unicast_bytes
;
2492 pStats
->tx_multicast_pkts
+= pTarget
->txrxStats
.tx_stats
.tx_multicast_pkts
;
2493 pStats
->tx_multicast_bytes
+= pTarget
->txrxStats
.tx_stats
.tx_multicast_bytes
;
2494 pStats
->tx_broadcast_pkts
+= pTarget
->txrxStats
.tx_stats
.tx_broadcast_pkts
;
2495 pStats
->tx_broadcast_bytes
+= pTarget
->txrxStats
.tx_stats
.tx_broadcast_bytes
;
2496 pStats
->tx_rts_success_cnt
+= pTarget
->txrxStats
.tx_stats
.tx_rts_success_cnt
;
2497 for(ac
= 0; ac
< WMM_NUM_AC
; ac
++)
2498 pStats
->tx_packet_per_ac
[ac
] += pTarget
->txrxStats
.tx_stats
.tx_packet_per_ac
[ac
];
2499 pStats
->tx_errors
+= pTarget
->txrxStats
.tx_stats
.tx_errors
;
2500 pStats
->tx_failed_cnt
+= pTarget
->txrxStats
.tx_stats
.tx_failed_cnt
;
2501 pStats
->tx_retry_cnt
+= pTarget
->txrxStats
.tx_stats
.tx_retry_cnt
;
2502 pStats
->tx_rts_fail_cnt
+= pTarget
->txrxStats
.tx_stats
.tx_rts_fail_cnt
;
2503 pStats
->tx_unicast_rate
= wmi_get_rate(pTarget
->txrxStats
.tx_stats
.tx_unicast_rate
);
2505 pStats
->rx_packets
+= pTarget
->txrxStats
.rx_stats
.rx_packets
;
2506 pStats
->rx_bytes
+= pTarget
->txrxStats
.rx_stats
.rx_bytes
;
2507 pStats
->rx_unicast_pkts
+= pTarget
->txrxStats
.rx_stats
.rx_unicast_pkts
;
2508 pStats
->rx_unicast_bytes
+= pTarget
->txrxStats
.rx_stats
.rx_unicast_bytes
;
2509 pStats
->rx_multicast_pkts
+= pTarget
->txrxStats
.rx_stats
.rx_multicast_pkts
;
2510 pStats
->rx_multicast_bytes
+= pTarget
->txrxStats
.rx_stats
.rx_multicast_bytes
;
2511 pStats
->rx_broadcast_pkts
+= pTarget
->txrxStats
.rx_stats
.rx_broadcast_pkts
;
2512 pStats
->rx_broadcast_bytes
+= pTarget
->txrxStats
.rx_stats
.rx_broadcast_bytes
;
2513 pStats
->rx_fragment_pkt
+= pTarget
->txrxStats
.rx_stats
.rx_fragment_pkt
;
2514 pStats
->rx_errors
+= pTarget
->txrxStats
.rx_stats
.rx_errors
;
2515 pStats
->rx_crcerr
+= pTarget
->txrxStats
.rx_stats
.rx_crcerr
;
2516 pStats
->rx_key_cache_miss
+= pTarget
->txrxStats
.rx_stats
.rx_key_cache_miss
;
2517 pStats
->rx_decrypt_err
+= pTarget
->txrxStats
.rx_stats
.rx_decrypt_err
;
2518 pStats
->rx_duplicate_frames
+= pTarget
->txrxStats
.rx_stats
.rx_duplicate_frames
;
2519 pStats
->rx_unicast_rate
= wmi_get_rate(pTarget
->txrxStats
.rx_stats
.rx_unicast_rate
);
2522 pStats
->tkip_local_mic_failure
2523 += pTarget
->txrxStats
.tkipCcmpStats
.tkip_local_mic_failure
;
2524 pStats
->tkip_counter_measures_invoked
2525 += pTarget
->txrxStats
.tkipCcmpStats
.tkip_counter_measures_invoked
;
2526 pStats
->tkip_replays
+= pTarget
->txrxStats
.tkipCcmpStats
.tkip_replays
;
2527 pStats
->tkip_format_errors
+= pTarget
->txrxStats
.tkipCcmpStats
.tkip_format_errors
;
2528 pStats
->ccmp_format_errors
+= pTarget
->txrxStats
.tkipCcmpStats
.ccmp_format_errors
;
2529 pStats
->ccmp_replays
+= pTarget
->txrxStats
.tkipCcmpStats
.ccmp_replays
;
2532 pStats
->power_save_failure_cnt
+= pTarget
->pmStats
.power_save_failure_cnt
;
2533 pStats
->noise_floor_calibation
= pTarget
->noise_floor_calibation
;
2535 pStats
->cs_bmiss_cnt
+= pTarget
->cservStats
.cs_bmiss_cnt
;
2536 pStats
->cs_lowRssi_cnt
+= pTarget
->cservStats
.cs_lowRssi_cnt
;
2537 pStats
->cs_connect_cnt
+= pTarget
->cservStats
.cs_connect_cnt
;
2538 pStats
->cs_disconnect_cnt
+= pTarget
->cservStats
.cs_disconnect_cnt
;
2539 pStats
->cs_aveBeacon_snr
= pTarget
->cservStats
.cs_aveBeacon_snr
;
2540 pStats
->cs_aveBeacon_rssi
= pTarget
->cservStats
.cs_aveBeacon_rssi
;
2541 pStats
->cs_lastRoam_msec
= pTarget
->cservStats
.cs_lastRoam_msec
;
2542 pStats
->cs_snr
= pTarget
->cservStats
.cs_snr
;
2543 pStats
->cs_rssi
= pTarget
->cservStats
.cs_rssi
;
2545 pStats
->lq_val
= pTarget
->lqVal
;
2547 pStats
->wow_num_pkts_dropped
+= pTarget
->wowStats
.wow_num_pkts_dropped
;
2548 pStats
->wow_num_host_pkt_wakeups
+= pTarget
->wowStats
.wow_num_host_pkt_wakeups
;
2549 pStats
->wow_num_host_event_wakeups
+= pTarget
->wowStats
.wow_num_host_event_wakeups
;
2550 pStats
->wow_num_events_discarded
+= pTarget
->wowStats
.wow_num_events_discarded
;
2552 ar
->statsUpdatePending
= FALSE
;
2557 ar6000_rssiThreshold_event(AR_SOFTC_T
*ar
, WMI_RSSI_THRESHOLD_VAL newThreshold
, A_INT16 rssi
)
2559 USER_RSSI_THOLD userRssiThold
;
2561 userRssiThold
.tag
= rssi_map
[newThreshold
].tag
;
2562 userRssiThold
.rssi
= rssi
;
2563 AR_DEBUG2_PRINTF("rssi Threshold range = %d tag = %d rssi = %d\n", newThreshold
, userRssiThold
.tag
, rssi
);
2564 #ifdef SEND_EVENT_TO_APP
2565 ar6000_send_event_to_app(ar
, WMI_RSSI_THRESHOLD_EVENTID
,(A_UINT8
*)&userRssiThold
, sizeof(USER_RSSI_THOLD
));
2571 ar6000_hbChallengeResp_event(AR_SOFTC_T
*ar
, A_UINT32 cookie
, A_UINT32 source
)
2573 if (source
== APP_HB_CHALLENGE
) {
2574 /* Report it to the app in case it wants a positive acknowledgement */
2575 #ifdef SEND_EVENT_TO_APP
2576 ar6000_send_event_to_app(ar
, WMIX_HB_CHALLENGE_RESP_EVENTID
,
2577 (A_UINT8
*)&cookie
, sizeof(cookie
));
2580 /* This would ignore the replys that come in after their due time */
2581 if (cookie
== ar
->arHBChallengeResp
.seqNum
) {
2582 ar
->arHBChallengeResp
.outstanding
= FALSE
;
2589 ar6000_reportError_event(AR_SOFTC_T
*ar
, WMI_TARGET_ERROR_VAL errorVal
)
2591 char *errString
[] = {
2592 [WMI_TARGET_PM_ERR_FAIL
] "WMI_TARGET_PM_ERR_FAIL",
2593 [WMI_TARGET_KEY_NOT_FOUND
] "WMI_TARGET_KEY_NOT_FOUND",
2594 [WMI_TARGET_DECRYPTION_ERR
] "WMI_TARGET_DECRYPTION_ERR",
2595 [WMI_TARGET_BMISS
] "WMI_TARGET_BMISS",
2596 [WMI_PSDISABLE_NODE_JOIN
] "WMI_PSDISABLE_NODE_JOIN"
2599 A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal
);
2601 /* One error is reported at a time, and errorval is a bitmask */
2602 if(errorVal
& (errorVal
- 1))
2605 A_PRINTF("AR6000 Error type = ");
2608 case WMI_TARGET_PM_ERR_FAIL
:
2609 case WMI_TARGET_KEY_NOT_FOUND
:
2610 case WMI_TARGET_DECRYPTION_ERR
:
2611 case WMI_TARGET_BMISS
:
2612 case WMI_PSDISABLE_NODE_JOIN
:
2613 A_PRINTF("%s\n", errString
[errorVal
]);
2616 A_PRINTF("INVALID\n");
2624 ar6000_cac_event(AR_SOFTC_T
*ar
, A_UINT8 ac
, A_UINT8 cacIndication
,
2625 A_UINT8 statusCode
, A_UINT8
*tspecSuggestion
)
2627 WMM_TSPEC_IE
*tspecIe
;
2630 * This is the TSPEC IE suggestion from AP.
2631 * Suggestion provided by AP under some error
2632 * cases, could be helpful for the host app.
2633 * Check documentation.
2635 tspecIe
= (WMM_TSPEC_IE
*)tspecSuggestion
;
2638 * What do we do, if we get TSPEC rejection? One thought
2639 * that comes to mind is implictly delete the pstream...
2641 A_PRINTF("AR6000 CAC notification. "
2642 "AC = %d, cacIndication = 0x%x, statusCode = 0x%x\n",
2643 ac
, cacIndication
, statusCode
);
2646 #define AR6000_PRINT_BSSID(_pBss) do { \
2647 A_PRINTF("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",\
2648 (_pBss)[0],(_pBss)[1],(_pBss)[2],(_pBss)[3],\
2649 (_pBss)[4],(_pBss)[5]); \
2653 ar6000_roam_tbl_event(AR_SOFTC_T
*ar
, WMI_TARGET_ROAM_TBL
*pTbl
)
2657 A_PRINTF("ROAM TABLE NO OF ENTRIES is %d ROAM MODE is %d\n",
2658 pTbl
->numEntries
, pTbl
->roamMode
);
2659 for (i
= 0; i
< pTbl
->numEntries
; i
++) {
2660 A_PRINTF("[%d]bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", i
,
2661 pTbl
->bssRoamInfo
[i
].bssid
[0], pTbl
->bssRoamInfo
[i
].bssid
[1],
2662 pTbl
->bssRoamInfo
[i
].bssid
[2],
2663 pTbl
->bssRoamInfo
[i
].bssid
[3],
2664 pTbl
->bssRoamInfo
[i
].bssid
[4],
2665 pTbl
->bssRoamInfo
[i
].bssid
[5]);
2666 A_PRINTF("RSSI %d RSSIDT %d LAST RSSI %d UTIL %d ROAM_UTIL %d"
2668 pTbl
->bssRoamInfo
[i
].rssi
,
2669 pTbl
->bssRoamInfo
[i
].rssidt
,
2670 pTbl
->bssRoamInfo
[i
].last_rssi
,
2671 pTbl
->bssRoamInfo
[i
].util
,
2672 pTbl
->bssRoamInfo
[i
].roam_util
,
2673 pTbl
->bssRoamInfo
[i
].bias
);
2678 ar6000_wow_list_event(struct ar6_softc
*ar
, A_UINT8 num_filters
, WMI_GET_WOW_LIST_REPLY
*wow_reply
)
2682 /*Each event now contains exactly one filter, see bug 26613*/
2683 A_PRINTF("WOW pattern %d of %d patterns\n", wow_reply
->this_filter_num
, wow_reply
->num_filters
);
2684 A_PRINTF("wow mode = %s host mode = %s\n",
2685 (wow_reply
->wow_mode
== 0? "disabled":"enabled"),
2686 (wow_reply
->host_mode
== 1 ? "awake":"asleep"));
2689 /*If there are no patterns, the reply will only contain generic
2690 WoW information. Pattern information will exist only if there are
2691 patterns present. Bug 26716*/
2693 /* If this event contains pattern information, display it*/
2694 if (wow_reply
->this_filter_num
) {
2696 A_PRINTF("id=%d size=%d offset=%d\n",
2697 wow_reply
->wow_filters
[i
].wow_filter_id
,
2698 wow_reply
->wow_filters
[i
].wow_filter_size
,
2699 wow_reply
->wow_filters
[i
].wow_filter_offset
);
2700 A_PRINTF("wow pattern = ");
2701 for (j
=0; j
< wow_reply
->wow_filters
[i
].wow_filter_size
; j
++) {
2702 A_PRINTF("%2.2x",wow_reply
->wow_filters
[i
].wow_filter_pattern
[j
]);
2705 A_PRINTF("\nwow mask = ");
2706 for (j
=0; j
< wow_reply
->wow_filters
[i
].wow_filter_size
; j
++) {
2707 A_PRINTF("%2.2x",wow_reply
->wow_filters
[i
].wow_filter_mask
[j
]);
2714 * Report the Roaming related data collected on the target
2717 ar6000_display_roam_time(WMI_TARGET_ROAM_TIME
*p
)
2719 A_PRINTF("Disconnect Data : BSSID: ");
2720 AR6000_PRINT_BSSID(p
->disassoc_bssid
);
2721 A_PRINTF(" RSSI %d DISASSOC Time %d NO_TXRX_TIME %d\n",
2722 p
->disassoc_bss_rssi
,p
->disassoc_time
,
2724 A_PRINTF("Connect Data: BSSID: ");
2725 AR6000_PRINT_BSSID(p
->assoc_bssid
);
2726 A_PRINTF(" RSSI %d ASSOC Time %d TXRX_TIME %d\n",
2727 p
->assoc_bss_rssi
,p
->assoc_time
,
2728 p
->allow_txrx_time
);
2729 A_PRINTF("Last Data Tx Time (b4 Disassoc) %d "\
2730 "First Data Tx Time (after Assoc) %d\n",
2731 p
->last_data_txrx_time
, p
->first_data_txrx_time
);
2735 ar6000_roam_data_event(AR_SOFTC_T
*ar
, WMI_TARGET_ROAM_DATA
*p
)
2737 switch (p
->roamDataType
) {
2738 case ROAM_DATA_TIME
:
2739 ar6000_display_roam_time(&p
->u
.roamTime
);
2747 ar6000_bssInfo_event_rx(AR_SOFTC_T
*ar
, A_UINT8
*datap
, int len
)
2749 struct sk_buff
*skb
;
2750 WMI_BSS_INFO_HDR
*bih
= (WMI_BSS_INFO_HDR
*)datap
;
2753 if (!ar
->arMgmtFilter
) {
2756 if (((ar
->arMgmtFilter
& IEEE80211_FILTER_TYPE_BEACON
) &&
2757 (bih
->frameType
!= BEACON_FTYPE
)) ||
2758 ((ar
->arMgmtFilter
& IEEE80211_FILTER_TYPE_PROBE_RESP
) &&
2759 (bih
->frameType
!= PROBERESP_FTYPE
)))
2764 if ((skb
= A_NETBUF_ALLOC_RAW(len
)) != NULL
) {
2766 A_NETBUF_PUT(skb
, len
);
2767 A_MEMCPY(A_NETBUF_DATA(skb
), datap
, len
);
2768 skb
->dev
= ar
->arNetDev
;
2769 printk("MAC RAW...\n");
2770 // skb->mac.raw = A_NETBUF_DATA(skb);
2771 skb
->ip_summed
= CHECKSUM_NONE
;
2772 skb
->pkt_type
= PACKET_OTHERHOST
;
2773 skb
->protocol
= __constant_htons(0x0019);
2778 A_UINT32 wmiSendCmdNum
;
2781 ar6000_control_tx(void *devt
, void *osbuf
, WMI_PRI_STREAM_ID streamID
)
2783 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
2784 A_STATUS status
= A_OK
;
2785 struct ar_cookie
*cookie
= NULL
;
2788 /* take lock to protect ar6000_alloc_cookie() */
2789 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
2793 AR_DEBUG2_PRINTF("ar_contrstatus = ol_tx: skb=0x%x, len=0x%x, sid=%d\n",
2794 (A_UINT32
)osbuf
, A_NETBUF_LEN(osbuf
), streamID
);
2796 if ((streamID
== WMI_CONTROL_PRI
) && (ar
->arWMIControlEpFull
)) {
2797 /* control endpoint is full, don't allocate resources, we
2798 * are just going to drop this packet */
2800 AR_DEBUG_PRINTF(" WMI Control EP full, dropping packet : 0x%X, len:%d \n",
2801 (A_UINT32
)osbuf
, A_NETBUF_LEN(osbuf
));
2803 cookie
= ar6000_alloc_cookie(ar
);
2806 if (cookie
== NULL
) {
2807 status
= A_NO_MEMORY
;
2812 A_PRINTF("WMI cmd send, msgNo %d :", wmiSendCmdNum
);
2813 for(i
= 0; i
< a_netbuf_to_len(osbuf
); i
++)
2814 A_PRINTF("%x ", ((A_UINT8
*)a_netbuf_to_data(osbuf
))[i
]);
2822 if (cookie
!= NULL
) {
2823 /* got a structure to send it out on */
2824 ar
->arTxPending
[streamID
]++;
2826 if (streamID
!= WMI_CONTROL_PRI
) {
2827 ar
->arTotalTxDataPending
++;
2831 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
2833 if (cookie
!= NULL
) {
2834 cookie
->arc_bp
[0] = (A_UINT32
)osbuf
;
2835 cookie
->arc_bp
[1] = 0;
2836 SET_HTC_PACKET_INFO_TX(&cookie
->HtcPkt
,
2838 A_NETBUF_DATA(osbuf
),
2839 A_NETBUF_LEN(osbuf
),
2840 arWMIStream2EndpointID(ar
,streamID
),
2841 AR6K_CONTROL_PKT_TAG
);
2842 /* this interface is asynchronous, if there is an error, cleanup will happen in the
2843 * TX completion callback */
2844 HTCSendPkt(ar
->arHtcTarget
, &cookie
->HtcPkt
);
2851 /* indicate tx activity or inactivity on a WMI stream */
2852 void ar6000_indicate_tx_activity(void *devt
, A_UINT8 TrafficClass
, A_BOOL Active
)
2854 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
2855 WMI_PRI_STREAM_ID streamid
;
2857 if (ar
->arWmiEnabled
) {
2858 streamid
= wmi_get_stream_id(ar
->arWmi
, TrafficClass
);
2860 /* for mbox ping testing, the traffic class is mapped directly as a stream ID,
2861 * see handling of AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE in ioctl.c */
2862 streamid
= (WMI_PRI_STREAM_ID
)TrafficClass
;
2865 /* notify HTC, this may cause credit distribution changes */
2867 HTCIndicateActivityChange(ar
->arHtcTarget
,
2868 arWMIStream2EndpointID(ar
,streamid
),
2873 module_init(ar6000_init_module
);
2874 module_exit(ar6000_cleanup_module
);
2876 /* Init cookie queue */
2878 ar6000_cookie_init(AR_SOFTC_T
*ar
)
2882 ar
->arCookieList
= NULL
;
2883 A_MEMZERO(s_ar_cookie_mem
, sizeof(s_ar_cookie_mem
));
2885 for (i
= 0; i
< MAX_COOKIE_NUM
; i
++) {
2886 ar6000_free_cookie(ar
, &s_ar_cookie_mem
[i
]);
2890 /* cleanup cookie queue */
2892 ar6000_cookie_cleanup(AR_SOFTC_T
*ar
)
2894 /* It is gone .... */
2895 ar
->arCookieList
= NULL
;
2898 /* Init cookie queue */
2900 ar6000_free_cookie(AR_SOFTC_T
*ar
, struct ar_cookie
* cookie
)
2903 A_ASSERT(ar
!= NULL
);
2904 A_ASSERT(cookie
!= NULL
);
2905 cookie
->arc_list_next
= ar
->arCookieList
;
2906 ar
->arCookieList
= cookie
;
2909 /* cleanup cookie queue */
2910 static struct ar_cookie
*
2911 ar6000_alloc_cookie(AR_SOFTC_T
*ar
)
2913 struct ar_cookie
*cookie
;
2915 cookie
= ar
->arCookieList
;
2918 ar
->arCookieList
= cookie
->arc_list_next
;
2924 #ifdef SEND_EVENT_TO_APP
2926 * This function is used to send event which come from taget to
2927 * the application. The buf which send to application is include
2928 * the event ID and event content.
2930 #define EVENT_ID_LEN 2
2931 void ar6000_send_event_to_app(AR_SOFTC_T
*ar
, A_UINT16 eventId
,
2932 A_UINT8
*datap
, int len
)
2935 #if (WIRELESS_EXT >= 15)
2937 /* note: IWEVCUSTOM only exists in wireless extensions after version 15 */
2941 union iwreq_data wrqu
;
2943 size
= len
+ EVENT_ID_LEN
;
2945 if (size
> IW_CUSTOM_MAX
) {
2946 AR_DEBUG_PRINTF("WMI event ID : 0x%4.4X, len = %d too big for IWEVCUSTOM (max=%d) \n",
2947 eventId
, size
, IW_CUSTOM_MAX
);
2951 buf
= A_MALLOC_NOWAIT(size
);
2952 A_MEMZERO(buf
, size
);
2953 A_MEMCPY(buf
, &eventId
, EVENT_ID_LEN
);
2954 A_MEMCPY(buf
+EVENT_ID_LEN
, datap
, len
);
2956 //AR_DEBUG_PRINTF("event ID = %d,len = %d\n",*(A_UINT16*)buf, size);
2957 A_MEMZERO(&wrqu
, sizeof(wrqu
));
2958 wrqu
.data
.length
= size
;
2959 wireless_send_event(ar
->arNetDev
, IWEVCUSTOM
, &wrqu
, buf
);
2970 ar6000_tx_retry_err_event(void *devt
)
2972 AR_DEBUG2_PRINTF("Tx retries reach maximum!\n");
2976 ar6000_snrThresholdEvent_rx(void *devt
, WMI_SNR_THRESHOLD_VAL newThreshold
, A_UINT8 snr
)
2978 AR_DEBUG2_PRINTF("snr threshold range %d, snr %d\n", newThreshold
, snr
);
2982 ar6000_lqThresholdEvent_rx(void *devt
, WMI_LQ_THRESHOLD_VAL newThreshold
, A_UINT8 lq
)
2984 AR_DEBUG2_PRINTF("lq threshold range %d, lq %d\n", newThreshold
, lq
);
2990 a_copy_to_user(void *to
, const void *from
, A_UINT32 n
)
2992 return(copy_to_user(to
, from
, n
));
2996 a_copy_from_user(void *to
, const void *from
, A_UINT32 n
)
2998 return(copy_from_user(to
, from
, n
));
3003 ar6000_get_driver_cfg(struct net_device
*dev
,
3012 case AR6000_DRIVER_CFG_GET_WLANNODECACHING
:
3013 *((A_UINT32
*)result
) = wlanNodeCaching
;
3015 case AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS
:
3016 *((A_UINT32
*)result
) = logWmiRawMsgs
;
3027 ar6000_keepalive_rx(void *devt
, A_UINT8 configured
)
3029 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)devt
;
3031 ar
->arKeepaliveConfigured
= configured
;
3036 ar6000_pmkid_list_event(void *devt
, A_UINT8 numPMKID
, WMI_PMKID
*pmkidList
)
3040 A_PRINTF("Number of Cached PMKIDs is %d\n", numPMKID
);
3042 for (i
= 0; i
< numPMKID
; i
++) {
3043 A_PRINTF("\nPMKID %d ", i
);
3044 for (j
= 0; j
< WMI_PMKID_LEN
; j
++) {
3045 A_PRINTF("%2.2x", pmkidList
->pmkid
[j
]);
3054 ar6000_reinstall_keys(AR_SOFTC_T
*ar
, A_UINT8 key_op_ctrl
)
3056 A_STATUS status
= A_OK
;
3057 struct ieee80211req_key
*uik
= &ar
->user_saved_keys
.ucast_ik
;
3058 struct ieee80211req_key
*bik
= &ar
->user_saved_keys
.bcast_ik
;
3059 CRYPTO_TYPE keyType
= ar
->user_saved_keys
.keyType
;
3061 if (IEEE80211_CIPHER_CCKM_KRK
!= uik
->ik_type
) {
3062 if (NONE_CRYPT
== keyType
) {
3063 goto _reinstall_keys_out
;
3066 if (uik
->ik_keylen
) {
3067 status
= wmi_addKey_cmd(ar
->arWmi
, uik
->ik_keyix
,
3068 ar
->user_saved_keys
.keyType
, PAIRWISE_USAGE
,
3069 uik
->ik_keylen
, (A_UINT8
*)&uik
->ik_keyrsc
,
3070 uik
->ik_keydata
, key_op_ctrl
, SYNC_BEFORE_WMIFLAG
);
3074 status
= wmi_add_krk_cmd(ar
->arWmi
, uik
->ik_keydata
);
3077 if (IEEE80211_CIPHER_CCKM_KRK
!= bik
->ik_type
) {
3078 if (NONE_CRYPT
== keyType
) {
3079 goto _reinstall_keys_out
;
3082 if (bik
->ik_keylen
) {
3083 status
= wmi_addKey_cmd(ar
->arWmi
, bik
->ik_keyix
,
3084 ar
->user_saved_keys
.keyType
, GROUP_USAGE
,
3085 bik
->ik_keylen
, (A_UINT8
*)&bik
->ik_keyrsc
,
3086 bik
->ik_keydata
, key_op_ctrl
, NO_SYNC_WMIFLAG
);
3089 status
= wmi_add_krk_cmd(ar
->arWmi
, bik
->ik_keydata
);
3092 _reinstall_keys_out
:
3093 ar
->user_savedkeys_stat
= USER_SAVEDKEYS_STAT_INIT
;
3094 ar
->user_key_ctrl
= 0;
3098 #endif /* USER_KEYS */
3102 ar6000_dset_open_req(
3105 A_UINT32 targHandle
,
3106 A_UINT32 targReplyFn
,
3107 A_UINT32 targReplyArg
)
3114 A_UINT32 access_cookie
)
3120 ar6000_dset_data_req(
3122 A_UINT32 accessCookie
,
3126 A_UINT32 targReplyFn
,
3127 A_UINT32 targReplyArg
)