aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/ath6kl/os
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/ath6kl/os')
-rw-r--r--drivers/staging/ath6kl/os/linux/ar6000_drv.c6267
-rw-r--r--drivers/staging/ath6kl/os/linux/ar6000_pm.c626
-rw-r--r--drivers/staging/ath6kl/os/linux/ar6000_raw_if.c455
-rw-r--r--drivers/staging/ath6kl/os/linux/cfg80211.c1892
-rw-r--r--drivers/staging/ath6kl/os/linux/export_hci_transport.c124
-rw-r--r--drivers/staging/ath6kl/os/linux/hci_bridge.c1141
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ar6000_drv.h776
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ar6k_pal.h36
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h190
-rw-r--r--drivers/staging/ath6kl/os/linux/include/athdrv_linux.h1217
-rw-r--r--drivers/staging/ath6kl/os/linux/include/cfg80211.h61
-rw-r--r--drivers/staging/ath6kl/os/linux/include/config_linux.h51
-rw-r--r--drivers/staging/ath6kl/os/linux/include/debug_linux.h50
-rw-r--r--drivers/staging/ath6kl/os/linux/include/export_hci_transport.h76
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h177
-rw-r--r--drivers/staging/ath6kl/os/linux/include/osapi_linux.h339
-rw-r--r--drivers/staging/ath6kl/os/linux/include/wlan_config.h108
-rw-r--r--drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h300
-rw-r--r--drivers/staging/ath6kl/os/linux/netbuf.c231
19 files changed, 14117 insertions, 0 deletions
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c
new file mode 100644
index 00000000000..32ee39ad00d
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c
@@ -0,0 +1,6267 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24/*
25 * This driver is a pseudo ethernet driver to access the Atheros AR6000
26 * WLAN Device
27 */
28
29#include "ar6000_drv.h"
30#include "cfg80211.h"
31#include "htc.h"
32#include "wmi_filter_linux.h"
33#include "epping_test.h"
34#include "wlan_config.h"
35#include "ar3kconfig.h"
36#include "ar6k_pal.h"
37#include "AR6002/addrs.h"
38
39
40/* LINUX_HACK_FUDGE_FACTOR -- this is used to provide a workaround for linux behavior. When
41 * the meta data was added to the header it was found that linux did not correctly provide
42 * enough headroom. However when more headroom was requested beyond what was truly needed
43 * Linux gave the requested headroom. Therefore to get the necessary headroom from Linux
44 * the driver requests more than is needed by the amount = LINUX_HACK_FUDGE_FACTOR */
45#define LINUX_HACK_FUDGE_FACTOR 16
46#define BDATA_BDADDR_OFFSET 28
47
48u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
49u8 null_mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
50
51#ifdef DEBUG
52
53#define ATH_DEBUG_DBG_LOG ATH_DEBUG_MAKE_MODULE_MASK(0)
54#define ATH_DEBUG_WLAN_CONNECT ATH_DEBUG_MAKE_MODULE_MASK(1)
55#define ATH_DEBUG_WLAN_SCAN ATH_DEBUG_MAKE_MODULE_MASK(2)
56#define ATH_DEBUG_WLAN_TX ATH_DEBUG_MAKE_MODULE_MASK(3)
57#define ATH_DEBUG_WLAN_RX ATH_DEBUG_MAKE_MODULE_MASK(4)
58#define ATH_DEBUG_HTC_RAW ATH_DEBUG_MAKE_MODULE_MASK(5)
59#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
60
61static struct ath_debug_mask_description driver_debug_desc[] = {
62 { ATH_DEBUG_DBG_LOG , "Target Debug Logs"},
63 { ATH_DEBUG_WLAN_CONNECT , "WLAN connect"},
64 { ATH_DEBUG_WLAN_SCAN , "WLAN scan"},
65 { ATH_DEBUG_WLAN_TX , "WLAN Tx"},
66 { ATH_DEBUG_WLAN_RX , "WLAN Rx"},
67 { ATH_DEBUG_HTC_RAW , "HTC Raw IF tracing"},
68 { ATH_DEBUG_HCI_BRIDGE , "HCI Bridge Setup"},
69 { ATH_DEBUG_HCI_RECV , "HCI Recv tracing"},
70 { ATH_DEBUG_HCI_DUMP , "HCI Packet dumps"},
71};
72
73ATH_DEBUG_INSTANTIATE_MODULE_VAR(driver,
74 "driver",
75 "Linux Driver Interface",
76 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_WLAN_SCAN |
77 ATH_DEBUG_HCI_BRIDGE,
78 ATH_DEBUG_DESCRIPTION_COUNT(driver_debug_desc),
79 driver_debug_desc);
80
81#endif
82
83
84#define IS_MAC_NULL(mac) (mac[0]==0 && mac[1]==0 && mac[2]==0 && mac[3]==0 && mac[4]==0 && mac[5]==0)
85#define IS_MAC_BCAST(mac) (*mac==0xff)
86
87#define DESCRIPTION "Driver to access the Atheros AR600x Device, version " __stringify(__VER_MAJOR_) "." __stringify(__VER_MINOR_) "." __stringify(__VER_PATCH_) "." __stringify(__BUILD_NUMBER_)
88
89MODULE_AUTHOR("Atheros Communications, Inc.");
90MODULE_DESCRIPTION(DESCRIPTION);
91MODULE_LICENSE("Dual BSD/GPL");
92
93#ifndef REORG_APTC_HEURISTICS
94#undef ADAPTIVE_POWER_THROUGHPUT_CONTROL
95#endif /* REORG_APTC_HEURISTICS */
96
97#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
98#define APTC_TRAFFIC_SAMPLING_INTERVAL 100 /* msec */
99#define APTC_UPPER_THROUGHPUT_THRESHOLD 3000 /* Kbps */
100#define APTC_LOWER_THROUGHPUT_THRESHOLD 2000 /* Kbps */
101
102typedef struct aptc_traffic_record {
103 bool timerScheduled;
104 struct timeval samplingTS;
105 unsigned long bytesReceived;
106 unsigned long bytesTransmitted;
107} APTC_TRAFFIC_RECORD;
108
109A_TIMER aptcTimer;
110APTC_TRAFFIC_RECORD aptcTR;
111#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
112
113#ifdef EXPORT_HCI_BRIDGE_INTERFACE
114// callbacks registered by HCI transport driver
115struct hci_transport_callbacks ar6kHciTransCallbacks = { NULL };
116#endif
117
118unsigned int processDot11Hdr = 0;
119
120char ifname[IFNAMSIZ] = {0,};
121
122int wlaninitmode = WLAN_INIT_MODE_DEFAULT;
123static bool bypasswmi;
124unsigned int debuglevel = 0;
125int tspecCompliance = ATHEROS_COMPLIANCE;
126unsigned int busspeedlow = 0;
127unsigned int onebitmode = 0;
128unsigned int skipflash = 0;
129unsigned int wmitimeout = 2;
130unsigned int wlanNodeCaching = 1;
131unsigned int enableuartprint = ENABLEUARTPRINT_DEFAULT;
132unsigned int logWmiRawMsgs = 0;
133unsigned int enabletimerwar = 0;
134unsigned int num_device = 1;
135unsigned int regscanmode;
136unsigned int fwmode = 1;
137unsigned int mbox_yield_limit = 99;
138unsigned int enablerssicompensation = 0;
139int reduce_credit_dribble = 1 + HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF;
140int allow_trace_signal = 0;
141#ifdef CONFIG_HOST_TCMD_SUPPORT
142unsigned int testmode =0;
143#endif
144
145unsigned int irqprocmode = HIF_DEVICE_IRQ_SYNC_ONLY;//HIF_DEVICE_IRQ_ASYNC_SYNC;
146unsigned int panic_on_assert = 1;
147unsigned int nohifscattersupport = NOHIFSCATTERSUPPORT_DEFAULT;
148
149unsigned int setuphci = SETUPHCI_DEFAULT;
150unsigned int loghci = 0;
151unsigned int setupbtdev = SETUPBTDEV_DEFAULT;
152#ifndef EXPORT_HCI_BRIDGE_INTERFACE
153unsigned int ar3khcibaud = AR3KHCIBAUD_DEFAULT;
154unsigned int hciuartscale = HCIUARTSCALE_DEFAULT;
155unsigned int hciuartstep = HCIUARTSTEP_DEFAULT;
156#endif
157unsigned int csumOffload=0;
158unsigned int csumOffloadTest=0;
159unsigned int eppingtest=0;
160unsigned int mac_addr_method;
161unsigned int firmware_bridge;
162
163module_param_string(ifname, ifname, sizeof(ifname), 0644);
164module_param(wlaninitmode, int, 0644);
165module_param(bypasswmi, bool, 0644);
166module_param(debuglevel, uint, 0644);
167module_param(tspecCompliance, int, 0644);
168module_param(onebitmode, uint, 0644);
169module_param(busspeedlow, uint, 0644);
170module_param(skipflash, uint, 0644);
171module_param(wmitimeout, uint, 0644);
172module_param(wlanNodeCaching, uint, 0644);
173module_param(logWmiRawMsgs, uint, 0644);
174module_param(enableuartprint, uint, 0644);
175module_param(enabletimerwar, uint, 0644);
176module_param(fwmode, uint, 0644);
177module_param(mbox_yield_limit, uint, 0644);
178module_param(reduce_credit_dribble, int, 0644);
179module_param(allow_trace_signal, int, 0644);
180module_param(enablerssicompensation, uint, 0644);
181module_param(processDot11Hdr, uint, 0644);
182module_param(csumOffload, uint, 0644);
183#ifdef CONFIG_HOST_TCMD_SUPPORT
184module_param(testmode, uint, 0644);
185#endif
186module_param(irqprocmode, uint, 0644);
187module_param(nohifscattersupport, uint, 0644);
188module_param(panic_on_assert, uint, 0644);
189module_param(setuphci, uint, 0644);
190module_param(loghci, uint, 0644);
191module_param(setupbtdev, uint, 0644);
192#ifndef EXPORT_HCI_BRIDGE_INTERFACE
193module_param(ar3khcibaud, uint, 0644);
194module_param(hciuartscale, uint, 0644);
195module_param(hciuartstep, uint, 0644);
196#endif
197module_param(eppingtest, uint, 0644);
198
199/* in 2.6.10 and later this is now a pointer to a uint */
200unsigned int _mboxnum = HTC_MAILBOX_NUM_MAX;
201#define mboxnum &_mboxnum
202
203#ifdef DEBUG
204u32 g_dbg_flags = DBG_DEFAULTS;
205unsigned int debugflags = 0;
206int debugdriver = 0;
207unsigned int debughtc = 0;
208unsigned int debugbmi = 0;
209unsigned int debughif = 0;
210unsigned int txcreditsavailable[HTC_MAILBOX_NUM_MAX] = {0};
211unsigned int txcreditsconsumed[HTC_MAILBOX_NUM_MAX] = {0};
212unsigned int txcreditintrenable[HTC_MAILBOX_NUM_MAX] = {0};
213unsigned int txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX] = {0};
214module_param(debugflags, uint, 0644);
215module_param(debugdriver, int, 0644);
216module_param(debughtc, uint, 0644);
217module_param(debugbmi, uint, 0644);
218module_param(debughif, uint, 0644);
219module_param_array(txcreditsavailable, uint, mboxnum, 0644);
220module_param_array(txcreditsconsumed, uint, mboxnum, 0644);
221module_param_array(txcreditintrenable, uint, mboxnum, 0644);
222module_param_array(txcreditintrenableaggregate, uint, mboxnum, 0644);
223
224#endif /* DEBUG */
225
226unsigned int resetok = 1;
227unsigned int tx_attempt[HTC_MAILBOX_NUM_MAX] = {0};
228unsigned int tx_post[HTC_MAILBOX_NUM_MAX] = {0};
229unsigned int tx_complete[HTC_MAILBOX_NUM_MAX] = {0};
230unsigned int hifBusRequestNumMax = 40;
231unsigned int war23838_disabled = 0;
232#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
233unsigned int enableAPTCHeuristics = 1;
234#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
235module_param_array(tx_attempt, uint, mboxnum, 0644);
236module_param_array(tx_post, uint, mboxnum, 0644);
237module_param_array(tx_complete, uint, mboxnum, 0644);
238module_param(hifBusRequestNumMax, uint, 0644);
239module_param(war23838_disabled, uint, 0644);
240module_param(resetok, uint, 0644);
241#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
242module_param(enableAPTCHeuristics, uint, 0644);
243#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
244
245#ifdef BLOCK_TX_PATH_FLAG
246int blocktx = 0;
247module_param(blocktx, int, 0644);
248#endif /* BLOCK_TX_PATH_FLAG */
249
250typedef struct user_rssi_compensation_t {
251 u16 customerID;
252 union {
253 u16 a_enable;
254 u16 bg_enable;
255 u16 enable;
256 };
257 s16 bg_param_a;
258 s16 bg_param_b;
259 s16 a_param_a;
260 s16 a_param_b;
261 u32 reserved;
262} USER_RSSI_CPENSATION;
263
264static USER_RSSI_CPENSATION rssi_compensation_param;
265
266static s16 rssi_compensation_table[96];
267
268int reconnect_flag = 0;
269static ar6k_pal_config_t ar6k_pal_config_g;
270
271/* Function declarations */
272static int ar6000_init_module(void);
273static void ar6000_cleanup_module(void);
274
275int ar6000_init(struct net_device *dev);
276static int ar6000_open(struct net_device *dev);
277static int ar6000_close(struct net_device *dev);
278static void ar6000_init_control_info(struct ar6_softc *ar);
279static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev);
280
281void ar6000_destroy(struct net_device *dev, unsigned int unregister);
282static void ar6000_detect_error(unsigned long ptr);
283static void ar6000_set_multicast_list(struct net_device *dev);
284static struct net_device_stats *ar6000_get_stats(struct net_device *dev);
285
286static void disconnect_timer_handler(unsigned long ptr);
287
288void read_rssi_compensation_param(struct ar6_softc *ar);
289
290/*
291 * HTC service connection handlers
292 */
293static int ar6000_avail_ev(void *context, void *hif_handle);
294
295static int ar6000_unavail_ev(void *context, void *hif_handle);
296
297int ar6000_configure_target(struct ar6_softc *ar);
298
299static void ar6000_target_failure(void *Instance, int Status);
300
301static void ar6000_rx(void *Context, struct htc_packet *pPacket);
302
303static void ar6000_rx_refill(void *Context,HTC_ENDPOINT_ID Endpoint);
304
305static void ar6000_tx_complete(void *Context, struct htc_packet_queue *pPackets);
306
307static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket);
308
309static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num);
310static void ar6000_deliver_frames_to_nw_stack(void * dev, void *osbuf);
311//static void ar6000_deliver_frames_to_bt_stack(void * dev, void *osbuf);
312
313static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length);
314
315static void ar6000_refill_amsdu_rxbufs(struct ar6_softc *ar, int Count);
316
317static void ar6000_cleanup_amsdu_rxbufs(struct ar6_softc *ar);
318
319static ssize_t
320ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj,
321 struct bin_attribute *bin_attr,
322 char *buf, loff_t pos, size_t count);
323
324static ssize_t
325ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj,
326 struct bin_attribute *bin_attr,
327 char *buf, loff_t pos, size_t count);
328
329static int
330ar6000_sysfs_bmi_init(struct ar6_softc *ar);
331
332void ar6k_cleanup_hci_pal(struct ar6_softc *ar);
333
334static void
335ar6000_sysfs_bmi_deinit(struct ar6_softc *ar);
336
337int
338ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode);
339
340/*
341 * Static variables
342 */
343
344struct net_device *ar6000_devices[MAX_AR6000];
345static int is_netdev_registered;
346DECLARE_WAIT_QUEUE_HEAD(arEvent);
347static void ar6000_cookie_init(struct ar6_softc *ar);
348static void ar6000_cookie_cleanup(struct ar6_softc *ar);
349static void ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie);
350static struct ar_cookie *ar6000_alloc_cookie(struct ar6_softc *ar);
351
352static int ar6000_reinstall_keys(struct ar6_softc *ar,u8 key_op_ctrl);
353
354#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
355struct net_device *arApNetDev;
356#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
357
358static struct ar_cookie s_ar_cookie_mem[MAX_COOKIE_NUM];
359
360#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
361 (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
362 (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0))
363
364
365static struct net_device_ops ar6000_netdev_ops = {
366 .ndo_init = NULL,
367 .ndo_open = ar6000_open,
368 .ndo_stop = ar6000_close,
369 .ndo_get_stats = ar6000_get_stats,
370 .ndo_start_xmit = ar6000_data_tx,
371 .ndo_set_multicast_list = ar6000_set_multicast_list,
372};
373
374/* Debug log support */
375
376/*
377 * Flag to govern whether the debug logs should be parsed in the kernel
378 * or reported to the application.
379 */
380#define REPORT_DEBUG_LOGS_TO_APP
381
382int
383ar6000_set_host_app_area(struct ar6_softc *ar)
384{
385 u32 address, data;
386 struct host_app_area_s host_app_area;
387
388 /* Fetch the address of the host_app_area_s instance in the host interest area */
389 address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest));
390 if (ar6000_ReadRegDiag(ar->arHifDevice, &address, &data) != 0) {
391 return A_ERROR;
392 }
393 address = TARG_VTOP(ar->arTargetType, data);
394 host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION;
395 if (ar6000_WriteDataDiag(ar->arHifDevice, address,
396 (u8 *)&host_app_area,
397 sizeof(struct host_app_area_s)) != 0)
398 {
399 return A_ERROR;
400 }
401
402 return 0;
403}
404
405u32 dbglog_get_debug_hdr_ptr(struct ar6_softc *ar)
406{
407 u32 param;
408 u32 address;
409 int status;
410
411 address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbglog_hdr));
412 if ((status = ar6000_ReadDataDiag(ar->arHifDevice, address,
413 (u8 *)&param, 4)) != 0)
414 {
415 param = 0;
416 }
417
418 return param;
419}
420
421/*
422 * The dbglog module has been initialized. Its ok to access the relevant
423 * data stuctures over the diagnostic window.
424 */
425void
426ar6000_dbglog_init_done(struct ar6_softc *ar)
427{
428 ar->dbglog_init_done = true;
429}
430
431u32 dbglog_get_debug_fragment(s8 *datap, u32 len, u32 limit)
432{
433 s32 *buffer;
434 u32 count;
435 u32 numargs;
436 u32 length;
437 u32 fraglen;
438
439 count = fraglen = 0;
440 buffer = (s32 *)datap;
441 length = (limit >> 2);
442
443 if (len <= limit) {
444 fraglen = len;
445 } else {
446 while (count < length) {
447 numargs = DBGLOG_GET_NUMARGS(buffer[count]);
448 fraglen = (count << 2);
449 count += numargs + 1;
450 }
451 }
452
453 return fraglen;
454}
455
456void
457dbglog_parse_debug_logs(s8 *datap, u32 len)
458{
459 s32 *buffer;
460 u32 count;
461 u32 timestamp;
462 u32 debugid;
463 u32 moduleid;
464 u32 numargs;
465 u32 length;
466
467 count = 0;
468 buffer = (s32 *)datap;
469 length = (len >> 2);
470 while (count < length) {
471 debugid = DBGLOG_GET_DBGID(buffer[count]);
472 moduleid = DBGLOG_GET_MODULEID(buffer[count]);
473 numargs = DBGLOG_GET_NUMARGS(buffer[count]);
474 timestamp = DBGLOG_GET_TIMESTAMP(buffer[count]);
475 switch (numargs) {
476 case 0:
477 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d)\n", moduleid, debugid, timestamp));
478 break;
479
480 case 1:
481 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x\n", moduleid, debugid,
482 timestamp, buffer[count+1]));
483 break;
484
485 case 2:
486 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x, 0x%x\n", moduleid, debugid,
487 timestamp, buffer[count+1], buffer[count+2]));
488 break;
489
490 default:
491 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid args: %d\n", numargs));
492 }
493 count += numargs + 1;
494 }
495}
496
497int
498ar6000_dbglog_get_debug_logs(struct ar6_softc *ar)
499{
500 u32 data[8]; /* Should be able to accommodate struct dbglog_buf_s */
501 u32 address;
502 u32 length;
503 u32 dropped;
504 u32 firstbuf;
505 u32 debug_hdr_ptr;
506
507 if (!ar->dbglog_init_done) return A_ERROR;
508
509
510 AR6000_SPIN_LOCK(&ar->arLock, 0);
511
512 if (ar->dbgLogFetchInProgress) {
513 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
514 return A_EBUSY;
515 }
516
517 /* block out others */
518 ar->dbgLogFetchInProgress = true;
519
520 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
521
522 debug_hdr_ptr = dbglog_get_debug_hdr_ptr(ar);
523 printk("debug_hdr_ptr: 0x%x\n", debug_hdr_ptr);
524
525 /* Get the contents of the ring buffer */
526 if (debug_hdr_ptr) {
527 address = TARG_VTOP(ar->arTargetType, debug_hdr_ptr);
528 length = 4 /* sizeof(dbuf) */ + 4 /* sizeof(dropped) */;
529 A_MEMZERO(data, sizeof(data));
530 ar6000_ReadDataDiag(ar->arHifDevice, address, (u8 *)data, length);
531 address = TARG_VTOP(ar->arTargetType, data[0] /* dbuf */);
532 firstbuf = address;
533 dropped = data[1]; /* dropped */
534 length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */;
535 A_MEMZERO(data, sizeof(data));
536 ar6000_ReadDataDiag(ar->arHifDevice, address, (u8 *)&data, length);
537
538 do {
539 address = TARG_VTOP(ar->arTargetType, data[1] /* buffer*/);
540 length = data[3]; /* length */
541 if ((length) && (length <= data[2] /* bufsize*/)) {
542 /* Rewind the index if it is about to overrun the buffer */
543 if (ar->log_cnt > (DBGLOG_HOST_LOG_BUFFER_SIZE - length)) {
544 ar->log_cnt = 0;
545 }
546 if(0 != ar6000_ReadDataDiag(ar->arHifDevice, address,
547 (u8 *)&ar->log_buffer[ar->log_cnt], length))
548 {
549 break;
550 }
551 ar6000_dbglog_event(ar, dropped, (s8 *)&ar->log_buffer[ar->log_cnt], length);
552 ar->log_cnt += length;
553 } else {
554 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("Length: %d (Total size: %d)\n",
555 data[3], data[2]));
556 }
557
558 address = TARG_VTOP(ar->arTargetType, data[0] /* next */);
559 length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */;
560 A_MEMZERO(data, sizeof(data));
561 if(0 != ar6000_ReadDataDiag(ar->arHifDevice, address,
562 (u8 *)&data, length))
563 {
564 break;
565 }
566
567 } while (address != firstbuf);
568 }
569
570 ar->dbgLogFetchInProgress = false;
571
572 return 0;
573}
574
575void
576ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped,
577 s8 *buffer, u32 length)
578{
579#ifdef REPORT_DEBUG_LOGS_TO_APP
580 #define MAX_WIRELESS_EVENT_SIZE 252
581 /*
582 * Break it up into chunks of MAX_WIRELESS_EVENT_SIZE bytes of messages.
583 * There seems to be a limitation on the length of message that could be
584 * transmitted to the user app via this mechanism.
585 */
586 u32 send, sent;
587
588 sent = 0;
589 send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
590 MAX_WIRELESS_EVENT_SIZE);
591 while (send) {
592 sent += send;
593 send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
594 MAX_WIRELESS_EVENT_SIZE);
595 }
596#else
597 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Dropped logs: 0x%x\nDebug info length: %d\n",
598 dropped, length));
599
600 /* Interpret the debug logs */
601 dbglog_parse_debug_logs((s8 *)buffer, length);
602#endif /* REPORT_DEBUG_LOGS_TO_APP */
603}
604
605
606static int __init
607ar6000_init_module(void)
608{
609 static int probed = 0;
610 int r;
611 OSDRV_CALLBACKS osdrvCallbacks;
612
613 a_module_debug_support_init();
614
615#ifdef DEBUG
616 /* check for debug mask overrides */
617 if (debughtc != 0) {
618 ATH_DEBUG_SET_DEBUG_MASK(htc,debughtc);
619 }
620 if (debugbmi != 0) {
621 ATH_DEBUG_SET_DEBUG_MASK(bmi,debugbmi);
622 }
623 if (debughif != 0) {
624 ATH_DEBUG_SET_DEBUG_MASK(hif,debughif);
625 }
626 if (debugdriver != 0) {
627 ATH_DEBUG_SET_DEBUG_MASK(driver,debugdriver);
628 }
629
630#endif
631
632 A_REGISTER_MODULE_DEBUG_INFO(driver);
633
634 A_MEMZERO(&osdrvCallbacks,sizeof(osdrvCallbacks));
635 osdrvCallbacks.deviceInsertedHandler = ar6000_avail_ev;
636 osdrvCallbacks.deviceRemovedHandler = ar6000_unavail_ev;
637#ifdef CONFIG_PM
638 osdrvCallbacks.deviceSuspendHandler = ar6000_suspend_ev;
639 osdrvCallbacks.deviceResumeHandler = ar6000_resume_ev;
640 osdrvCallbacks.devicePowerChangeHandler = ar6000_power_change_ev;
641#endif
642
643#ifdef DEBUG
644 /* Set the debug flags if specified at load time */
645 if(debugflags != 0)
646 {
647 g_dbg_flags = debugflags;
648 }
649#endif
650
651 if (probed) {
652 return -ENODEV;
653 }
654 probed++;
655
656#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
657 memset(&aptcTR, 0, sizeof(APTC_TRAFFIC_RECORD));
658#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
659
660 r = HIFInit(&osdrvCallbacks);
661 if (r)
662 return r;
663
664 return 0;
665}
666
667static void __exit
668ar6000_cleanup_module(void)
669{
670 int i = 0;
671 struct net_device *ar6000_netdev;
672
673#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
674 /* Delete the Adaptive Power Control timer */
675 if (timer_pending(&aptcTimer)) {
676 del_timer_sync(&aptcTimer);
677 }
678#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
679
680 for (i=0; i < MAX_AR6000; i++) {
681 if (ar6000_devices[i] != NULL) {
682 ar6000_netdev = ar6000_devices[i];
683 ar6000_devices[i] = NULL;
684 ar6000_destroy(ar6000_netdev, 1);
685 }
686 }
687
688 HIFShutDownDevice(NULL);
689
690 a_module_debug_support_cleanup();
691
692 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_cleanup: success\n"));
693}
694
695#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
696void
697aptcTimerHandler(unsigned long arg)
698{
699 u32 numbytes;
700 u32 throughput;
701 struct ar6_softc *ar;
702 int status;
703
704 ar = (struct ar6_softc *)arg;
705 A_ASSERT(ar != NULL);
706 A_ASSERT(!timer_pending(&aptcTimer));
707
708 AR6000_SPIN_LOCK(&ar->arLock, 0);
709
710 /* Get the number of bytes transferred */
711 numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
712 aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
713
714 /* Calculate and decide based on throughput thresholds */
715 throughput = ((numbytes * 8)/APTC_TRAFFIC_SAMPLING_INTERVAL); /* Kbps */
716 if (throughput < APTC_LOWER_THROUGHPUT_THRESHOLD) {
717 /* Enable Sleep and delete the timer */
718 A_ASSERT(ar->arWmiReady == true);
719 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
720 status = wmi_powermode_cmd(ar->arWmi, REC_POWER);
721 AR6000_SPIN_LOCK(&ar->arLock, 0);
722 A_ASSERT(status == 0);
723 aptcTR.timerScheduled = false;
724 } else {
725 A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
726 }
727
728 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
729}
730#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
731
732static void
733ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num)
734{
735 void * osbuf;
736
737 while(num) {
738 if((osbuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE))) {
739 A_NETBUF_ENQUEUE(q, osbuf);
740 } else {
741 break;
742 }
743 num--;
744 }
745
746 if(num) {
747 A_PRINTF("%s(), allocation of netbuf failed", __func__);
748 }
749}
750
751static struct bin_attribute bmi_attr = {
752 .attr = {.name = "bmi", .mode = 0600},
753 .read = ar6000_sysfs_bmi_read,
754 .write = ar6000_sysfs_bmi_write,
755};
756
757static ssize_t
758ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj,
759 struct bin_attribute *bin_attr,
760 char *buf, loff_t pos, size_t count)
761{
762 int index;
763 struct ar6_softc *ar;
764 struct hif_device_os_device_info *osDevInfo;
765
766 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Read %d bytes\n", (u32)count));
767 for (index=0; index < MAX_AR6000; index++) {
768 ar = (struct ar6_softc *)ar6k_priv(ar6000_devices[index]);
769 osDevInfo = &ar->osDevInfo;
770 if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) {
771 break;
772 }
773 }
774
775 if (index == MAX_AR6000) return 0;
776
777 if ((BMIRawRead(ar->arHifDevice, (u8*)buf, count, true)) != 0) {
778 return 0;
779 }
780
781 return count;
782}
783
784static ssize_t
785ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj,
786 struct bin_attribute *bin_attr,
787 char *buf, loff_t pos, size_t count)
788{
789 int index;
790 struct ar6_softc *ar;
791 struct hif_device_os_device_info *osDevInfo;
792
793 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Write %d bytes\n", (u32)count));
794 for (index=0; index < MAX_AR6000; index++) {
795 ar = (struct ar6_softc *)ar6k_priv(ar6000_devices[index]);
796 osDevInfo = &ar->osDevInfo;
797 if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) {
798 break;
799 }
800 }
801
802 if (index == MAX_AR6000) return 0;
803
804 if ((BMIRawWrite(ar->arHifDevice, (u8*)buf, count)) != 0) {
805 return 0;
806 }
807
808 return count;
809}
810
811static int
812ar6000_sysfs_bmi_init(struct ar6_softc *ar)
813{
814 int status;
815
816 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Creating sysfs entry\n"));
817 A_MEMZERO(&ar->osDevInfo, sizeof(struct hif_device_os_device_info));
818
819 /* Get the underlying OS device */
820 status = HIFConfigureDevice(ar->arHifDevice,
821 HIF_DEVICE_GET_OS_DEVICE,
822 &ar->osDevInfo,
823 sizeof(struct hif_device_os_device_info));
824
825 if (status) {
826 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failed to get OS device info from HIF\n"));
827 return A_ERROR;
828 }
829
830 /* Create a bmi entry in the sysfs filesystem */
831 if ((sysfs_create_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), &bmi_attr)) < 0)
832 {
833 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to create entry for bmi in sysfs filesystem\n"));
834 return A_ERROR;
835 }
836
837 return 0;
838}
839
840static void
841ar6000_sysfs_bmi_deinit(struct ar6_softc *ar)
842{
843 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Deleting sysfs entry\n"));
844
845 sysfs_remove_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), &bmi_attr);
846}
847
848#define bmifn(fn) do { \
849 if ((fn) < 0) { \
850 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); \
851 return A_ERROR; \
852 } \
853} while(0)
854
855#ifdef SOFTMAC_FILE_USED
856#define AR6002_MAC_ADDRESS_OFFSET 0x0A
857#define AR6003_MAC_ADDRESS_OFFSET 0x16
858static
859void calculate_crc(u32 TargetType, u8 *eeprom_data)
860{
861 u16 *ptr_crc;
862 u16 *ptr16_eeprom;
863 u16 checksum;
864 u32 i;
865 u32 eeprom_size;
866
867 if (TargetType == TARGET_TYPE_AR6001)
868 {
869 eeprom_size = 512;
870 ptr_crc = (u16 *)eeprom_data;
871 }
872 else if (TargetType == TARGET_TYPE_AR6003)
873 {
874 eeprom_size = 1024;
875 ptr_crc = (u16 *)((u8 *)eeprom_data + 0x04);
876 }
877 else
878 {
879 eeprom_size = 768;
880 ptr_crc = (u16 *)((u8 *)eeprom_data + 0x04);
881 }
882
883
884 // Clear the crc
885 *ptr_crc = 0;
886
887 // Recalculate new CRC
888 checksum = 0;
889 ptr16_eeprom = (u16 *)eeprom_data;
890 for (i = 0;i < eeprom_size; i += 2)
891 {
892 checksum = checksum ^ (*ptr16_eeprom);
893 ptr16_eeprom++;
894 }
895 checksum = 0xFFFF ^ checksum;
896 *ptr_crc = checksum;
897}
898
899static void
900ar6000_softmac_update(struct ar6_softc *ar, u8 *eeprom_data, size_t size)
901{
902 const char *source = "random generated";
903 const struct firmware *softmac_entry;
904 u8 *ptr_mac;
905 switch (ar->arTargetType) {
906 case TARGET_TYPE_AR6002:
907 ptr_mac = (u8 *)((u8 *)eeprom_data + AR6002_MAC_ADDRESS_OFFSET);
908 break;
909 case TARGET_TYPE_AR6003:
910 ptr_mac = (u8 *)((u8 *)eeprom_data + AR6003_MAC_ADDRESS_OFFSET);
911 break;
912 default:
913 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Target Type\n"));
914 return;
915 }
916 printk(KERN_DEBUG "MAC from EEPROM %pM\n", ptr_mac);
917
918 /* create a random MAC in case we cannot read file from system */
919 ptr_mac[0] = 0;
920 ptr_mac[1] = 0x03;
921 ptr_mac[2] = 0x7F;
922 ptr_mac[3] = random32() & 0xff;
923 ptr_mac[4] = random32() & 0xff;
924 ptr_mac[5] = random32() & 0xff;
925 if ((A_REQUEST_FIRMWARE(&softmac_entry, "softmac", ((struct device *)ar->osDevInfo.pOSDevice))) == 0)
926 {
927 char *macbuf = A_MALLOC_NOWAIT(softmac_entry->size+1);
928 if (macbuf) {
929 unsigned int softmac[6];
930 memcpy(macbuf, softmac_entry->data, softmac_entry->size);
931 macbuf[softmac_entry->size] = '\0';
932 if (sscanf(macbuf, "%02x:%02x:%02x:%02x:%02x:%02x",
933 &softmac[0], &softmac[1], &softmac[2],
934 &softmac[3], &softmac[4], &softmac[5])==6) {
935 int i;
936 for (i=0; i<6; ++i) {
937 ptr_mac[i] = softmac[i] & 0xff;
938 }
939 source = "softmac file";
940 }
941 kfree(macbuf);
942 }
943 A_RELEASE_FIRMWARE(softmac_entry);
944 }
945 printk(KERN_DEBUG "MAC from %s %pM\n", source, ptr_mac);
946 calculate_crc(ar->arTargetType, eeprom_data);
947}
948#endif /* SOFTMAC_FILE_USED */
949
950static int
951ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, bool compressed)
952{
953 int status;
954 const char *filename;
955 const struct firmware *fw_entry;
956 u32 fw_entry_size;
957 u8 **buf;
958 size_t *buf_len;
959
960 switch (file) {
961 case AR6K_OTP_FILE:
962 buf = &ar->fw_otp;
963 buf_len = &ar->fw_otp_len;
964 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
965 filename = AR6003_REV1_OTP_FILE;
966 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
967 filename = AR6003_REV2_OTP_FILE;
968 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
969 filename = AR6003_REV3_OTP_FILE;
970 } else {
971 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
972 return A_ERROR;
973 }
974 break;
975
976 case AR6K_FIRMWARE_FILE:
977 buf = &ar->fw;
978 buf_len = &ar->fw_len;
979 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
980 filename = AR6003_REV1_FIRMWARE_FILE;
981 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
982 filename = AR6003_REV2_FIRMWARE_FILE;
983 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
984 filename = AR6003_REV3_FIRMWARE_FILE;
985 } else {
986 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
987 return A_ERROR;
988 }
989
990 if (eppingtest) {
991 bypasswmi = true;
992 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
993 filename = AR6003_REV1_EPPING_FIRMWARE_FILE;
994 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
995 filename = AR6003_REV2_EPPING_FIRMWARE_FILE;
996 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
997 filename = AR6003_REV3_EPPING_FIRMWARE_FILE;
998 } else {
999 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("eppingtest : unsupported firmware revision: %d\n",
1000 ar->arVersion.target_ver));
1001 return A_ERROR;
1002 }
1003 compressed = false;
1004 }
1005
1006#ifdef CONFIG_HOST_TCMD_SUPPORT
1007 if(testmode) {
1008 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1009 filename = AR6003_REV1_TCMD_FIRMWARE_FILE;
1010 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1011 filename = AR6003_REV2_TCMD_FIRMWARE_FILE;
1012 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
1013 filename = AR6003_REV3_TCMD_FIRMWARE_FILE;
1014 } else {
1015 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1016 return A_ERROR;
1017 }
1018 compressed = false;
1019 }
1020#endif
1021#ifdef HTC_RAW_INTERFACE
1022 if (!eppingtest && bypasswmi) {
1023 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1024 filename = AR6003_REV1_ART_FIRMWARE_FILE;
1025 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1026 filename = AR6003_REV2_ART_FIRMWARE_FILE;
1027 } else {
1028 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1029 return A_ERROR;
1030 }
1031 compressed = false;
1032 }
1033#endif
1034 break;
1035
1036 case AR6K_PATCH_FILE:
1037 buf = &ar->fw_patch;
1038 buf_len = &ar->fw_patch_len;
1039 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1040 filename = AR6003_REV1_PATCH_FILE;
1041 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1042 filename = AR6003_REV2_PATCH_FILE;
1043 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
1044 filename = AR6003_REV3_PATCH_FILE;
1045 } else {
1046 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1047 return A_ERROR;
1048 }
1049 break;
1050
1051 case AR6K_BOARD_DATA_FILE:
1052 buf = &ar->fw_data;
1053 buf_len = &ar->fw_data_len;
1054 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1055 filename = AR6003_REV1_BOARD_DATA_FILE;
1056 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1057 filename = AR6003_REV2_BOARD_DATA_FILE;
1058 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
1059 filename = AR6003_REV3_BOARD_DATA_FILE;
1060 } else {
1061 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1062 return A_ERROR;
1063 }
1064 break;
1065
1066 default:
1067 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown file type: %d\n", file));
1068 return A_ERROR;
1069 }
1070
1071 if (*buf == NULL) {
1072 if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0) {
1073 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename));
1074 return A_ENOENT;
1075 }
1076
1077 *buf = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
1078 *buf_len = fw_entry->size;
1079 A_RELEASE_FIRMWARE(fw_entry);
1080 }
1081
1082#ifdef SOFTMAC_FILE_USED
1083 if (file==AR6K_BOARD_DATA_FILE && *buf_len) {
1084 ar6000_softmac_update(ar, *buf, *buf_len);
1085 }
1086#endif
1087
1088
1089 fw_entry_size = *buf_len;
1090
1091 /* Load extended board data for AR6003 */
1092 if ((file==AR6K_BOARD_DATA_FILE) && *buf) {
1093 u32 board_ext_address;
1094 u32 board_ext_data_size;
1095 u32 board_data_size;
1096
1097 board_ext_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_EXT_DATA_SZ : \
1098 (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_EXT_DATA_SZ : 0));
1099
1100 board_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_DATA_SZ : \
1101 (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_DATA_SZ : 0));
1102
1103 /* Determine where in Target RAM to write Board Data */
1104 bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data), (u8 *)&board_ext_address, 4));
1105 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board extended Data download address: 0x%x\n", board_ext_address));
1106
1107 /* check whether the target has allocated memory for extended board data and file contains extended board data */
1108 if ((board_ext_address) && (*buf_len == (board_data_size + board_ext_data_size))) {
1109 u32 param;
1110
1111 status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(*buf + board_data_size), board_ext_data_size);
1112
1113 if (status) {
1114 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
1115 return A_ERROR;
1116 }
1117
1118 /* Record the fact that extended board Data IS initialized */
1119 param = (board_ext_data_size << 16) | 1;
1120 bmifn(BMIWriteMemory(ar->arHifDevice,
1121 HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data_config),
1122 (unsigned char *)&param, 4));
1123 }
1124 fw_entry_size = board_data_size;
1125 }
1126
1127 if (compressed) {
1128 status = BMIFastDownload(ar->arHifDevice, address, *buf, fw_entry_size);
1129 } else {
1130 status = BMIWriteMemory(ar->arHifDevice, address, *buf, fw_entry_size);
1131 }
1132
1133 if (status) {
1134 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
1135 return A_ERROR;
1136 }
1137
1138 return 0;
1139}
1140
1141int
1142ar6000_update_bdaddr(struct ar6_softc *ar)
1143{
1144
1145 if (setupbtdev != 0) {
1146 u32 address;
1147
1148 if (BMIReadMemory(ar->arHifDevice,
1149 HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (u8 *)&address, 4) != 0)
1150 {
1151 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for hi_board_data failed\n"));
1152 return A_ERROR;
1153 }
1154
1155 if (BMIReadMemory(ar->arHifDevice, address + BDATA_BDADDR_OFFSET, (u8 *)ar->bdaddr, 6) != 0)
1156 {
1157 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for BD address failed\n"));
1158 return A_ERROR;
1159 }
1160 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BDADDR 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n", ar->bdaddr[0],
1161 ar->bdaddr[1], ar->bdaddr[2], ar->bdaddr[3],
1162 ar->bdaddr[4], ar->bdaddr[5]));
1163 }
1164
1165return 0;
1166}
1167
1168int
1169ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode)
1170{
1171 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Requesting device specific configuration\n"));
1172
1173 if (mode == WLAN_INIT_MODE_UDEV) {
1174 char version[16];
1175 const struct firmware *fw_entry;
1176
1177 /* Get config using udev through a script in user space */
1178 sprintf(version, "%2.2x", ar->arVersion.target_ver);
1179 if ((A_REQUEST_FIRMWARE(&fw_entry, version, ((struct device *)ar->osDevInfo.pOSDevice))) != 0)
1180 {
1181 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failure to get configuration for target version: %s\n", version));
1182 return A_ERROR;
1183 }
1184
1185 A_RELEASE_FIRMWARE(fw_entry);
1186 } else {
1187 /* The config is contained within the driver itself */
1188 int status;
1189 u32 param, options, sleep, address;
1190
1191 /* Temporarily disable system sleep */
1192 address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1193 bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1194 options = param;
1195 param |= AR6K_OPTION_SLEEP_DISABLE;
1196 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1197
1198 address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1199 bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1200 sleep = param;
1201 param |= WLAN_SYSTEM_SLEEP_DISABLE_SET(1);
1202 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1203 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("old options: %d, old sleep: %d\n", options, sleep));
1204
1205 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1206 /* Program analog PLL register */
1207 bmifn(BMIWriteSOCRegister(ar->arHifDevice, ANALOG_INTF_BASE_ADDRESS + 0x284, 0xF9104001));
1208 /* Run at 80/88MHz by default */
1209 param = CPU_CLOCK_STANDARD_SET(1);
1210 } else {
1211 /* Run at 40/44MHz by default */
1212 param = CPU_CLOCK_STANDARD_SET(0);
1213 }
1214 address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
1215 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1216
1217 param = 0;
1218 if (ar->arTargetType == TARGET_TYPE_AR6002) {
1219 bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (u8 *)&param, 4));
1220 }
1221
1222 /* LPO_CAL.ENABLE = 1 if no external clk is detected */
1223 if (param != 1) {
1224 address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
1225 param = LPO_CAL_ENABLE_SET(1);
1226 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1227 }
1228
1229 /* Venus2.0: Lower SDIO pad drive strength,
1230 * temporary WAR to avoid SDIO CRC error */
1231 if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1232 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6K: Temporary WAR to avoid SDIO CRC error\n"));
1233 param = 0x20;
1234 address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
1235 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1236
1237 address = GPIO_BASE_ADDRESS + GPIO_PIN11_ADDRESS;
1238 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1239
1240 address = GPIO_BASE_ADDRESS + GPIO_PIN12_ADDRESS;
1241 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1242
1243 address = GPIO_BASE_ADDRESS + GPIO_PIN13_ADDRESS;
1244 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1245 }
1246
1247#ifdef FORCE_INTERNAL_CLOCK
1248 /* Ignore external clock, if any, and force use of internal clock */
1249 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1250 /* hi_ext_clk_detected = 0 */
1251 param = 0;
1252 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (u8 *)&param, 4));
1253
1254 /* CLOCK_CONTROL &= ~LF_CLK32 */
1255 address = RTC_BASE_ADDRESS + CLOCK_CONTROL_ADDRESS;
1256 bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1257 param &= (~CLOCK_CONTROL_LF_CLK32_SET(1));
1258 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1259 }
1260#endif /* FORCE_INTERNAL_CLOCK */
1261
1262 /* Transfer Board Data from Target EEPROM to Target RAM */
1263 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1264 /* Determine where in Target RAM to write Board Data */
1265 bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (u8 *)&address, 4));
1266 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board Data download address: 0x%x\n", address));
1267
1268 /* Write EEPROM data to Target RAM */
1269 if ((ar6000_transfer_bin_file(ar, AR6K_BOARD_DATA_FILE, address, false)) != 0) {
1270 return A_ERROR;
1271 }
1272
1273 /* Record the fact that Board Data IS initialized */
1274 param = 1;
1275 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data_initialized), (u8 *)&param, 4));
1276
1277 /* Transfer One time Programmable data */
1278 AR6K_APP_LOAD_ADDRESS(address, ar->arVersion.target_ver);
1279 if (ar->arVersion.target_ver == AR6003_REV3_VERSION)
1280 address = 0x1234;
1281 status = ar6000_transfer_bin_file(ar, AR6K_OTP_FILE, address, true);
1282 if (status == 0) {
1283 /* Execute the OTP code */
1284 param = 0;
1285 AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver);
1286 bmifn(BMIExecute(ar->arHifDevice, address, &param));
1287 } else if (status != A_ENOENT) {
1288 return A_ERROR;
1289 }
1290 } else {
1291 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Programming of board data for chip %d not supported\n", ar->arTargetType));
1292 return A_ERROR;
1293 }
1294
1295 /* Download Target firmware */
1296 AR6K_APP_LOAD_ADDRESS(address, ar->arVersion.target_ver);
1297 if (ar->arVersion.target_ver == AR6003_REV3_VERSION)
1298 address = 0x1234;
1299 if ((ar6000_transfer_bin_file(ar, AR6K_FIRMWARE_FILE, address, true)) != 0) {
1300 return A_ERROR;
1301 }
1302
1303 /* Set starting address for firmware */
1304 AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver);
1305 bmifn(BMISetAppStart(ar->arHifDevice, address));
1306
1307 if(ar->arTargetType == TARGET_TYPE_AR6003) {
1308 AR6K_DATASET_PATCH_ADDRESS(address, ar->arVersion.target_ver);
1309 if ((ar6000_transfer_bin_file(ar, AR6K_PATCH_FILE,
1310 address, false)) != 0)
1311 return A_ERROR;
1312 param = address;
1313 bmifn(BMIWriteMemory(ar->arHifDevice,
1314 HOST_INTEREST_ITEM_ADDRESS(ar, hi_dset_list_head),
1315 (unsigned char *)&param, 4));
1316 }
1317
1318 /* Restore system sleep */
1319 address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1320 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, sleep));
1321
1322 address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1323 param = options | 0x20;
1324 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1325
1326 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1327 /* Configure GPIO AR6003 UART */
1328#ifndef CONFIG_AR600x_DEBUG_UART_TX_PIN
1329#define CONFIG_AR600x_DEBUG_UART_TX_PIN 8
1330#endif
1331 param = CONFIG_AR600x_DEBUG_UART_TX_PIN;
1332 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbg_uart_txpin), (u8 *)&param, 4));
1333
1334#if (CONFIG_AR600x_DEBUG_UART_TX_PIN == 23)
1335 {
1336 address = GPIO_BASE_ADDRESS + CLOCK_GPIO_ADDRESS;
1337 bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1338 param |= CLOCK_GPIO_BT_CLK_OUT_EN_SET(1);
1339 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1340 }
1341#endif
1342
1343 /* Configure GPIO for BT Reset */
1344#ifdef ATH6KL_CONFIG_GPIO_BT_RESET
1345#define CONFIG_AR600x_BT_RESET_PIN 0x16
1346 param = CONFIG_AR600x_BT_RESET_PIN;
1347 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_support_pins), (u8 *)&param, 4));
1348#endif /* ATH6KL_CONFIG_GPIO_BT_RESET */
1349
1350 /* Configure UART flow control polarity */
1351#ifndef CONFIG_ATH6KL_BT_UART_FC_POLARITY
1352#define CONFIG_ATH6KL_BT_UART_FC_POLARITY 0
1353#endif
1354
1355#if (CONFIG_ATH6KL_BT_UART_FC_POLARITY == 1)
1356 if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1357 param = ((CONFIG_ATH6KL_BT_UART_FC_POLARITY << 1) & 0x2);
1358 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_pwr_mgmt_params), (u8 *)&param, 4));
1359 }
1360#endif /* CONFIG_ATH6KL_BT_UART_FC_POLARITY */
1361 }
1362
1363#ifdef HTC_RAW_INTERFACE
1364 if (!eppingtest && bypasswmi) {
1365 /* Don't run BMIDone for ART mode and force resetok=0 */
1366 resetok = 0;
1367 msleep(1000);
1368 }
1369#endif /* HTC_RAW_INTERFACE */
1370 }
1371
1372 return 0;
1373}
1374
1375int
1376ar6000_configure_target(struct ar6_softc *ar)
1377{
1378 u32 param;
1379 if (enableuartprint) {
1380 param = 1;
1381 if (BMIWriteMemory(ar->arHifDevice,
1382 HOST_INTEREST_ITEM_ADDRESS(ar, hi_serial_enable),
1383 (u8 *)&param,
1384 4)!= 0)
1385 {
1386 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enableuartprint failed \n"));
1387 return A_ERROR;
1388 }
1389 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Serial console prints enabled\n"));
1390 }
1391
1392 /* Tell target which HTC version it is used*/
1393 param = HTC_PROTOCOL_VERSION;
1394 if (BMIWriteMemory(ar->arHifDevice,
1395 HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest),
1396 (u8 *)&param,
1397 4)!= 0)
1398 {
1399 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for htc version failed \n"));
1400 return A_ERROR;
1401 }
1402
1403#ifdef CONFIG_HOST_TCMD_SUPPORT
1404 if(testmode) {
1405 ar->arTargetMode = AR6000_TCMD_MODE;
1406 }else {
1407 ar->arTargetMode = AR6000_WLAN_MODE;
1408 }
1409#endif
1410 if (enabletimerwar) {
1411 u32 param;
1412
1413 if (BMIReadMemory(ar->arHifDevice,
1414 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1415 (u8 *)&param,
1416 4)!= 0)
1417 {
1418 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for enabletimerwar failed \n"));
1419 return A_ERROR;
1420 }
1421
1422 param |= HI_OPTION_TIMER_WAR;
1423
1424 if (BMIWriteMemory(ar->arHifDevice,
1425 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1426 (u8 *)&param,
1427 4) != 0)
1428 {
1429 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enabletimerwar failed \n"));
1430 return A_ERROR;
1431 }
1432 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Timer WAR enabled\n"));
1433 }
1434
1435 /* set the firmware mode to STA/IBSS/AP */
1436 {
1437 u32 param;
1438
1439 if (BMIReadMemory(ar->arHifDevice,
1440 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1441 (u8 *)&param,
1442 4)!= 0)
1443 {
1444 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for setting fwmode failed \n"));
1445 return A_ERROR;
1446 }
1447
1448 param |= (num_device << HI_OPTION_NUM_DEV_SHIFT);
1449 param |= (fwmode << HI_OPTION_FW_MODE_SHIFT);
1450 param |= (mac_addr_method << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
1451 param |= (firmware_bridge << HI_OPTION_FW_BRIDGE_SHIFT);
1452
1453
1454 if (BMIWriteMemory(ar->arHifDevice,
1455 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1456 (u8 *)&param,
1457 4) != 0)
1458 {
1459 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for setting fwmode failed \n"));
1460 return A_ERROR;
1461 }
1462 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n"));
1463 }
1464
1465#ifdef ATH6KL_DISABLE_TARGET_DBGLOGS
1466 {
1467 u32 param;
1468
1469 if (BMIReadMemory(ar->arHifDevice,
1470 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1471 (u8 *)&param,
1472 4)!= 0)
1473 {
1474 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for disabling debug logs failed\n"));
1475 return A_ERROR;
1476 }
1477
1478 param |= HI_OPTION_DISABLE_DBGLOG;
1479
1480 if (BMIWriteMemory(ar->arHifDevice,
1481 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1482 (u8 *)&param,
1483 4) != 0)
1484 {
1485 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for HI_OPTION_DISABLE_DBGLOG\n"));
1486 return A_ERROR;
1487 }
1488 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n"));
1489 }
1490#endif /* ATH6KL_DISABLE_TARGET_DBGLOGS */
1491
1492 /*
1493 * Hardcode the address use for the extended board data
1494 * Ideally this should be pre-allocate by the OS at boot time
1495 * But since it is a new feature and board data is loaded
1496 * at init time, we have to workaround this from host.
1497 * It is difficult to patch the firmware boot code,
1498 * but possible in theory.
1499 */
1500
1501 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1502 u32 ramReservedSz;
1503 if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1504 param = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
1505 ramReservedSz = AR6003_REV2_RAM_RESERVE_SIZE;
1506 } else {
1507 param = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
1508 ramReservedSz = AR6003_REV3_RAM_RESERVE_SIZE;
1509 }
1510 if (BMIWriteMemory(ar->arHifDevice,
1511 HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data),
1512 (u8 *)&param, 4) != 0) {
1513 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1514 ("BMIWriteMemory for "
1515 "hi_board_ext_data failed\n"));
1516 return A_ERROR;
1517 }
1518 if (BMIWriteMemory(ar->arHifDevice,
1519 HOST_INTEREST_ITEM_ADDRESS(ar,
1520 hi_end_RAM_reserve_sz),
1521 (u8 *)&ramReservedSz, 4) != 0) {
1522 AR_DEBUG_PRINTF(ATH_DEBUG_ERR ,
1523 ("BMIWriteMemory for "
1524 "hi_end_RAM_reserve_sz failed\n"));
1525 return A_ERROR;
1526 }
1527 }
1528
1529 /* since BMIInit is called in the driver layer, we have to set the block
1530 * size here for the target */
1531
1532 if (ar6000_set_htc_params(ar->arHifDevice, ar->arTargetType,
1533 mbox_yield_limit, 0)) {
1534 /* use default number of control buffers */
1535 return A_ERROR;
1536 }
1537
1538 if (setupbtdev != 0) {
1539 if (ar6000_set_hci_bridge_flags(ar->arHifDevice,
1540 ar->arTargetType,
1541 setupbtdev)) {
1542 return A_ERROR;
1543 }
1544 }
1545 return 0;
1546}
1547
1548static void
1549init_netdev(struct net_device *dev, char *name)
1550{
1551 dev->netdev_ops = &ar6000_netdev_ops;
1552 dev->watchdog_timeo = AR6000_TX_TIMEOUT;
1553
1554 /*
1555 * We need the OS to provide us with more headroom in order to
1556 * perform dix to 802.3, WMI header encap, and the HTC header
1557 */
1558 if (processDot11Hdr) {
1559 dev->hard_header_len = sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR;
1560 } else {
1561 dev->hard_header_len = ETH_HLEN + sizeof(ATH_LLC_SNAP_HDR) +
1562 sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR;
1563 }
1564
1565 if (name[0])
1566 {
1567 strcpy(dev->name, name);
1568 }
1569
1570#ifdef CONFIG_CHECKSUM_OFFLOAD
1571 if(csumOffload){
1572 dev->features |= NETIF_F_IP_CSUM; /*advertise kernel capability to do TCP/UDP CSUM offload for IPV4*/
1573 }
1574#endif
1575
1576 return;
1577}
1578
1579static int __ath6kl_init_netdev(struct net_device *dev)
1580{
1581 int r;
1582
1583 rtnl_lock();
1584 r = ar6000_init(dev);
1585 rtnl_unlock();
1586
1587 if (r) {
1588 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n"));
1589 return r;
1590 }
1591
1592 return 0;
1593}
1594
1595#ifdef HTC_RAW_INTERFACE
1596static int ath6kl_init_netdev_wmi(struct net_device *dev)
1597{
1598 if (!eppingtest && bypasswmi)
1599 return 0;
1600
1601 return __ath6kl_init_netdev(dev);
1602}
1603#else
1604static int ath6kl_init_netdev_wmi(struct net_device *dev)
1605{
1606 return __ath6kl_init_netdev(dev);
1607}
1608#endif
1609
1610static int ath6kl_init_netdev(struct ar6_softc *ar)
1611{
1612 int r;
1613
1614 r = ar6000_sysfs_bmi_get_config(ar, wlaninitmode);
1615 if (r) {
1616 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1617 ("ar6000_avail: "
1618 "ar6000_sysfs_bmi_get_config failed\n"));
1619 return r;
1620 }
1621
1622 return ath6kl_init_netdev_wmi(ar->arNetDev);
1623}
1624
1625/*
1626 * HTC Event handlers
1627 */
1628static int
1629ar6000_avail_ev(void *context, void *hif_handle)
1630{
1631 int i;
1632 struct net_device *dev;
1633 void *ar_netif;
1634 struct ar6_softc *ar;
1635 int device_index = 0;
1636 struct htc_init_info htcInfo;
1637 struct wireless_dev *wdev;
1638 int r = 0;
1639 struct hif_device_os_device_info osDevInfo;
1640
1641 memset(&osDevInfo, 0, sizeof(osDevInfo));
1642 if (HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_OS_DEVICE,
1643 &osDevInfo, sizeof(osDevInfo))) {
1644 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: Failed to get OS device instance\n", __func__));
1645 return A_ERROR;
1646 }
1647
1648 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_available\n"));
1649
1650 for (i=0; i < MAX_AR6000; i++) {
1651 if (ar6000_devices[i] == NULL) {
1652 break;
1653 }
1654 }
1655
1656 if (i == MAX_AR6000) {
1657 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_available: max devices reached\n"));
1658 return A_ERROR;
1659 }
1660
1661 /* Save this. It gives a bit better readability especially since */
1662 /* we use another local "i" variable below. */
1663 device_index = i;
1664
1665 wdev = ar6k_cfg80211_init(osDevInfo.pOSDevice);
1666 if (IS_ERR(wdev)) {
1667 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ar6k_cfg80211_init failed\n", __func__));
1668 return A_ERROR;
1669 }
1670 ar_netif = wdev_priv(wdev);
1671
1672 if (ar_netif == NULL) {
1673 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Can't allocate ar6k priv memory\n", __func__));
1674 return A_ERROR;
1675 }
1676
1677 A_MEMZERO(ar_netif, sizeof(struct ar6_softc));
1678 ar = (struct ar6_softc *)ar_netif;
1679
1680 ar->wdev = wdev;
1681 wdev->iftype = NL80211_IFTYPE_STATION;
1682
1683 dev = alloc_netdev_mq(0, "wlan%d", ether_setup, 1);
1684 if (!dev) {
1685 printk(KERN_CRIT "AR6K: no memory for network device instance\n");
1686 ar6k_cfg80211_deinit(ar);
1687 return A_ERROR;
1688 }
1689
1690 dev->ieee80211_ptr = wdev;
1691 SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
1692 wdev->netdev = dev;
1693 ar->arNetworkType = INFRA_NETWORK;
1694 ar->smeState = SME_DISCONNECTED;
1695 ar->arAutoAuthStage = AUTH_IDLE;
1696
1697 init_netdev(dev, ifname);
1698
1699
1700 ar->arNetDev = dev;
1701 ar->arHifDevice = hif_handle;
1702 ar->arWlanState = WLAN_ENABLED;
1703 ar->arDeviceIndex = device_index;
1704
1705 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
1706 ar->arWlanOff = false; /* We are in ON state */
1707#ifdef CONFIG_PM
1708 ar->arWowState = WLAN_WOW_STATE_NONE;
1709 ar->arBTOff = true; /* BT chip assumed to be OFF */
1710 ar->arBTSharing = WLAN_CONFIG_BT_SHARING;
1711 ar->arWlanOffConfig = WLAN_CONFIG_WLAN_OFF;
1712 ar->arSuspendConfig = WLAN_CONFIG_PM_SUSPEND;
1713 ar->arWow2Config = WLAN_CONFIG_PM_WOW2;
1714#endif /* CONFIG_PM */
1715
1716 A_INIT_TIMER(&ar->arHBChallengeResp.timer, ar6000_detect_error, dev);
1717 ar->arHBChallengeResp.seqNum = 0;
1718 ar->arHBChallengeResp.outstanding = false;
1719 ar->arHBChallengeResp.missCnt = 0;
1720 ar->arHBChallengeResp.frequency = AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT;
1721 ar->arHBChallengeResp.missThres = AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT;
1722
1723 ar6000_init_control_info(ar);
1724 init_waitqueue_head(&arEvent);
1725 sema_init(&ar->arSem, 1);
1726 ar->bIsDestroyProgress = false;
1727
1728 INIT_HTC_PACKET_QUEUE(&ar->amsdu_rx_buffer_queue);
1729
1730#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1731 A_INIT_TIMER(&aptcTimer, aptcTimerHandler, ar);
1732#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1733
1734 A_INIT_TIMER(&ar->disconnect_timer, disconnect_timer_handler, dev);
1735
1736 BMIInit();
1737
1738 ar6000_sysfs_bmi_init(ar);
1739
1740 {
1741 struct bmi_target_info targ_info;
1742
1743 r = BMIGetTargetInfo(ar->arHifDevice, &targ_info);
1744 if (r)
1745 goto avail_ev_failed;
1746
1747 ar->arVersion.target_ver = targ_info.target_ver;
1748 ar->arTargetType = targ_info.target_type;
1749 wdev->wiphy->hw_version = targ_info.target_ver;
1750 }
1751
1752 r = ar6000_configure_target(ar);
1753 if (r)
1754 goto avail_ev_failed;
1755
1756 A_MEMZERO(&htcInfo,sizeof(htcInfo));
1757 htcInfo.pContext = ar;
1758 htcInfo.TargetFailure = ar6000_target_failure;
1759
1760 ar->arHtcTarget = HTCCreate(ar->arHifDevice,&htcInfo);
1761
1762 if (!ar->arHtcTarget) {
1763 r = -ENOMEM;
1764 goto avail_ev_failed;
1765 }
1766
1767 spin_lock_init(&ar->arLock);
1768
1769#ifdef WAPI_ENABLE
1770 ar->arWapiEnable = 0;
1771#endif
1772
1773
1774 if(csumOffload){
1775 /*if external frame work is also needed, change and use an extended rxMetaVerion*/
1776 ar->rxMetaVersion=WMI_META_VERSION_2;
1777 }
1778
1779 ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs);
1780 if (!ar->aggr_cntxt) {
1781 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize aggr.\n", __func__));
1782 r = -ENOMEM;
1783 goto avail_ev_failed;
1784 }
1785
1786 aggr_register_rx_dispatcher(ar->aggr_cntxt, (void *)dev, ar6000_deliver_frames_to_nw_stack);
1787
1788 HIFClaimDevice(ar->arHifDevice, ar);
1789
1790 /* We only register the device in the global list if we succeed. */
1791 /* If the device is in the global list, it will be destroyed */
1792 /* when the module is unloaded. */
1793 ar6000_devices[device_index] = dev;
1794
1795 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode));
1796 if ((wlaninitmode == WLAN_INIT_MODE_UDEV) ||
1797 (wlaninitmode == WLAN_INIT_MODE_DRV)) {
1798 r = ath6kl_init_netdev(ar);
1799 if (r)
1800 goto avail_ev_failed;
1801 }
1802
1803 /* This runs the init function if registered */
1804 r = register_netdev(dev);
1805 if (r) {
1806 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: register_netdev failed\n"));
1807 ar6000_destroy(dev, 0);
1808 return r;
1809 }
1810
1811 is_netdev_registered = 1;
1812
1813#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
1814 arApNetDev = NULL;
1815#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
1816 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_avail: name=%s hifdevice=0x%lx, dev=0x%lx (%d), ar=0x%lx\n",
1817 dev->name, (unsigned long)ar->arHifDevice, (unsigned long)dev, device_index,
1818 (unsigned long)ar));
1819
1820avail_ev_failed :
1821 if (r)
1822 ar6000_sysfs_bmi_deinit(ar);
1823
1824 return r;
1825}
1826
1827static void ar6000_target_failure(void *Instance, int Status)
1828{
1829 struct ar6_softc *ar = (struct ar6_softc *)Instance;
1830 WMI_TARGET_ERROR_REPORT_EVENT errEvent;
1831 static bool sip = false;
1832
1833 if (Status != 0) {
1834
1835 printk(KERN_ERR "ar6000_target_failure: target asserted \n");
1836
1837 if (timer_pending(&ar->arHBChallengeResp.timer)) {
1838 A_UNTIMEOUT(&ar->arHBChallengeResp.timer);
1839 }
1840
1841 /* try dumping target assertion information (if any) */
1842 ar6000_dump_target_assert_info(ar->arHifDevice,ar->arTargetType);
1843
1844 /*
1845 * Fetch the logs from the target via the diagnostic
1846 * window.
1847 */
1848 ar6000_dbglog_get_debug_logs(ar);
1849
1850 /* Report the error only once */
1851 if (!sip) {
1852 sip = true;
1853 errEvent.errorVal = WMI_TARGET_COM_ERR |
1854 WMI_TARGET_FATAL_ERR;
1855 }
1856 }
1857}
1858
1859static int
1860ar6000_unavail_ev(void *context, void *hif_handle)
1861{
1862 struct ar6_softc *ar = (struct ar6_softc *)context;
1863 /* NULL out it's entry in the global list */
1864 ar6000_devices[ar->arDeviceIndex] = NULL;
1865 ar6000_destroy(ar->arNetDev, 1);
1866
1867 return 0;
1868}
1869
1870void
1871ar6000_restart_endpoint(struct net_device *dev)
1872{
1873 int status = 0;
1874 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
1875
1876 BMIInit();
1877 do {
1878 if ( (status=ar6000_configure_target(ar))!= 0)
1879 break;
1880 if ( (status=ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != 0)
1881 {
1882 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n"));
1883 break;
1884 }
1885 rtnl_lock();
1886 status = (ar6000_init(dev)==0) ? 0 : A_ERROR;
1887 rtnl_unlock();
1888
1889 if (status) {
1890 break;
1891 }
1892 if (ar->arSsidLen && ar->arWlanState == WLAN_ENABLED) {
1893 ar6000_connect_to_ap(ar);
1894 }
1895 } while (0);
1896
1897 if (status== 0) {
1898 return;
1899 }
1900
1901 ar6000_devices[ar->arDeviceIndex] = NULL;
1902 ar6000_destroy(ar->arNetDev, 1);
1903}
1904
1905void
1906ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs)
1907{
1908 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
1909
1910 /* Stop the transmit queues */
1911 netif_stop_queue(dev);
1912
1913 /* Disable the target and the interrupts associated with it */
1914 if (ar->arWmiReady == true)
1915 {
1916 if (!bypasswmi)
1917 {
1918 bool disconnectIssued;
1919
1920 disconnectIssued = (ar->arConnected) || (ar->arConnectPending);
1921 ar6000_disconnect(ar);
1922 if (!keepprofile) {
1923 ar6000_init_profile_info(ar);
1924 }
1925
1926 A_UNTIMEOUT(&ar->disconnect_timer);
1927
1928 if (getdbglogs) {
1929 ar6000_dbglog_get_debug_logs(ar);
1930 }
1931
1932 ar->arWmiReady = false;
1933 wmi_shutdown(ar->arWmi);
1934 ar->arWmiEnabled = false;
1935 ar->arWmi = NULL;
1936 /*
1937 * After wmi_shudown all WMI events will be dropped.
1938 * We need to cleanup the buffers allocated in AP mode
1939 * and give disconnect notification to stack, which usually
1940 * happens in the disconnect_event.
1941 * Simulate the disconnect_event by calling the function directly.
1942 * Sometimes disconnect_event will be received when the debug logs
1943 * are collected.
1944 */
1945 if (disconnectIssued) {
1946 if(ar->arNetworkType & AP_NETWORK) {
1947 ar6000_disconnect_event(ar, DISCONNECT_CMD, bcast_mac, 0, NULL, 0);
1948 } else {
1949 ar6000_disconnect_event(ar, DISCONNECT_CMD, ar->arBssid, 0, NULL, 0);
1950 }
1951 }
1952 ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
1953 ar->user_key_ctrl = 0;
1954 }
1955
1956 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI stopped\n", __func__));
1957 }
1958 else
1959 {
1960 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI not ready 0x%lx 0x%lx\n",
1961 __func__, (unsigned long) ar, (unsigned long) ar->arWmi));
1962
1963 /* Shut down WMI if we have started it */
1964 if(ar->arWmiEnabled == true)
1965 {
1966 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Shut down WMI\n", __func__));
1967 wmi_shutdown(ar->arWmi);
1968 ar->arWmiEnabled = false;
1969 ar->arWmi = NULL;
1970 }
1971 }
1972
1973 if (ar->arHtcTarget != NULL) {
1974#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1975 if (NULL != ar6kHciTransCallbacks.cleanupTransport) {
1976 ar6kHciTransCallbacks.cleanupTransport(NULL);
1977 }
1978#else
1979 // FIXME: workaround to reset BT's UART baud rate to default
1980 if (NULL != ar->exitCallback) {
1981 struct ar3k_config_info ar3kconfig;
1982 int status;
1983
1984 A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
1985 ar6000_set_default_ar3kconfig(ar, (void *)&ar3kconfig);
1986 status = ar->exitCallback(&ar3kconfig);
1987 if (0 != status) {
1988 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to reset AR3K baud rate! \n"));
1989 }
1990 }
1991 // END workaround
1992 if (setuphci)
1993 ar6000_cleanup_hci(ar);
1994#endif
1995 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Shutting down HTC .... \n"));
1996 /* stop HTC */
1997 HTCStop(ar->arHtcTarget);
1998 }
1999
2000 if (resetok) {
2001 /* try to reset the device if we can
2002 * The driver may have been configure NOT to reset the target during
2003 * a debug session */
2004 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Attempting to reset target on instance destroy.... \n"));
2005 if (ar->arHifDevice != NULL) {
2006 bool coldReset = (ar->arTargetType == TARGET_TYPE_AR6003) ? true: false;
2007 ar6000_reset_device(ar->arHifDevice, ar->arTargetType, true, coldReset);
2008 }
2009 } else {
2010 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Host does not want target reset. \n"));
2011 }
2012 /* Done with cookies */
2013 ar6000_cookie_cleanup(ar);
2014
2015 /* cleanup any allocated AMSDU buffers */
2016 ar6000_cleanup_amsdu_rxbufs(ar);
2017}
2018/*
2019 * We need to differentiate between the surprise and planned removal of the
2020 * device because of the following consideration:
2021 * - In case of surprise removal, the hcd already frees up the pending
2022 * for the device and hence there is no need to unregister the function
2023 * driver inorder to get these requests. For planned removal, the function
2024 * driver has to explicitly unregister itself to have the hcd return all the
2025 * pending requests before the data structures for the devices are freed up.
2026 * Note that as per the current implementation, the function driver will
2027 * end up releasing all the devices since there is no API to selectively
2028 * release a particular device.
2029 * - Certain commands issued to the target can be skipped for surprise
2030 * removal since they will anyway not go through.
2031 */
2032void
2033ar6000_destroy(struct net_device *dev, unsigned int unregister)
2034{
2035 struct ar6_softc *ar;
2036
2037 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("+ar6000_destroy \n"));
2038
2039 if((dev == NULL) || ((ar = ar6k_priv(dev)) == NULL))
2040 {
2041 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): Failed to get device structure.\n", __func__));
2042 return;
2043 }
2044
2045 ar->bIsDestroyProgress = true;
2046
2047 if (down_interruptible(&ar->arSem)) {
2048 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): down_interruptible failed \n", __func__));
2049 return;
2050 }
2051
2052 if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) {
2053 /* only stop endpoint if we are not stop it in suspend_ev */
2054 ar6000_stop_endpoint(dev, false, true);
2055 }
2056
2057 ar->arWlanState = WLAN_DISABLED;
2058 if (ar->arHtcTarget != NULL) {
2059 /* destroy HTC */
2060 HTCDestroy(ar->arHtcTarget);
2061 }
2062 if (ar->arHifDevice != NULL) {
2063 /*release the device so we do not get called back on remove incase we
2064 * we're explicity destroyed by module unload */
2065 HIFReleaseDevice(ar->arHifDevice);
2066 HIFShutDownDevice(ar->arHifDevice);
2067 }
2068 aggr_module_destroy(ar->aggr_cntxt);
2069
2070 /* Done with cookies */
2071 ar6000_cookie_cleanup(ar);
2072
2073 /* cleanup any allocated AMSDU buffers */
2074 ar6000_cleanup_amsdu_rxbufs(ar);
2075
2076 ar6000_sysfs_bmi_deinit(ar);
2077
2078 /* Cleanup BMI */
2079 BMICleanup();
2080
2081 /* Clear the tx counters */
2082 memset(tx_attempt, 0, sizeof(tx_attempt));
2083 memset(tx_post, 0, sizeof(tx_post));
2084 memset(tx_complete, 0, sizeof(tx_complete));
2085
2086#ifdef HTC_RAW_INTERFACE
2087 if (ar->arRawHtc) {
2088 kfree(ar->arRawHtc);
2089 ar->arRawHtc = NULL;
2090 }
2091#endif
2092 /* Free up the device data structure */
2093 if (unregister && is_netdev_registered) {
2094 unregister_netdev(dev);
2095 is_netdev_registered = 0;
2096 }
2097 free_netdev(dev);
2098
2099 ar6k_cfg80211_deinit(ar);
2100
2101#ifdef CONFIG_AP_VIRTUL_ADAPTER_SUPPORT
2102 ar6000_remove_ap_interface();
2103#endif /*CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
2104
2105 kfree(ar->fw_otp);
2106 kfree(ar->fw);
2107 kfree(ar->fw_patch);
2108 kfree(ar->fw_data);
2109
2110 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("-ar6000_destroy \n"));
2111}
2112
2113static void disconnect_timer_handler(unsigned long ptr)
2114{
2115 struct net_device *dev = (struct net_device *)ptr;
2116 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2117
2118 A_UNTIMEOUT(&ar->disconnect_timer);
2119
2120 ar6000_init_profile_info(ar);
2121 ar6000_disconnect(ar);
2122}
2123
2124static void ar6000_detect_error(unsigned long ptr)
2125{
2126 struct net_device *dev = (struct net_device *)ptr;
2127 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2128 WMI_TARGET_ERROR_REPORT_EVENT errEvent;
2129
2130 AR6000_SPIN_LOCK(&ar->arLock, 0);
2131
2132 if (ar->arHBChallengeResp.outstanding) {
2133 ar->arHBChallengeResp.missCnt++;
2134 } else {
2135 ar->arHBChallengeResp.missCnt = 0;
2136 }
2137
2138 if (ar->arHBChallengeResp.missCnt > ar->arHBChallengeResp.missThres) {
2139 /* Send Error Detect event to the application layer and do not reschedule the error detection module timer */
2140 ar->arHBChallengeResp.missCnt = 0;
2141 ar->arHBChallengeResp.seqNum = 0;
2142 errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR;
2143 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2144 return;
2145 }
2146
2147 /* Generate the sequence number for the next challenge */
2148 ar->arHBChallengeResp.seqNum++;
2149 ar->arHBChallengeResp.outstanding = true;
2150
2151 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2152
2153 /* Send the challenge on the control channel */
2154 if (wmi_get_challenge_resp_cmd(ar->arWmi, ar->arHBChallengeResp.seqNum, DRV_HB_CHALLENGE) != 0) {
2155 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to send heart beat challenge\n"));
2156 }
2157
2158
2159 /* Reschedule the timer for the next challenge */
2160 A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0);
2161}
2162
2163void ar6000_init_profile_info(struct ar6_softc *ar)
2164{
2165 ar->arSsidLen = 0;
2166 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
2167
2168 switch(fwmode) {
2169 case HI_OPTION_FW_MODE_IBSS:
2170 ar->arNetworkType = ar->arNextMode = ADHOC_NETWORK;
2171 break;
2172 case HI_OPTION_FW_MODE_BSS_STA:
2173 ar->arNetworkType = ar->arNextMode = INFRA_NETWORK;
2174 break;
2175 case HI_OPTION_FW_MODE_AP:
2176 ar->arNetworkType = ar->arNextMode = AP_NETWORK;
2177 break;
2178 }
2179
2180 ar->arDot11AuthMode = OPEN_AUTH;
2181 ar->arAuthMode = NONE_AUTH;
2182 ar->arPairwiseCrypto = NONE_CRYPT;
2183 ar->arPairwiseCryptoLen = 0;
2184 ar->arGroupCrypto = NONE_CRYPT;
2185 ar->arGroupCryptoLen = 0;
2186 A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
2187 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
2188 A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
2189 ar->arBssChannel = 0;
2190}
2191
2192static void
2193ar6000_init_control_info(struct ar6_softc *ar)
2194{
2195 ar->arWmiEnabled = false;
2196 ar6000_init_profile_info(ar);
2197 ar->arDefTxKeyIndex = 0;
2198 A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
2199 ar->arChannelHint = 0;
2200 ar->arListenIntervalT = A_DEFAULT_LISTEN_INTERVAL;
2201 ar->arListenIntervalB = 0;
2202 ar->arVersion.host_ver = AR6K_SW_VERSION;
2203 ar->arRssi = 0;
2204 ar->arTxPwr = 0;
2205 ar->arTxPwrSet = false;
2206 ar->arSkipScan = 0;
2207 ar->arBeaconInterval = 0;
2208 ar->arBitRate = 0;
2209 ar->arMaxRetries = 0;
2210 ar->arWmmEnabled = true;
2211 ar->intra_bss = 1;
2212 ar->scan_triggered = 0;
2213 A_MEMZERO(&ar->scParams, sizeof(ar->scParams));
2214 ar->scParams.shortScanRatio = WMI_SHORTSCANRATIO_DEFAULT;
2215 ar->scParams.scanCtrlFlags = DEFAULT_SCAN_CTRL_FLAGS;
2216
2217 /* Initialize the AP mode state info */
2218 {
2219 u8 ctr;
2220 A_MEMZERO((u8 *)ar->sta_list, AP_MAX_NUM_STA * sizeof(sta_t));
2221
2222 /* init the Mutexes */
2223 A_MUTEX_INIT(&ar->mcastpsqLock);
2224
2225 /* Init the PS queues */
2226 for (ctr=0; ctr < AP_MAX_NUM_STA ; ctr++) {
2227 A_MUTEX_INIT(&ar->sta_list[ctr].psqLock);
2228 A_NETBUF_QUEUE_INIT(&ar->sta_list[ctr].psq);
2229 }
2230
2231 ar->ap_profile_flag = 0;
2232 A_NETBUF_QUEUE_INIT(&ar->mcastpsq);
2233
2234 memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
2235 ar->ap_wmode = DEF_AP_WMODE_G;
2236 ar->ap_dtim_period = DEF_AP_DTIM;
2237 ar->ap_beacon_interval = DEF_BEACON_INTERVAL;
2238 }
2239}
2240
2241static int
2242ar6000_open(struct net_device *dev)
2243{
2244 unsigned long flags;
2245 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2246
2247 spin_lock_irqsave(&ar->arLock, flags);
2248
2249 if(ar->arWlanState == WLAN_DISABLED) {
2250 ar->arWlanState = WLAN_ENABLED;
2251 }
2252
2253 if( ar->arConnected || bypasswmi) {
2254 netif_carrier_on(dev);
2255 /* Wake up the queues */
2256 netif_wake_queue(dev);
2257 }
2258 else
2259 netif_carrier_off(dev);
2260
2261 spin_unlock_irqrestore(&ar->arLock, flags);
2262 return 0;
2263}
2264
2265static int
2266ar6000_close(struct net_device *dev)
2267{
2268 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2269 netif_stop_queue(dev);
2270
2271 ar6000_disconnect(ar);
2272
2273 if(ar->arWmiReady == true) {
2274 if (wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0,
2275 0, 0, 0, 0, 0, 0, 0, 0) != 0) {
2276 return -EIO;
2277 }
2278 ar->arWlanState = WLAN_DISABLED;
2279 }
2280 ar6k_cfg80211_scanComplete_event(ar, A_ECANCELED);
2281
2282 return 0;
2283}
2284
2285/* connect to a service */
2286static int ar6000_connectservice(struct ar6_softc *ar,
2287 struct htc_service_connect_req *pConnect,
2288 char *pDesc)
2289{
2290 int status;
2291 struct htc_service_connect_resp response;
2292
2293 do {
2294
2295 A_MEMZERO(&response,sizeof(response));
2296
2297 status = HTCConnectService(ar->arHtcTarget,
2298 pConnect,
2299 &response);
2300
2301 if (status) {
2302 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Failed to connect to %s service status:%d \n",
2303 pDesc, status));
2304 break;
2305 }
2306 switch (pConnect->ServiceID) {
2307 case WMI_CONTROL_SVC :
2308 if (ar->arWmiEnabled) {
2309 /* set control endpoint for WMI use */
2310 wmi_set_control_ep(ar->arWmi, response.Endpoint);
2311 }
2312 /* save EP for fast lookup */
2313 ar->arControlEp = response.Endpoint;
2314 break;
2315 case WMI_DATA_BE_SVC :
2316 arSetAc2EndpointIDMap(ar, WMM_AC_BE, response.Endpoint);
2317 break;
2318 case WMI_DATA_BK_SVC :
2319 arSetAc2EndpointIDMap(ar, WMM_AC_BK, response.Endpoint);
2320 break;
2321 case WMI_DATA_VI_SVC :
2322 arSetAc2EndpointIDMap(ar, WMM_AC_VI, response.Endpoint);
2323 break;
2324 case WMI_DATA_VO_SVC :
2325 arSetAc2EndpointIDMap(ar, WMM_AC_VO, response.Endpoint);
2326 break;
2327 default:
2328 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ServiceID not mapped %d\n", pConnect->ServiceID));
2329 status = A_EINVAL;
2330 break;
2331 }
2332
2333 } while (false);
2334
2335 return status;
2336}
2337
2338void ar6000_TxDataCleanup(struct ar6_softc *ar)
2339{
2340 /* flush all the data (non-control) streams
2341 * we only flush packets that are tagged as data, we leave any control packets that
2342 * were in the TX queues alone */
2343 HTCFlushEndpoint(ar->arHtcTarget,
2344 arAc2EndpointID(ar, WMM_AC_BE),
2345 AR6K_DATA_PKT_TAG);
2346 HTCFlushEndpoint(ar->arHtcTarget,
2347 arAc2EndpointID(ar, WMM_AC_BK),
2348 AR6K_DATA_PKT_TAG);
2349 HTCFlushEndpoint(ar->arHtcTarget,
2350 arAc2EndpointID(ar, WMM_AC_VI),
2351 AR6K_DATA_PKT_TAG);
2352 HTCFlushEndpoint(ar->arHtcTarget,
2353 arAc2EndpointID(ar, WMM_AC_VO),
2354 AR6K_DATA_PKT_TAG);
2355}
2356
2357HTC_ENDPOINT_ID
2358ar6000_ac2_endpoint_id ( void * devt, u8 ac)
2359{
2360 struct ar6_softc *ar = (struct ar6_softc *) devt;
2361 return(arAc2EndpointID(ar, ac));
2362}
2363
2364u8 ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep )
2365{
2366 struct ar6_softc *ar = (struct ar6_softc *) devt;
2367 return(arEndpoint2Ac(ar, ep ));
2368}
2369
2370#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE)
2371static int ath6kl_config_btcoex_params(struct ar6_softc *ar)
2372{
2373 int r;
2374 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd;
2375 WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd;
2376
2377 /* Configure the type of BT collocated with WLAN */
2378 memset(&sbcb_cmd, 0, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
2379 sbcb_cmd.btcoexCoLocatedBTdev = ATH6KL_BT_DEV;
2380
2381 r = wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd);
2382
2383 if (r) {
2384 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
2385 ("Unable to set collocated BT type\n"));
2386 return r;
2387 }
2388
2389 /* Configure the type of BT collocated with WLAN */
2390 memset(&sbfa_cmd, 0, sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
2391
2392 sbfa_cmd.btcoexFeAntType = ATH6KL_BT_ANTENNA;
2393
2394 r = wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd);
2395 if (r) {
2396 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
2397 ("Unable to set fornt end antenna configuration\n"));
2398 return r;
2399 }
2400
2401 return 0;
2402}
2403#else
2404static int ath6kl_config_btcoex_params(struct ar6_softc *ar)
2405{
2406 return 0;
2407}
2408#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */
2409
2410/*
2411 * This function applies WLAN specific configuration defined in wlan_config.h
2412 */
2413int ar6000_target_config_wlan_params(struct ar6_softc *ar)
2414{
2415 int status = 0;
2416
2417#ifdef CONFIG_HOST_TCMD_SUPPORT
2418 if (ar->arTargetMode != AR6000_WLAN_MODE) {
2419 return 0;
2420 }
2421#endif /* CONFIG_HOST_TCMD_SUPPORT */
2422
2423 /*
2424 * configure the device for rx dot11 header rules 0,0 are the default values
2425 * therefore this command can be skipped if the inputs are 0,FALSE,FALSE.Required
2426 * if checksum offload is needed. Set RxMetaVersion to 2
2427 */
2428 if ((wmi_set_rx_frame_format_cmd(ar->arWmi,ar->rxMetaVersion, processDot11Hdr, processDot11Hdr)) != 0) {
2429 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the rx frame format.\n"));
2430 status = A_ERROR;
2431 }
2432
2433 status = ath6kl_config_btcoex_params(ar);
2434 if (status)
2435 return status;
2436
2437#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN
2438 if ((wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) {
2439 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set power save fail event policy\n"));
2440 status = A_ERROR;
2441 }
2442#endif
2443
2444#if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP
2445 if ((wmi_set_lpreamble_cmd(ar->arWmi, 0, WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) {
2446 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set barker preamble policy\n"));
2447 status = A_ERROR;
2448 }
2449#endif
2450
2451 if ((wmi_set_keepalive_cmd(ar->arWmi, WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) != 0) {
2452 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set keep alive interval\n"));
2453 status = A_ERROR;
2454 }
2455
2456#if WLAN_CONFIG_DISABLE_11N
2457 {
2458 WMI_SET_HT_CAP_CMD htCap;
2459
2460 memset(&htCap, 0, sizeof(WMI_SET_HT_CAP_CMD));
2461 htCap.band = 0;
2462 if ((wmi_set_ht_cap_cmd(ar->arWmi, &htCap)) != 0) {
2463 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set ht capabilities \n"));
2464 status = A_ERROR;
2465 }
2466
2467 htCap.band = 1;
2468 if ((wmi_set_ht_cap_cmd(ar->arWmi, &htCap)) != 0) {
2469 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set ht capabilities \n"));
2470 status = A_ERROR;
2471 }
2472 }
2473#endif /* WLAN_CONFIG_DISABLE_11N */
2474
2475#ifdef ATH6K_CONFIG_OTA_MODE
2476 if ((wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER)) != 0) {
2477 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set power mode \n"));
2478 status = A_ERROR;
2479 }
2480#endif
2481
2482 if ((wmi_disctimeout_cmd(ar->arWmi, WLAN_CONFIG_DISCONNECT_TIMEOUT)) != 0) {
2483 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set disconnect timeout \n"));
2484 status = A_ERROR;
2485 }
2486
2487#if WLAN_CONFIG_DISABLE_TX_BURSTING
2488 if ((wmi_set_wmm_txop(ar->arWmi, WMI_TXOP_DISABLED)) != 0) {
2489 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set txop bursting \n"));
2490 status = A_ERROR;
2491 }
2492#endif
2493
2494 return status;
2495}
2496
2497/* This function does one time initialization for the lifetime of the device */
2498int ar6000_init(struct net_device *dev)
2499{
2500 struct ar6_softc *ar;
2501 int status;
2502 s32 timeleft;
2503 s16 i;
2504 int ret = 0;
2505
2506 if((ar = ar6k_priv(dev)) == NULL)
2507 {
2508 return -EIO;
2509 }
2510
2511 if (wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) {
2512
2513 ar6000_update_bdaddr(ar);
2514
2515 if (enablerssicompensation) {
2516 ar6000_copy_cust_data_from_target(ar->arHifDevice, ar->arTargetType);
2517 read_rssi_compensation_param(ar);
2518 for (i=-95; i<=0; i++) {
2519 rssi_compensation_table[0-i] = rssi_compensation_calc(ar,i);
2520 }
2521 }
2522 }
2523
2524 dev_hold(dev);
2525 rtnl_unlock();
2526
2527 /* Do we need to finish the BMI phase */
2528 if ((wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) &&
2529 (BMIDone(ar->arHifDevice) != 0))
2530 {
2531 ret = -EIO;
2532 goto ar6000_init_done;
2533 }
2534
2535 if (!bypasswmi)
2536 {
2537#if 0 /* TBDXXX */
2538 if (ar->arVersion.host_ver != ar->arVersion.target_ver) {
2539 A_PRINTF("WARNING: Host version 0x%x does not match Target "
2540 " version 0x%x!\n",
2541 ar->arVersion.host_ver, ar->arVersion.target_ver);
2542 }
2543#endif
2544
2545 /* Indicate that WMI is enabled (although not ready yet) */
2546 ar->arWmiEnabled = true;
2547 if ((ar->arWmi = wmi_init((void *) ar)) == NULL)
2548 {
2549 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize WMI.\n", __func__));
2550 ret = -EIO;
2551 goto ar6000_init_done;
2552 }
2553
2554 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Got WMI @ 0x%lx.\n", __func__,
2555 (unsigned long) ar->arWmi));
2556 }
2557
2558 do {
2559 struct htc_service_connect_req connect;
2560
2561 /* the reason we have to wait for the target here is that the driver layer
2562 * has to init BMI in order to set the host block size,
2563 */
2564 status = HTCWaitTarget(ar->arHtcTarget);
2565
2566 if (status) {
2567 break;
2568 }
2569
2570 A_MEMZERO(&connect,sizeof(connect));
2571 /* meta data is unused for now */
2572 connect.pMetaData = NULL;
2573 connect.MetaDataLength = 0;
2574 /* these fields are the same for all service endpoints */
2575 connect.EpCallbacks.pContext = ar;
2576 connect.EpCallbacks.EpTxCompleteMultiple = ar6000_tx_complete;
2577 connect.EpCallbacks.EpRecv = ar6000_rx;
2578 connect.EpCallbacks.EpRecvRefill = ar6000_rx_refill;
2579 connect.EpCallbacks.EpSendFull = ar6000_tx_queue_full;
2580 /* set the max queue depth so that our ar6000_tx_queue_full handler gets called.
2581 * Linux has the peculiarity of not providing flow control between the
2582 * NIC and the network stack. There is no API to indicate that a TX packet
2583 * was sent which could provide some back pressure to the network stack.
2584 * Under linux you would have to wait till the network stack consumed all sk_buffs
2585 * before any back-flow kicked in. Which isn't very friendly.
2586 * So we have to manage this ourselves */
2587 connect.MaxSendQueueDepth = MAX_DEFAULT_SEND_QUEUE_DEPTH;
2588 connect.EpCallbacks.RecvRefillWaterMark = AR6000_MAX_RX_BUFFERS / 4; /* set to 25 % */
2589 if (0 == connect.EpCallbacks.RecvRefillWaterMark) {
2590 connect.EpCallbacks.RecvRefillWaterMark++;
2591 }
2592 /* connect to control service */
2593 connect.ServiceID = WMI_CONTROL_SVC;
2594 status = ar6000_connectservice(ar,
2595 &connect,
2596 "WMI CONTROL");
2597 if (status) {
2598 break;
2599 }
2600
2601 connect.LocalConnectionFlags |= HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING;
2602 /* limit the HTC message size on the send path, although we can receive A-MSDU frames of
2603 * 4K, we will only send ethernet-sized (802.3) frames on the send path. */
2604 connect.MaxSendMsgSize = WMI_MAX_TX_DATA_FRAME_LENGTH;
2605
2606 /* to reduce the amount of committed memory for larger A_MSDU frames, use the recv-alloc threshold
2607 * mechanism for larger packets */
2608 connect.EpCallbacks.RecvAllocThreshold = AR6000_BUFFER_SIZE;
2609 connect.EpCallbacks.EpRecvAllocThresh = ar6000_alloc_amsdu_rxbuf;
2610
2611 /* for the remaining data services set the connection flag to reduce dribbling,
2612 * if configured to do so */
2613 if (reduce_credit_dribble) {
2614 connect.ConnectionFlags |= HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE;
2615 /* the credit dribble trigger threshold is (reduce_credit_dribble - 1) for a value
2616 * of 0-3 */
2617 connect.ConnectionFlags &= ~HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
2618 connect.ConnectionFlags |=
2619 ((u16)reduce_credit_dribble - 1) & HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
2620 }
2621 /* connect to best-effort service */
2622 connect.ServiceID = WMI_DATA_BE_SVC;
2623
2624 status = ar6000_connectservice(ar,
2625 &connect,
2626 "WMI DATA BE");
2627 if (status) {
2628 break;
2629 }
2630
2631 /* connect to back-ground
2632 * map this to WMI LOW_PRI */
2633 connect.ServiceID = WMI_DATA_BK_SVC;
2634 status = ar6000_connectservice(ar,
2635 &connect,
2636 "WMI DATA BK");
2637 if (status) {
2638 break;
2639 }
2640
2641 /* connect to Video service, map this to
2642 * to HI PRI */
2643 connect.ServiceID = WMI_DATA_VI_SVC;
2644 status = ar6000_connectservice(ar,
2645 &connect,
2646 "WMI DATA VI");
2647 if (status) {
2648 break;
2649 }
2650
2651 /* connect to VO service, this is currently not
2652 * mapped to a WMI priority stream due to historical reasons.
2653 * WMI originally defined 3 priorities over 3 mailboxes
2654 * We can change this when WMI is reworked so that priorities are not
2655 * dependent on mailboxes */
2656 connect.ServiceID = WMI_DATA_VO_SVC;
2657 status = ar6000_connectservice(ar,
2658 &connect,
2659 "WMI DATA VO");
2660 if (status) {
2661 break;
2662 }
2663
2664 A_ASSERT(arAc2EndpointID(ar,WMM_AC_BE) != 0);
2665 A_ASSERT(arAc2EndpointID(ar,WMM_AC_BK) != 0);
2666 A_ASSERT(arAc2EndpointID(ar,WMM_AC_VI) != 0);
2667 A_ASSERT(arAc2EndpointID(ar,WMM_AC_VO) != 0);
2668
2669 /* setup access class priority mappings */
2670 ar->arAcStreamPriMap[WMM_AC_BK] = 0; /* lowest */
2671 ar->arAcStreamPriMap[WMM_AC_BE] = 1; /* */
2672 ar->arAcStreamPriMap[WMM_AC_VI] = 2; /* */
2673 ar->arAcStreamPriMap[WMM_AC_VO] = 3; /* highest */
2674
2675#ifdef EXPORT_HCI_BRIDGE_INTERFACE
2676 if (setuphci && (NULL != ar6kHciTransCallbacks.setupTransport)) {
2677 struct hci_transport_misc_handles hciHandles;
2678
2679 hciHandles.netDevice = ar->arNetDev;
2680 hciHandles.hifDevice = ar->arHifDevice;
2681 hciHandles.htcHandle = ar->arHtcTarget;
2682 status = (int)(ar6kHciTransCallbacks.setupTransport(&hciHandles));
2683 }
2684#else
2685 if (setuphci) {
2686 /* setup HCI */
2687 status = ar6000_setup_hci(ar);
2688 }
2689#endif
2690
2691 } while (false);
2692
2693 if (status) {
2694 ret = -EIO;
2695 goto ar6000_init_done;
2696 }
2697
2698 if (regscanmode) {
2699 u32 param;
2700
2701 if (BMIReadMemory(ar->arHifDevice,
2702 HOST_INTEREST_ITEM_ADDRESS(ar,
2703 hi_option_flag),
2704 (u8 *)&param,
2705 4) != 0) {
2706 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
2707 ("BMIReadMemory forsetting "
2708 "regscanmode failed\n"));
2709 return A_ERROR;
2710 }
2711
2712 if (regscanmode == 1)
2713 param |= HI_OPTION_SKIP_REG_SCAN;
2714 else if (regscanmode == 2)
2715 param |= HI_OPTION_INIT_REG_SCAN;
2716
2717 if (BMIWriteMemory(ar->arHifDevice,
2718 HOST_INTEREST_ITEM_ADDRESS(ar,
2719 hi_option_flag),
2720 (u8 *)&param,
2721 4) != 0) {
2722 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
2723 ("BMIWriteMemory forsetting "
2724 "regscanmode failed\n"));
2725 return A_ERROR;
2726 }
2727 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Regulatory scan mode set\n"));
2728 }
2729
2730 /*
2731 * give our connected endpoints some buffers
2732 */
2733
2734 ar6000_rx_refill(ar, ar->arControlEp);
2735 ar6000_rx_refill(ar, arAc2EndpointID(ar,WMM_AC_BE));
2736
2737 /*
2738 * We will post the receive buffers only for SPE or endpoint ping testing so we are
2739 * making it conditional on the 'bypasswmi' flag.
2740 */
2741 if (bypasswmi) {
2742 ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_BK));
2743 ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VI));
2744 ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VO));
2745 }
2746
2747 /* allocate some buffers that handle larger AMSDU frames */
2748 ar6000_refill_amsdu_rxbufs(ar,AR6000_MAX_AMSDU_RX_BUFFERS);
2749
2750 /* setup credit distribution */
2751 ar6000_setup_credit_dist(ar->arHtcTarget, &ar->arCreditStateInfo);
2752
2753 /* Since cookies are used for HTC transports, they should be */
2754 /* initialized prior to enabling HTC. */
2755 ar6000_cookie_init(ar);
2756
2757 /* start HTC */
2758 status = HTCStart(ar->arHtcTarget);
2759
2760 if (status) {
2761 if (ar->arWmiEnabled == true) {
2762 wmi_shutdown(ar->arWmi);
2763 ar->arWmiEnabled = false;
2764 ar->arWmi = NULL;
2765 }
2766 ar6000_cookie_cleanup(ar);
2767 ret = -EIO;
2768 goto ar6000_init_done;
2769 }
2770
2771 if (!bypasswmi) {
2772 /* Wait for Wmi event to be ready */
2773 timeleft = wait_event_interruptible_timeout(arEvent,
2774 (ar->arWmiReady == true), wmitimeout * HZ);
2775
2776 if (ar->arVersion.abi_ver != AR6K_ABI_VERSION) {
2777 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ABI Version mismatch: Host(0x%x), Target(0x%x)\n", AR6K_ABI_VERSION, ar->arVersion.abi_ver));
2778#ifndef ATH6K_SKIP_ABI_VERSION_CHECK
2779 ret = -EIO;
2780 goto ar6000_init_done;
2781#endif /* ATH6K_SKIP_ABI_VERSION_CHECK */
2782 }
2783
2784 if(!timeleft || signal_pending(current))
2785 {
2786 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI is not ready or wait was interrupted\n"));
2787 ret = -EIO;
2788 goto ar6000_init_done;
2789 }
2790
2791 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() WMI is ready\n", __func__));
2792
2793 /* Communicate the wmi protocol verision to the target */
2794 if ((ar6000_set_host_app_area(ar)) != 0) {
2795 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the host app area\n"));
2796 }
2797 ar6000_target_config_wlan_params(ar);
2798 }
2799
2800 ar->arNumDataEndPts = 1;
2801
2802 if (bypasswmi) {
2803 /* for tests like endpoint ping, the MAC address needs to be non-zero otherwise
2804 * the data path through a raw socket is disabled */
2805 dev->dev_addr[0] = 0x00;
2806 dev->dev_addr[1] = 0x01;
2807 dev->dev_addr[2] = 0x02;
2808 dev->dev_addr[3] = 0xAA;
2809 dev->dev_addr[4] = 0xBB;
2810 dev->dev_addr[5] = 0xCC;
2811 }
2812
2813ar6000_init_done:
2814 rtnl_lock();
2815 dev_put(dev);
2816
2817 return ret;
2818}
2819
2820
2821void
2822ar6000_bitrate_rx(void *devt, s32 rateKbps)
2823{
2824 struct ar6_softc *ar = (struct ar6_softc *)devt;
2825
2826 ar->arBitRate = rateKbps;
2827 wake_up(&arEvent);
2828}
2829
2830void
2831ar6000_ratemask_rx(void *devt, u32 ratemask)
2832{
2833 struct ar6_softc *ar = (struct ar6_softc *)devt;
2834
2835 ar->arRateMask = ratemask;
2836 wake_up(&arEvent);
2837}
2838
2839void
2840ar6000_txPwr_rx(void *devt, u8 txPwr)
2841{
2842 struct ar6_softc *ar = (struct ar6_softc *)devt;
2843
2844 ar->arTxPwr = txPwr;
2845 wake_up(&arEvent);
2846}
2847
2848
2849void
2850ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList)
2851{
2852 struct ar6_softc *ar = (struct ar6_softc *)devt;
2853
2854 memcpy(ar->arChannelList, chanList, numChan * sizeof (u16));
2855 ar->arNumChannels = numChan;
2856
2857 wake_up(&arEvent);
2858}
2859
2860u8 ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, u32 *mapNo)
2861{
2862 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2863 u8 *datap;
2864 ATH_MAC_HDR *macHdr;
2865 u32 i, eptMap;
2866
2867 (*mapNo) = 0;
2868 datap = A_NETBUF_DATA(skb);
2869 macHdr = (ATH_MAC_HDR *)(datap + sizeof(WMI_DATA_HDR));
2870 if (IEEE80211_IS_MULTICAST(macHdr->dstMac)) {
2871 return ENDPOINT_2;
2872 }
2873
2874 eptMap = -1;
2875 for (i = 0; i < ar->arNodeNum; i ++) {
2876 if (IEEE80211_ADDR_EQ(macHdr->dstMac, ar->arNodeMap[i].macAddress)) {
2877 (*mapNo) = i + 1;
2878 ar->arNodeMap[i].txPending ++;
2879 return ar->arNodeMap[i].epId;
2880 }
2881
2882 if ((eptMap == -1) && !ar->arNodeMap[i].txPending) {
2883 eptMap = i;
2884 }
2885 }
2886
2887 if (eptMap == -1) {
2888 eptMap = ar->arNodeNum;
2889 ar->arNodeNum ++;
2890 A_ASSERT(ar->arNodeNum <= MAX_NODE_NUM);
2891 }
2892
2893 memcpy(ar->arNodeMap[eptMap].macAddress, macHdr->dstMac, IEEE80211_ADDR_LEN);
2894
2895 for (i = ENDPOINT_2; i <= ENDPOINT_5; i ++) {
2896 if (!ar->arTxPending[i]) {
2897 ar->arNodeMap[eptMap].epId = i;
2898 break;
2899 }
2900 // No free endpoint is available, start redistribution on the inuse endpoints.
2901 if (i == ENDPOINT_5) {
2902 ar->arNodeMap[eptMap].epId = ar->arNexEpId;
2903 ar->arNexEpId ++;
2904 if (ar->arNexEpId > ENDPOINT_5) {
2905 ar->arNexEpId = ENDPOINT_2;
2906 }
2907 }
2908 }
2909
2910 (*mapNo) = eptMap + 1;
2911 ar->arNodeMap[eptMap].txPending ++;
2912
2913 return ar->arNodeMap[eptMap].epId;
2914}
2915
2916#ifdef DEBUG
2917static void ar6000_dump_skb(struct sk_buff *skb)
2918{
2919 u_char *ch;
2920 for (ch = A_NETBUF_DATA(skb);
2921 (unsigned long)ch < ((unsigned long)A_NETBUF_DATA(skb) +
2922 A_NETBUF_LEN(skb)); ch++)
2923 {
2924 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("%2.2x ", *ch));
2925 }
2926 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("\n"));
2927}
2928#endif
2929
2930#ifdef HTC_TEST_SEND_PKTS
2931static void DoHTCSendPktsTest(struct ar6_softc *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *skb);
2932#endif
2933
2934static int
2935ar6000_data_tx(struct sk_buff *skb, struct net_device *dev)
2936{
2937#define AC_NOT_MAPPED 99
2938 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2939 u8 ac = AC_NOT_MAPPED;
2940 HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED;
2941 u32 mapNo = 0;
2942 int len;
2943 struct ar_cookie *cookie;
2944 bool checkAdHocPsMapping = false,bMoreData = false;
2945 HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG;
2946 u8 dot11Hdr = processDot11Hdr;
2947#ifdef CONFIG_PM
2948 if (ar->arWowState != WLAN_WOW_STATE_NONE) {
2949 A_NETBUF_FREE(skb);
2950 return 0;
2951 }
2952#endif /* CONFIG_PM */
2953
2954 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_data_tx start - skb=0x%lx, data=0x%lx, len=0x%x\n",
2955 (unsigned long)skb, (unsigned long)A_NETBUF_DATA(skb),
2956 A_NETBUF_LEN(skb)));
2957
2958 /* If target is not associated */
2959 if( (!ar->arConnected && !bypasswmi)
2960#ifdef CONFIG_HOST_TCMD_SUPPORT
2961 /* TCMD doesn't support any data, free the buf and return */
2962 || (ar->arTargetMode == AR6000_TCMD_MODE)
2963#endif
2964 ) {
2965 A_NETBUF_FREE(skb);
2966 return 0;
2967 }
2968
2969 do {
2970
2971 if (ar->arWmiReady == false && bypasswmi == 0) {
2972 break;
2973 }
2974
2975#ifdef BLOCK_TX_PATH_FLAG
2976 if (blocktx) {
2977 break;
2978 }
2979#endif /* BLOCK_TX_PATH_FLAG */
2980
2981 /* AP mode Power save processing */
2982 /* If the dst STA is in sleep state, queue the pkt in its PS queue */
2983
2984 if (ar->arNetworkType == AP_NETWORK) {
2985 ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
2986 sta_t *conn = NULL;
2987
2988 /* If the dstMac is a Multicast address & atleast one of the
2989 * associated STA is in PS mode, then queue the pkt to the
2990 * mcastq
2991 */
2992 if (IEEE80211_IS_MULTICAST(datap->dstMac)) {
2993 u8 ctr=0;
2994 bool qMcast=false;
2995
2996
2997 for (ctr=0; ctr<AP_MAX_NUM_STA; ctr++) {
2998 if (STA_IS_PWR_SLEEP((&ar->sta_list[ctr]))) {
2999 qMcast = true;
3000 }
3001 }
3002 if(qMcast) {
3003
3004 /* If this transmit is not because of a Dtim Expiry q it */
3005 if (ar->DTIMExpired == false) {
3006 bool isMcastqEmpty = false;
3007
3008 A_MUTEX_LOCK(&ar->mcastpsqLock);
3009 isMcastqEmpty = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
3010 A_NETBUF_ENQUEUE(&ar->mcastpsq, skb);
3011 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
3012
3013 /* If this is the first Mcast pkt getting queued
3014 * indicate to the target to set the BitmapControl LSB
3015 * of the TIM IE.
3016 */
3017 if (isMcastqEmpty) {
3018 wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 1);
3019 }
3020 return 0;
3021 } else {
3022 /* This transmit is because of Dtim expiry. Determine if
3023 * MoreData bit has to be set.
3024 */
3025 A_MUTEX_LOCK(&ar->mcastpsqLock);
3026 if(!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
3027 bMoreData = true;
3028 }
3029 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
3030 }
3031 }
3032 } else {
3033 conn = ieee80211_find_conn(ar, datap->dstMac);
3034 if (conn) {
3035 if (STA_IS_PWR_SLEEP(conn)) {
3036 /* If this transmit is not because of a PsPoll q it*/
3037 if (!STA_IS_PS_POLLED(conn)) {
3038 bool isPsqEmpty = false;
3039 /* Queue the frames if the STA is sleeping */
3040 A_MUTEX_LOCK(&conn->psqLock);
3041 isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
3042 A_NETBUF_ENQUEUE(&conn->psq, skb);
3043 A_MUTEX_UNLOCK(&conn->psqLock);
3044
3045 /* If this is the first pkt getting queued
3046 * for this STA, update the PVB for this STA
3047 */
3048 if (isPsqEmpty) {
3049 wmi_set_pvb_cmd(ar->arWmi, conn->aid, 1);
3050 }
3051
3052 return 0;
3053 } else {
3054 /* This tx is because of a PsPoll. Determine if
3055 * MoreData bit has to be set
3056 */
3057 A_MUTEX_LOCK(&conn->psqLock);
3058 if (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) {
3059 bMoreData = true;
3060 }
3061 A_MUTEX_UNLOCK(&conn->psqLock);
3062 }
3063 }
3064 } else {
3065
3066 /* non existent STA. drop the frame */
3067 A_NETBUF_FREE(skb);
3068 return 0;
3069 }
3070 }
3071 }
3072
3073 if (ar->arWmiEnabled) {
3074 u8 csumStart=0;
3075 u8 csumDest=0;
3076 u8 csum=skb->ip_summed;
3077 if(csumOffload && (csum==CHECKSUM_PARTIAL)){
3078 csumStart = (skb->head + skb->csum_start - skb_network_header(skb) +
3079 sizeof(ATH_LLC_SNAP_HDR));
3080 csumDest=skb->csum_offset+csumStart;
3081 }
3082 if (A_NETBUF_HEADROOM(skb) < dev->hard_header_len - LINUX_HACK_FUDGE_FACTOR) {
3083 struct sk_buff *newbuf;
3084
3085 /*
3086 * We really should have gotten enough headroom but sometimes
3087 * we still get packets with not enough headroom. Copy the packet.
3088 */
3089 len = A_NETBUF_LEN(skb);
3090 newbuf = A_NETBUF_ALLOC(len);
3091 if (newbuf == NULL) {
3092 break;
3093 }
3094 A_NETBUF_PUT(newbuf, len);
3095 memcpy(A_NETBUF_DATA(newbuf), A_NETBUF_DATA(skb), len);
3096 A_NETBUF_FREE(skb);
3097 skb = newbuf;
3098 /* fall through and assemble header */
3099 }
3100
3101 if (dot11Hdr) {
3102 if (wmi_dot11_hdr_add(ar->arWmi,skb,ar->arNetworkType) != 0) {
3103 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx-wmi_dot11_hdr_add failed\n"));
3104 break;
3105 }
3106 } else {
3107 if (wmi_dix_2_dot3(ar->arWmi, skb) != 0) {
3108 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_dix_2_dot3 failed\n"));
3109 break;
3110 }
3111 }
3112 if(csumOffload && (csum ==CHECKSUM_PARTIAL)){
3113 WMI_TX_META_V2 metaV2;
3114 metaV2.csumStart =csumStart;
3115 metaV2.csumDest = csumDest;
3116 metaV2.csumFlags = 0x1;/*instruct target to calculate checksum*/
3117 if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,
3118 WMI_META_VERSION_2,&metaV2) != 0) {
3119 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n"));
3120 break;
3121 }
3122
3123 }
3124 else
3125 {
3126 if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,0,NULL) != 0) {
3127 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n"));
3128 break;
3129 }
3130 }
3131
3132
3133 if ((ar->arNetworkType == ADHOC_NETWORK) &&
3134 ar->arIbssPsEnable && ar->arConnected) {
3135 /* flag to check adhoc mapping once we take the lock below: */
3136 checkAdHocPsMapping = true;
3137
3138 } else {
3139 /* get the stream mapping */
3140 ac = wmi_implicit_create_pstream(ar->arWmi, skb, 0, ar->arWmmEnabled);
3141 }
3142
3143 } else {
3144 EPPING_HEADER *eppingHdr;
3145
3146 eppingHdr = A_NETBUF_DATA(skb);
3147
3148 if (IS_EPPING_PACKET(eppingHdr)) {
3149 /* the stream ID is mapped to an access class */
3150 ac = eppingHdr->StreamNo_h;
3151 /* some EPPING packets cannot be dropped no matter what access class it was
3152 * sent on. We can change the packet tag to guarantee it will not get dropped */
3153 if (IS_EPING_PACKET_NO_DROP(eppingHdr)) {
3154 htc_tag = AR6K_CONTROL_PKT_TAG;
3155 }
3156
3157 if (ac == HCI_TRANSPORT_STREAM_NUM) {
3158 /* pass this to HCI */
3159#ifndef EXPORT_HCI_BRIDGE_INTERFACE
3160 if (!hci_test_send(ar,skb)) {
3161 return 0;
3162 }
3163#endif
3164 /* set AC to discard this skb */
3165 ac = AC_NOT_MAPPED;
3166 } else {
3167 /* a quirk of linux, the payload of the frame is 32-bit aligned and thus the addition
3168 * of the HTC header will mis-align the start of the HTC frame, so we add some
3169 * padding which will be stripped off in the target */
3170 if (EPPING_ALIGNMENT_PAD > 0) {
3171 A_NETBUF_PUSH(skb, EPPING_ALIGNMENT_PAD);
3172 }
3173 }
3174
3175 } else {
3176 /* not a ping packet, drop it */
3177 ac = AC_NOT_MAPPED;
3178 }
3179 }
3180
3181 } while (false);
3182
3183 /* did we succeed ? */
3184 if ((ac == AC_NOT_MAPPED) && !checkAdHocPsMapping) {
3185 /* cleanup and exit */
3186 A_NETBUF_FREE(skb);
3187 AR6000_STAT_INC(ar, tx_dropped);
3188 AR6000_STAT_INC(ar, tx_aborted_errors);
3189 return 0;
3190 }
3191
3192 cookie = NULL;
3193
3194 /* take the lock to protect driver data */
3195 AR6000_SPIN_LOCK(&ar->arLock, 0);
3196
3197 do {
3198
3199 if (checkAdHocPsMapping) {
3200 eid = ar6000_ibss_map_epid(skb, dev, &mapNo);
3201 }else {
3202 eid = arAc2EndpointID (ar, ac);
3203 }
3204 /* validate that the endpoint is connected */
3205 if (eid == 0 || eid == ENDPOINT_UNUSED ) {
3206 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" eid %d is NOT mapped!\n", eid));
3207 break;
3208 }
3209 /* allocate resource for this packet */
3210 cookie = ar6000_alloc_cookie(ar);
3211
3212 if (cookie != NULL) {
3213 /* update counts while the lock is held */
3214 ar->arTxPending[eid]++;
3215 ar->arTotalTxDataPending++;
3216 }
3217
3218 } while (false);
3219
3220 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3221
3222 if (cookie != NULL) {
3223 cookie->arc_bp[0] = (unsigned long)skb;
3224 cookie->arc_bp[1] = mapNo;
3225 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
3226 cookie,
3227 A_NETBUF_DATA(skb),
3228 A_NETBUF_LEN(skb),
3229 eid,
3230 htc_tag);
3231
3232#ifdef DEBUG
3233 if (debugdriver >= 3) {
3234 ar6000_dump_skb(skb);
3235 }
3236#endif
3237#ifdef HTC_TEST_SEND_PKTS
3238 DoHTCSendPktsTest(ar,mapNo,eid,skb);
3239#endif
3240 /* HTC interface is asynchronous, if this fails, cleanup will happen in
3241 * the ar6000_tx_complete callback */
3242 HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
3243 } else {
3244 /* no packet to send, cleanup */
3245 A_NETBUF_FREE(skb);
3246 AR6000_STAT_INC(ar, tx_dropped);
3247 AR6000_STAT_INC(ar, tx_aborted_errors);
3248 }
3249
3250 return 0;
3251}
3252
3253int
3254ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev)
3255{
3256 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
3257 struct ar_cookie *cookie;
3258 HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED;
3259
3260 cookie = NULL;
3261 AR6000_SPIN_LOCK(&ar->arLock, 0);
3262
3263 /* For now we send ACL on BE endpoint: We can also have a dedicated EP */
3264 eid = arAc2EndpointID (ar, 0);
3265 /* allocate resource for this packet */
3266 cookie = ar6000_alloc_cookie(ar);
3267
3268 if (cookie != NULL) {
3269 /* update counts while the lock is held */
3270 ar->arTxPending[eid]++;
3271 ar->arTotalTxDataPending++;
3272 }
3273
3274
3275 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3276
3277 if (cookie != NULL) {
3278 cookie->arc_bp[0] = (unsigned long)skb;
3279 cookie->arc_bp[1] = 0;
3280 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
3281 cookie,
3282 A_NETBUF_DATA(skb),
3283 A_NETBUF_LEN(skb),
3284 eid,
3285 AR6K_DATA_PKT_TAG);
3286
3287 /* HTC interface is asynchronous, if this fails, cleanup will happen in
3288 * the ar6000_tx_complete callback */
3289 HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
3290 } else {
3291 /* no packet to send, cleanup */
3292 A_NETBUF_FREE(skb);
3293 AR6000_STAT_INC(ar, tx_dropped);
3294 AR6000_STAT_INC(ar, tx_aborted_errors);
3295 }
3296 return 0;
3297}
3298
3299
3300#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
3301static void
3302tvsub(register struct timeval *out, register struct timeval *in)
3303{
3304 if((out->tv_usec -= in->tv_usec) < 0) {
3305 out->tv_sec--;
3306 out->tv_usec += 1000000;
3307 }
3308 out->tv_sec -= in->tv_sec;
3309}
3310
3311void
3312applyAPTCHeuristics(struct ar6_softc *ar)
3313{
3314 u32 duration;
3315 u32 numbytes;
3316 u32 throughput;
3317 struct timeval ts;
3318 int status;
3319
3320 AR6000_SPIN_LOCK(&ar->arLock, 0);
3321
3322 if ((enableAPTCHeuristics) && (!aptcTR.timerScheduled)) {
3323 do_gettimeofday(&ts);
3324 tvsub(&ts, &aptcTR.samplingTS);
3325 duration = ts.tv_sec * 1000 + ts.tv_usec / 1000; /* ms */
3326 numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
3327
3328 if (duration > APTC_TRAFFIC_SAMPLING_INTERVAL) {
3329 /* Initialize the time stamp and byte count */
3330 aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
3331 do_gettimeofday(&aptcTR.samplingTS);
3332
3333 /* Calculate and decide based on throughput thresholds */
3334 throughput = ((numbytes * 8) / duration);
3335 if (throughput > APTC_UPPER_THROUGHPUT_THRESHOLD) {
3336 /* Disable Sleep and schedule a timer */
3337 A_ASSERT(ar->arWmiReady == true);
3338 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3339 status = wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER);
3340 AR6000_SPIN_LOCK(&ar->arLock, 0);
3341 A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
3342 aptcTR.timerScheduled = true;
3343 }
3344 }
3345 }
3346
3347 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3348}
3349#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
3350
3351static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket)
3352{
3353 struct ar6_softc *ar = (struct ar6_softc *)Context;
3354 HTC_SEND_FULL_ACTION action = HTC_SEND_FULL_KEEP;
3355 bool stopNet = false;
3356 HTC_ENDPOINT_ID Endpoint = HTC_GET_ENDPOINT_FROM_PKT(pPacket);
3357
3358 do {
3359
3360 if (bypasswmi) {
3361 int accessClass;
3362
3363 if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) {
3364 /* don't drop special control packets */
3365 break;
3366 }
3367
3368 accessClass = arEndpoint2Ac(ar,Endpoint);
3369 /* for endpoint ping testing drop Best Effort and Background */
3370 if ((accessClass == WMM_AC_BE) || (accessClass == WMM_AC_BK)) {
3371 action = HTC_SEND_FULL_DROP;
3372 stopNet = false;
3373 } else {
3374 /* keep but stop the netqueues */
3375 stopNet = true;
3376 }
3377 break;
3378 }
3379
3380 if (Endpoint == ar->arControlEp) {
3381 /* under normal WMI if this is getting full, then something is running rampant
3382 * the host should not be exhausting the WMI queue with too many commands
3383 * the only exception to this is during testing using endpointping */
3384 AR6000_SPIN_LOCK(&ar->arLock, 0);
3385 /* set flag to handle subsequent messages */
3386 ar->arWMIControlEpFull = true;
3387 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3388 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI Control Endpoint is FULL!!! \n"));
3389 /* no need to stop the network */
3390 stopNet = false;
3391 break;
3392 }
3393
3394 /* if we get here, we are dealing with data endpoints getting full */
3395
3396 if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) {
3397 /* don't drop control packets issued on ANY data endpoint */
3398 break;
3399 }
3400
3401 if (ar->arNetworkType == ADHOC_NETWORK) {
3402 /* in adhoc mode, we cannot differentiate traffic priorities so there is no need to
3403 * continue, however we should stop the network */
3404 stopNet = true;
3405 break;
3406 }
3407 /* the last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for the highest
3408 * active stream */
3409 if (ar->arAcStreamPriMap[arEndpoint2Ac(ar,Endpoint)] < ar->arHiAcStreamActivePri &&
3410 ar->arCookieCount <= MAX_HI_COOKIE_NUM) {
3411 /* this stream's priority is less than the highest active priority, we
3412 * give preference to the highest priority stream by directing
3413 * HTC to drop the packet that overflowed */
3414 action = HTC_SEND_FULL_DROP;
3415 /* since we are dropping packets, no need to stop the network */
3416 stopNet = false;
3417 break;
3418 }
3419
3420 } while (false);
3421
3422 if (stopNet) {
3423 AR6000_SPIN_LOCK(&ar->arLock, 0);
3424 ar->arNetQueueStopped = true;
3425 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3426 /* one of the data endpoints queues is getting full..need to stop network stack
3427 * the queue will resume in ar6000_tx_complete() */
3428 netif_stop_queue(ar->arNetDev);
3429 }
3430
3431 return action;
3432}
3433
3434
3435static void
3436ar6000_tx_complete(void *Context, struct htc_packet_queue *pPacketQueue)
3437{
3438 struct ar6_softc *ar = (struct ar6_softc *)Context;
3439 u32 mapNo = 0;
3440 int status;
3441 struct ar_cookie * ar_cookie;
3442 HTC_ENDPOINT_ID eid;
3443 bool wakeEvent = false;
3444 struct sk_buff_head skb_queue;
3445 struct htc_packet *pPacket;
3446 struct sk_buff *pktSkb;
3447 bool flushing = false;
3448
3449 skb_queue_head_init(&skb_queue);
3450
3451 /* lock the driver as we update internal state */
3452 AR6000_SPIN_LOCK(&ar->arLock, 0);
3453
3454 /* reap completed packets */
3455 while (!HTC_QUEUE_EMPTY(pPacketQueue)) {
3456
3457 pPacket = HTC_PACKET_DEQUEUE(pPacketQueue);
3458
3459 ar_cookie = (struct ar_cookie *)pPacket->pPktContext;
3460 A_ASSERT(ar_cookie);
3461
3462 status = pPacket->Status;
3463 pktSkb = (struct sk_buff *)ar_cookie->arc_bp[0];
3464 eid = pPacket->Endpoint;
3465 mapNo = ar_cookie->arc_bp[1];
3466
3467 A_ASSERT(pktSkb);
3468 A_ASSERT(pPacket->pBuffer == A_NETBUF_DATA(pktSkb));
3469
3470 /* add this to the list, use faster non-lock API */
3471 __skb_queue_tail(&skb_queue,pktSkb);
3472
3473 if (!status) {
3474 A_ASSERT(pPacket->ActualLength == A_NETBUF_LEN(pktSkb));
3475 }
3476
3477 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_tx_complete skb=0x%lx data=0x%lx len=0x%x eid=%d ",
3478 (unsigned long)pktSkb, (unsigned long)pPacket->pBuffer,
3479 pPacket->ActualLength,
3480 eid));
3481
3482 ar->arTxPending[eid]--;
3483
3484 if ((eid != ar->arControlEp) || bypasswmi) {
3485 ar->arTotalTxDataPending--;
3486 }
3487
3488 if (eid == ar->arControlEp)
3489 {
3490 if (ar->arWMIControlEpFull) {
3491 /* since this packet completed, the WMI EP is no longer full */
3492 ar->arWMIControlEpFull = false;
3493 }
3494
3495 if (ar->arTxPending[eid] == 0) {
3496 wakeEvent = true;
3497 }
3498 }
3499
3500 if (status) {
3501 if (status == A_ECANCELED) {
3502 /* a packet was flushed */
3503 flushing = true;
3504 }
3505 AR6000_STAT_INC(ar, tx_errors);
3506 if (status != A_NO_RESOURCE) {
3507 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() -TX ERROR, status: 0x%x\n", __func__,
3508 status));
3509 }
3510 } else {
3511 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("OK\n"));
3512 flushing = false;
3513 AR6000_STAT_INC(ar, tx_packets);
3514 ar->arNetStats.tx_bytes += A_NETBUF_LEN(pktSkb);
3515#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
3516 aptcTR.bytesTransmitted += a_netbuf_to_len(pktSkb);
3517 applyAPTCHeuristics(ar);
3518#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
3519 }
3520
3521 // TODO this needs to be looked at
3522 if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable
3523 && (eid != ar->arControlEp) && mapNo)
3524 {
3525 mapNo --;
3526 ar->arNodeMap[mapNo].txPending --;
3527
3528 if (!ar->arNodeMap[mapNo].txPending && (mapNo == (ar->arNodeNum - 1))) {
3529 u32 i;
3530 for (i = ar->arNodeNum; i > 0; i --) {
3531 if (!ar->arNodeMap[i - 1].txPending) {
3532 A_MEMZERO(&ar->arNodeMap[i - 1], sizeof(struct ar_node_mapping));
3533 ar->arNodeNum --;
3534 } else {
3535 break;
3536 }
3537 }
3538 }
3539 }
3540
3541 ar6000_free_cookie(ar, ar_cookie);
3542
3543 if (ar->arNetQueueStopped) {
3544 ar->arNetQueueStopped = false;
3545 }
3546 }
3547
3548 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3549
3550 /* lock is released, we can freely call other kernel APIs */
3551
3552 /* free all skbs in our local list */
3553 while (!skb_queue_empty(&skb_queue)) {
3554 /* use non-lock version */
3555 pktSkb = __skb_dequeue(&skb_queue);
3556 A_NETBUF_FREE(pktSkb);
3557 }
3558
3559 if ((ar->arConnected == true) || bypasswmi) {
3560 if (!flushing) {
3561 /* don't wake the queue if we are flushing, other wise it will just
3562 * keep queueing packets, which will keep failing */
3563 netif_wake_queue(ar->arNetDev);
3564 }
3565 }
3566
3567 if (wakeEvent) {
3568 wake_up(&arEvent);
3569 }
3570
3571}
3572
3573sta_t *
3574ieee80211_find_conn(struct ar6_softc *ar, u8 *node_addr)
3575{
3576 sta_t *conn = NULL;
3577 u8 i, max_conn;
3578
3579 switch(ar->arNetworkType) {
3580 case AP_NETWORK:
3581 max_conn = AP_MAX_NUM_STA;
3582 break;
3583 default:
3584 max_conn=0;
3585 break;
3586 }
3587
3588 for (i = 0; i < max_conn; i++) {
3589 if (IEEE80211_ADDR_EQ(node_addr, ar->sta_list[i].mac)) {
3590 conn = &ar->sta_list[i];
3591 break;
3592 }
3593 }
3594
3595 return conn;
3596}
3597
3598sta_t *ieee80211_find_conn_for_aid(struct ar6_softc *ar, u8 aid)
3599{
3600 sta_t *conn = NULL;
3601 u8 ctr;
3602
3603 for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
3604 if (ar->sta_list[ctr].aid == aid) {
3605 conn = &ar->sta_list[ctr];
3606 break;
3607 }
3608 }
3609 return conn;
3610}
3611
3612/*
3613 * Receive event handler. This is called by HTC when a packet is received
3614 */
3615int pktcount;
3616static void
3617ar6000_rx(void *Context, struct htc_packet *pPacket)
3618{
3619 struct ar6_softc *ar = (struct ar6_softc *)Context;
3620 struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext;
3621 int minHdrLen;
3622 u8 containsDot11Hdr = 0;
3623 int status = pPacket->Status;
3624 HTC_ENDPOINT_ID ept = pPacket->Endpoint;
3625
3626 A_ASSERT((status) ||
3627 (pPacket->pBuffer == (A_NETBUF_DATA(skb) + HTC_HEADER_LEN)));
3628
3629 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx ar=0x%lx eid=%d, skb=0x%lx, data=0x%lx, len=0x%x status:%d",
3630 (unsigned long)ar, ept, (unsigned long)skb, (unsigned long)pPacket->pBuffer,
3631 pPacket->ActualLength, status));
3632 if (status) {
3633 if (status != A_ECANCELED) {
3634 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("RX ERR (%d) \n",status));
3635 }
3636 }
3637
3638 /* take lock to protect buffer counts
3639 * and adaptive power throughput state */
3640 AR6000_SPIN_LOCK(&ar->arLock, 0);
3641
3642 if (!status) {
3643 AR6000_STAT_INC(ar, rx_packets);
3644 ar->arNetStats.rx_bytes += pPacket->ActualLength;
3645#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
3646 aptcTR.bytesReceived += a_netbuf_to_len(skb);
3647 applyAPTCHeuristics(ar);
3648#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
3649
3650 A_NETBUF_PUT(skb, pPacket->ActualLength + HTC_HEADER_LEN);
3651 A_NETBUF_PULL(skb, HTC_HEADER_LEN);
3652
3653#ifdef DEBUG
3654 if (debugdriver >= 2) {
3655 ar6000_dump_skb(skb);
3656 }
3657#endif /* DEBUG */
3658 }
3659
3660 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3661
3662 skb->dev = ar->arNetDev;
3663 if (status) {
3664 AR6000_STAT_INC(ar, rx_errors);
3665 A_NETBUF_FREE(skb);
3666 } else if (ar->arWmiEnabled == true) {
3667 if (ept == ar->arControlEp) {
3668 /*
3669 * this is a wmi control msg
3670 */
3671#ifdef CONFIG_PM
3672 ar6000_check_wow_status(ar, skb, true);
3673#endif /* CONFIG_PM */
3674 wmi_control_rx(ar->arWmi, skb);
3675 } else {
3676 WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb);
3677 bool is_amsdu;
3678 u8 tid;
3679
3680 /*
3681 * This check can be removed if after a while we do not
3682 * see the warning. For now we leave it to ensure
3683 * we drop these frames accordingly in case the
3684 * target generates them for some reason. These
3685 * were used for an internal PAL but that's not
3686 * used or supported anymore. These frames should
3687 * not come up from the target.
3688 */
3689 if (WARN_ON(WMI_DATA_HDR_GET_DATA_TYPE(dhdr) ==
3690 WMI_DATA_HDR_DATA_TYPE_ACL)) {
3691 AR6000_STAT_INC(ar, rx_errors);
3692 A_NETBUF_FREE(skb);
3693 return;
3694 }
3695
3696#ifdef CONFIG_PM
3697 ar6000_check_wow_status(ar, NULL, false);
3698#endif /* CONFIG_PM */
3699 /*
3700 * this is a wmi data packet
3701 */
3702 // NWF
3703
3704 if (processDot11Hdr) {
3705 minHdrLen = sizeof(WMI_DATA_HDR) + sizeof(struct ieee80211_frame) + sizeof(ATH_LLC_SNAP_HDR);
3706 } else {
3707 minHdrLen = sizeof (WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) +
3708 sizeof(ATH_LLC_SNAP_HDR);
3709 }
3710
3711 /* In the case of AP mode we may receive NULL data frames
3712 * that do not have LLC hdr. They are 16 bytes in size.
3713 * Allow these frames in the AP mode.
3714 * ACL data frames don't follow ethernet frame bounds for
3715 * min length
3716 */
3717 if (ar->arNetworkType != AP_NETWORK &&
3718 ((pPacket->ActualLength < minHdrLen) ||
3719 (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)))
3720 {
3721 /*
3722 * packet is too short or too long
3723 */
3724 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("TOO SHORT or TOO LONG\n"));
3725 AR6000_STAT_INC(ar, rx_errors);
3726 AR6000_STAT_INC(ar, rx_length_errors);
3727 A_NETBUF_FREE(skb);
3728 } else {
3729 u16 seq_no;
3730 u8 meta_type;
3731
3732#if 0
3733 /* Access RSSI values here */
3734 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("RSSI %d\n",
3735 ((WMI_DATA_HDR *) A_NETBUF_DATA(skb))->rssi));
3736#endif
3737 /* Get the Power save state of the STA */
3738 if (ar->arNetworkType == AP_NETWORK) {
3739 sta_t *conn = NULL;
3740 u8 psState=0,prevPsState;
3741 ATH_MAC_HDR *datap=NULL;
3742 u16 offset;
3743
3744 meta_type = WMI_DATA_HDR_GET_META(dhdr);
3745
3746 psState = (((WMI_DATA_HDR *)A_NETBUF_DATA(skb))->info
3747 >> WMI_DATA_HDR_PS_SHIFT) & WMI_DATA_HDR_PS_MASK;
3748
3749 offset = sizeof(WMI_DATA_HDR);
3750
3751 switch (meta_type) {
3752 case 0:
3753 break;
3754 case WMI_META_VERSION_1:
3755 offset += sizeof(WMI_RX_META_V1);
3756 break;
3757 case WMI_META_VERSION_2:
3758 offset += sizeof(WMI_RX_META_V2);
3759 break;
3760 default:
3761 break;
3762 }
3763
3764 datap = (ATH_MAC_HDR *)(A_NETBUF_DATA(skb)+offset);
3765 conn = ieee80211_find_conn(ar, datap->srcMac);
3766
3767 if (conn) {
3768 /* if there is a change in PS state of the STA,
3769 * take appropriate steps.
3770 * 1. If Sleep-->Awake, flush the psq for the STA
3771 * Clear the PVB for the STA.
3772 * 2. If Awake-->Sleep, Starting queueing frames
3773 * the STA.
3774 */
3775 prevPsState = STA_IS_PWR_SLEEP(conn);
3776 if (psState) {
3777 STA_SET_PWR_SLEEP(conn);
3778 } else {
3779 STA_CLR_PWR_SLEEP(conn);
3780 }
3781
3782 if (prevPsState ^ STA_IS_PWR_SLEEP(conn)) {
3783
3784 if (!STA_IS_PWR_SLEEP(conn)) {
3785
3786 A_MUTEX_LOCK(&conn->psqLock);
3787 while (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) {
3788 struct sk_buff *skb=NULL;
3789
3790 skb = A_NETBUF_DEQUEUE(&conn->psq);
3791 A_MUTEX_UNLOCK(&conn->psqLock);
3792 ar6000_data_tx(skb,ar->arNetDev);
3793 A_MUTEX_LOCK(&conn->psqLock);
3794 }
3795 A_MUTEX_UNLOCK(&conn->psqLock);
3796 /* Clear the PVB for this STA */
3797 wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
3798 }
3799 }
3800 } else {
3801 /* This frame is from a STA that is not associated*/
3802 A_ASSERT(false);
3803 }
3804
3805 /* Drop NULL data frames here */
3806 if((pPacket->ActualLength < minHdrLen) ||
3807 (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)) {
3808 A_NETBUF_FREE(skb);
3809 goto rx_done;
3810 }
3811 }
3812
3813 is_amsdu = WMI_DATA_HDR_IS_AMSDU(dhdr) ? true : false;
3814 tid = WMI_DATA_HDR_GET_UP(dhdr);
3815 seq_no = WMI_DATA_HDR_GET_SEQNO(dhdr);
3816 meta_type = WMI_DATA_HDR_GET_META(dhdr);
3817 containsDot11Hdr = WMI_DATA_HDR_GET_DOT11(dhdr);
3818
3819 wmi_data_hdr_remove(ar->arWmi, skb);
3820
3821 switch (meta_type) {
3822 case WMI_META_VERSION_1:
3823 {
3824 WMI_RX_META_V1 *pMeta = (WMI_RX_META_V1 *)A_NETBUF_DATA(skb);
3825 A_PRINTF("META %d %d %d %d %x\n", pMeta->status, pMeta->rix, pMeta->rssi, pMeta->channel, pMeta->flags);
3826 A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V1));
3827 break;
3828 }
3829 case WMI_META_VERSION_2:
3830 {
3831 WMI_RX_META_V2 *pMeta = (WMI_RX_META_V2 *)A_NETBUF_DATA(skb);
3832 if(pMeta->csumFlags & 0x1){
3833 skb->ip_summed=CHECKSUM_COMPLETE;
3834 skb->csum=(pMeta->csum);
3835 }
3836 A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V2));
3837 break;
3838 }
3839 default:
3840 break;
3841 }
3842
3843 A_ASSERT(status == 0);
3844
3845 /* NWF: print the 802.11 hdr bytes */
3846 if(containsDot11Hdr) {
3847 status = wmi_dot11_hdr_remove(ar->arWmi,skb);
3848 } else if(!is_amsdu) {
3849 status = wmi_dot3_2_dix(skb);
3850 }
3851
3852 if (status) {
3853 /* Drop frames that could not be processed (lack of memory, etc.) */
3854 A_NETBUF_FREE(skb);
3855 goto rx_done;
3856 }
3857
3858 if ((ar->arNetDev->flags & IFF_UP) == IFF_UP) {
3859 if (ar->arNetworkType == AP_NETWORK) {
3860 struct sk_buff *skb1 = NULL;
3861 ATH_MAC_HDR *datap;
3862
3863 datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
3864 if (IEEE80211_IS_MULTICAST(datap->dstMac)) {
3865 /* Bcast/Mcast frames should be sent to the OS
3866 * stack as well as on the air.
3867 */
3868 skb1 = skb_copy(skb,GFP_ATOMIC);
3869 } else {
3870 /* Search for a connected STA with dstMac as
3871 * the Mac address. If found send the frame to
3872 * it on the air else send the frame up the
3873 * stack
3874 */
3875 sta_t *conn = NULL;
3876 conn = ieee80211_find_conn(ar, datap->dstMac);
3877
3878 if (conn && ar->intra_bss) {
3879 skb1 = skb;
3880 skb = NULL;
3881 } else if(conn && !ar->intra_bss) {
3882 A_NETBUF_FREE(skb);
3883 skb = NULL;
3884 }
3885 }
3886 if (skb1) {
3887 ar6000_data_tx(skb1, ar->arNetDev);
3888 }
3889 }
3890 }
3891 aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no, is_amsdu, (void **)&skb);
3892 ar6000_deliver_frames_to_nw_stack((void *) ar->arNetDev, (void *)skb);
3893 }
3894 }
3895 } else {
3896 if (EPPING_ALIGNMENT_PAD > 0) {
3897 A_NETBUF_PULL(skb, EPPING_ALIGNMENT_PAD);
3898 }
3899 ar6000_deliver_frames_to_nw_stack((void *)ar->arNetDev, (void *)skb);
3900 }
3901
3902rx_done:
3903
3904 return;
3905}
3906
3907static void
3908ar6000_deliver_frames_to_nw_stack(void *dev, void *osbuf)
3909{
3910 struct sk_buff *skb = (struct sk_buff *)osbuf;
3911
3912 if(skb) {
3913 skb->dev = dev;
3914 if ((skb->dev->flags & IFF_UP) == IFF_UP) {
3915#ifdef CONFIG_PM
3916 ar6000_check_wow_status((struct ar6_softc *)ar6k_priv(dev), skb, false);
3917#endif /* CONFIG_PM */
3918 skb->protocol = eth_type_trans(skb, skb->dev);
3919 /*
3920 * If this routine is called on a ISR (Hard IRQ) or DSR (Soft IRQ)
3921 * or tasklet use the netif_rx to deliver the packet to the stack
3922 * netif_rx will queue the packet onto the receive queue and mark
3923 * the softirq thread has a pending action to complete. Kernel will
3924 * schedule the softIrq kernel thread after processing the DSR.
3925 *
3926 * If this routine is called on a process context, use netif_rx_ni
3927 * which will schedle the softIrq kernel thread after queuing the packet.
3928 */
3929 if (in_interrupt()) {
3930 netif_rx(skb);
3931 } else {
3932 netif_rx_ni(skb);
3933 }
3934 } else {
3935 A_NETBUF_FREE(skb);
3936 }
3937 }
3938}
3939
3940#if 0
3941static void
3942ar6000_deliver_frames_to_bt_stack(void *dev, void *osbuf)
3943{
3944 struct sk_buff *skb = (struct sk_buff *)osbuf;
3945
3946 if(skb) {
3947 skb->dev = dev;
3948 if ((skb->dev->flags & IFF_UP) == IFF_UP) {
3949 skb->protocol = htons(ETH_P_CONTROL);
3950 netif_rx(skb);
3951 } else {
3952 A_NETBUF_FREE(skb);
3953 }
3954 }
3955}
3956#endif
3957
3958static void
3959ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint)
3960{
3961 struct ar6_softc *ar = (struct ar6_softc *)Context;
3962 void *osBuf;
3963 int RxBuffers;
3964 int buffersToRefill;
3965 struct htc_packet *pPacket;
3966 struct htc_packet_queue queue;
3967
3968 buffersToRefill = (int)AR6000_MAX_RX_BUFFERS -
3969 HTCGetNumRecvBuffers(ar->arHtcTarget, Endpoint);
3970
3971 if (buffersToRefill <= 0) {
3972 /* fast return, nothing to fill */
3973 return;
3974 }
3975
3976 INIT_HTC_PACKET_QUEUE(&queue);
3977
3978 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx_refill: providing htc with %d buffers at eid=%d\n",
3979 buffersToRefill, Endpoint));
3980
3981 for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) {
3982 osBuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE);
3983 if (NULL == osBuf) {
3984 break;
3985 }
3986 /* the HTC packet wrapper is at the head of the reserved area
3987 * in the skb */
3988 pPacket = (struct htc_packet *)(A_NETBUF_HEAD(osBuf));
3989 /* set re-fill info */
3990 SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_BUFFER_SIZE,Endpoint);
3991 /* add to queue */
3992 HTC_PACKET_ENQUEUE(&queue,pPacket);
3993 }
3994
3995 if (!HTC_QUEUE_EMPTY(&queue)) {
3996 /* add packets */
3997 HTCAddReceivePktMultiple(ar->arHtcTarget, &queue);
3998 }
3999
4000}
4001
4002 /* clean up our amsdu buffer list */
4003static void ar6000_cleanup_amsdu_rxbufs(struct ar6_softc *ar)
4004{
4005 struct htc_packet *pPacket;
4006 void *osBuf;
4007
4008 /* empty AMSDU buffer queue and free OS bufs */
4009 while (true) {
4010
4011 AR6000_SPIN_LOCK(&ar->arLock, 0);
4012 pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue);
4013 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
4014
4015 if (NULL == pPacket) {
4016 break;
4017 }
4018
4019 osBuf = pPacket->pPktContext;
4020 if (NULL == osBuf) {
4021 A_ASSERT(false);
4022 break;
4023 }
4024
4025 A_NETBUF_FREE(osBuf);
4026 }
4027
4028}
4029
4030
4031 /* refill the amsdu buffer list */
4032static void ar6000_refill_amsdu_rxbufs(struct ar6_softc *ar, int Count)
4033{
4034 struct htc_packet *pPacket;
4035 void *osBuf;
4036
4037 while (Count > 0) {
4038 osBuf = A_NETBUF_ALLOC(AR6000_AMSDU_BUFFER_SIZE);
4039 if (NULL == osBuf) {
4040 break;
4041 }
4042 /* the HTC packet wrapper is at the head of the reserved area
4043 * in the skb */
4044 pPacket = (struct htc_packet *)(A_NETBUF_HEAD(osBuf));
4045 /* set re-fill info */
4046 SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_AMSDU_BUFFER_SIZE,0);
4047
4048 AR6000_SPIN_LOCK(&ar->arLock, 0);
4049 /* put it in the list */
4050 HTC_PACKET_ENQUEUE(&ar->amsdu_rx_buffer_queue,pPacket);
4051 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
4052 Count--;
4053 }
4054
4055}
4056
4057 /* callback to allocate a large receive buffer for a pending packet. This function is called when
4058 * an HTC packet arrives whose length exceeds a threshold value
4059 *
4060 * We use a pre-allocated list of buffers of maximum AMSDU size (4K). Under linux it is more optimal to
4061 * keep the allocation size the same to optimize cached-slab allocations.
4062 *
4063 * */
4064static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length)
4065{
4066 struct htc_packet *pPacket = NULL;
4067 struct ar6_softc *ar = (struct ar6_softc *)Context;
4068 int refillCount = 0;
4069
4070 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_alloc_amsdu_rxbuf: eid=%d, Length:%d\n",Endpoint,Length));
4071
4072 do {
4073
4074 if (Length <= AR6000_BUFFER_SIZE) {
4075 /* shouldn't be getting called on normal sized packets */
4076 A_ASSERT(false);
4077 break;
4078 }
4079
4080 if (Length > AR6000_AMSDU_BUFFER_SIZE) {
4081 A_ASSERT(false);
4082 break;
4083 }
4084
4085 AR6000_SPIN_LOCK(&ar->arLock, 0);
4086 /* allocate a packet from the list */
4087 pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue);
4088 /* see if we need to refill again */
4089 refillCount = AR6000_MAX_AMSDU_RX_BUFFERS - HTC_PACKET_QUEUE_DEPTH(&ar->amsdu_rx_buffer_queue);
4090 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
4091
4092 if (NULL == pPacket) {
4093 break;
4094 }
4095 /* set actual endpoint ID */
4096 pPacket->Endpoint = Endpoint;
4097
4098 } while (false);
4099
4100 if (refillCount >= AR6000_AMSDU_REFILL_THRESHOLD) {
4101 ar6000_refill_amsdu_rxbufs(ar,refillCount);
4102 }
4103
4104 return pPacket;
4105}
4106
4107static void
4108ar6000_set_multicast_list(struct net_device *dev)
4109{
4110 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000: Multicast filter not supported\n"));
4111}
4112
4113static struct net_device_stats *
4114ar6000_get_stats(struct net_device *dev)
4115{
4116 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
4117 return &ar->arNetStats;
4118}
4119
4120void
4121ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver)
4122{
4123 struct ar6_softc *ar = (struct ar6_softc *)devt;
4124 struct net_device *dev = ar->arNetDev;
4125
4126 memcpy(dev->dev_addr, datap, AR6000_ETH_ADDR_LEN);
4127 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
4128 dev->dev_addr[0], dev->dev_addr[1],
4129 dev->dev_addr[2], dev->dev_addr[3],
4130 dev->dev_addr[4], dev->dev_addr[5]));
4131
4132 ar->arPhyCapability = phyCap;
4133 ar->arVersion.wlan_ver = sw_ver;
4134 ar->arVersion.abi_ver = abi_ver;
4135
4136 snprintf(ar->wdev->wiphy->fw_version, sizeof(ar->wdev->wiphy->fw_version),
4137 "%u:%u:%u:%u",
4138 (ar->arVersion.wlan_ver & 0xf0000000) >> 28,
4139 (ar->arVersion.wlan_ver & 0x0f000000) >> 24,
4140 (ar->arVersion.wlan_ver & 0x00ff0000) >> 16,
4141 (ar->arVersion.wlan_ver & 0x0000ffff));
4142
4143 /* Indicate to the waiting thread that the ready event was received */
4144 ar->arWmiReady = true;
4145 wake_up(&arEvent);
4146}
4147
4148void ar6000_install_static_wep_keys(struct ar6_softc *ar)
4149{
4150 u8 index;
4151 u8 keyUsage;
4152
4153 for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
4154 if (ar->arWepKeyList[index].arKeyLen) {
4155 keyUsage = GROUP_USAGE;
4156 if (index == ar->arDefTxKeyIndex) {
4157 keyUsage |= TX_USAGE;
4158 }
4159 wmi_addKey_cmd(ar->arWmi,
4160 index,
4161 WEP_CRYPT,
4162 keyUsage,
4163 ar->arWepKeyList[index].arKeyLen,
4164 NULL,
4165 ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL,
4166 NO_SYNC_WMIFLAG);
4167 }
4168 }
4169}
4170
4171void
4172add_new_sta(struct ar6_softc *ar, u8 *mac, u16 aid, u8 *wpaie,
4173 u8 ielen, u8 keymgmt, u8 ucipher, u8 auth)
4174{
4175 u8 free_slot=aid-1;
4176
4177 memcpy(ar->sta_list[free_slot].mac, mac, ATH_MAC_LEN);
4178 memcpy(ar->sta_list[free_slot].wpa_ie, wpaie, ielen);
4179 ar->sta_list[free_slot].aid = aid;
4180 ar->sta_list[free_slot].keymgmt = keymgmt;
4181 ar->sta_list[free_slot].ucipher = ucipher;
4182 ar->sta_list[free_slot].auth = auth;
4183 ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
4184 ar->arAPStats.sta[free_slot].aid = aid;
4185}
4186
4187void
4188ar6000_connect_event(struct ar6_softc *ar, u16 channel, u8 *bssid,
4189 u16 listenInterval, u16 beaconInterval,
4190 NETWORK_TYPE networkType, u8 beaconIeLen,
4191 u8 assocReqLen, u8 assocRespLen,
4192 u8 *assocInfo)
4193{
4194 union iwreq_data wrqu;
4195 int i, beacon_ie_pos, assoc_resp_ie_pos, assoc_req_ie_pos;
4196 static const char *tag1 = "ASSOCINFO(ReqIEs=";
4197 static const char *tag2 = "ASSOCRESPIE=";
4198 static const char *beaconIetag = "BEACONIE=";
4199 char buf[WMI_CONTROL_MSG_MAX_LEN * 2 + strlen(tag1) + 1];
4200 char *pos;
4201 u8 key_op_ctrl;
4202 unsigned long flags;
4203 struct ieee80211req_key *ik;
4204 CRYPTO_TYPE keyType = NONE_CRYPT;
4205
4206 if(ar->arNetworkType & AP_NETWORK) {
4207 struct net_device *dev = ar->arNetDev;
4208 if(memcmp(dev->dev_addr, bssid, ATH_MAC_LEN)==0) {
4209 ar->arACS = channel;
4210 ik = &ar->ap_mode_bkey;
4211
4212 switch(ar->arAuthMode) {
4213 case NONE_AUTH:
4214 if(ar->arPairwiseCrypto == WEP_CRYPT) {
4215 ar6000_install_static_wep_keys(ar);
4216 }
4217#ifdef WAPI_ENABLE
4218 else if(ar->arPairwiseCrypto == WAPI_CRYPT) {
4219 ap_set_wapi_key(ar, ik);
4220 }
4221#endif
4222 break;
4223 case WPA_PSK_AUTH:
4224 case WPA2_PSK_AUTH:
4225 case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
4226 switch (ik->ik_type) {
4227 case IEEE80211_CIPHER_TKIP:
4228 keyType = TKIP_CRYPT;
4229 break;
4230 case IEEE80211_CIPHER_AES_CCM:
4231 keyType = AES_CRYPT;
4232 break;
4233 default:
4234 goto skip_key;
4235 }
4236 wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, GROUP_USAGE,
4237 ik->ik_keylen, (u8 *)&ik->ik_keyrsc,
4238 ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
4239 SYNC_BOTH_WMIFLAG);
4240
4241 break;
4242 }
4243skip_key:
4244 ar->arConnected = true;
4245 return;
4246 }
4247
4248 A_PRINTF("NEW STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n "
4249 " AID=%d \n", bssid[0], bssid[1], bssid[2],
4250 bssid[3], bssid[4], bssid[5], channel);
4251 switch ((listenInterval>>8)&0xFF) {
4252 case OPEN_AUTH:
4253 A_PRINTF("AUTH: OPEN\n");
4254 break;
4255 case SHARED_AUTH:
4256 A_PRINTF("AUTH: SHARED\n");
4257 break;
4258 default:
4259 A_PRINTF("AUTH: Unknown\n");
4260 break;
4261 }
4262 switch (listenInterval&0xFF) {
4263 case WPA_PSK_AUTH:
4264 A_PRINTF("KeyMgmt: WPA-PSK\n");
4265 break;
4266 case WPA2_PSK_AUTH:
4267 A_PRINTF("KeyMgmt: WPA2-PSK\n");
4268 break;
4269 default:
4270 A_PRINTF("KeyMgmt: NONE\n");
4271 break;
4272 }
4273 switch (beaconInterval) {
4274 case AES_CRYPT:
4275 A_PRINTF("Cipher: AES\n");
4276 break;
4277 case TKIP_CRYPT:
4278 A_PRINTF("Cipher: TKIP\n");
4279 break;
4280 case WEP_CRYPT:
4281 A_PRINTF("Cipher: WEP\n");
4282 break;
4283#ifdef WAPI_ENABLE
4284 case WAPI_CRYPT:
4285 A_PRINTF("Cipher: WAPI\n");
4286 break;
4287#endif
4288 default:
4289 A_PRINTF("Cipher: NONE\n");
4290 break;
4291 }
4292
4293 add_new_sta(ar, bssid, channel /*aid*/,
4294 assocInfo /* WPA IE */, assocRespLen /* IE len */,
4295 listenInterval&0xFF /* Keymgmt */, beaconInterval /* cipher */,
4296 (listenInterval>>8)&0xFF /* auth alg */);
4297
4298 /* Send event to application */
4299 A_MEMZERO(&wrqu, sizeof(wrqu));
4300 memcpy(wrqu.addr.sa_data, bssid, ATH_MAC_LEN);
4301 wireless_send_event(ar->arNetDev, IWEVREGISTERED, &wrqu, NULL);
4302 /* In case the queue is stopped when we switch modes, this will
4303 * wake it up
4304 */
4305 netif_wake_queue(ar->arNetDev);
4306 return;
4307 }
4308
4309 ar6k_cfg80211_connect_event(ar, channel, bssid,
4310 listenInterval, beaconInterval,
4311 networkType, beaconIeLen,
4312 assocReqLen, assocRespLen,
4313 assocInfo);
4314
4315 memcpy(ar->arBssid, bssid, sizeof(ar->arBssid));
4316 ar->arBssChannel = channel;
4317
4318 A_PRINTF("AR6000 connected event on freq %d ", channel);
4319 A_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
4320 " listenInterval=%d, beaconInterval = %d, beaconIeLen = %d assocReqLen=%d"
4321 " assocRespLen =%d\n",
4322 bssid[0], bssid[1], bssid[2],
4323 bssid[3], bssid[4], bssid[5],
4324 listenInterval, beaconInterval,
4325 beaconIeLen, assocReqLen, assocRespLen);
4326 if (networkType & ADHOC_NETWORK) {
4327 if (networkType & ADHOC_CREATOR) {
4328 A_PRINTF("Network: Adhoc (Creator)\n");
4329 } else {
4330 A_PRINTF("Network: Adhoc (Joiner)\n");
4331 }
4332 } else {
4333 A_PRINTF("Network: Infrastructure\n");
4334 }
4335
4336 if ((ar->arNetworkType == INFRA_NETWORK)) {
4337 wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB);
4338 }
4339
4340 if (beaconIeLen && (sizeof(buf) > (9 + beaconIeLen * 2))) {
4341 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nBeaconIEs= "));
4342
4343 beacon_ie_pos = 0;
4344 A_MEMZERO(buf, sizeof(buf));
4345 sprintf(buf, "%s", beaconIetag);
4346 pos = buf + 9;
4347 for (i = beacon_ie_pos; i < beacon_ie_pos + beaconIeLen; i++) {
4348 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4349 sprintf(pos, "%2.2x", assocInfo[i]);
4350 pos += 2;
4351 }
4352 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4353
4354 A_MEMZERO(&wrqu, sizeof(wrqu));
4355 wrqu.data.length = strlen(buf);
4356 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4357 }
4358
4359 if (assocRespLen && (sizeof(buf) > (12 + (assocRespLen * 2))))
4360 {
4361 assoc_resp_ie_pos = beaconIeLen + assocReqLen +
4362 sizeof(u16) + /* capinfo*/
4363 sizeof(u16) + /* status Code */
4364 sizeof(u16) ; /* associd */
4365 A_MEMZERO(buf, sizeof(buf));
4366 sprintf(buf, "%s", tag2);
4367 pos = buf + 12;
4368 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocRespIEs= "));
4369 /*
4370 * The Association Response Frame w.o. the WLAN header is delivered to
4371 * the host, so skip over to the IEs
4372 */
4373 for (i = assoc_resp_ie_pos; i < assoc_resp_ie_pos + assocRespLen - 6; i++)
4374 {
4375 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4376 sprintf(pos, "%2.2x", assocInfo[i]);
4377 pos += 2;
4378 }
4379 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4380
4381 A_MEMZERO(&wrqu, sizeof(wrqu));
4382 wrqu.data.length = strlen(buf);
4383 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4384 }
4385
4386 if (assocReqLen && (sizeof(buf) > (17 + (assocReqLen * 2)))) {
4387 /*
4388 * assoc Request includes capability and listen interval. Skip these.
4389 */
4390 assoc_req_ie_pos = beaconIeLen +
4391 sizeof(u16) + /* capinfo*/
4392 sizeof(u16); /* listen interval */
4393
4394 A_MEMZERO(buf, sizeof(buf));
4395 sprintf(buf, "%s", tag1);
4396 pos = buf + 17;
4397 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("AssocReqIEs= "));
4398 for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen - 4; i++) {
4399 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4400 sprintf(pos, "%2.2x", assocInfo[i]);
4401 pos += 2;
4402 }
4403 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4404
4405 A_MEMZERO(&wrqu, sizeof(wrqu));
4406 wrqu.data.length = strlen(buf);
4407 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4408 }
4409
4410 if (ar->user_savedkeys_stat == USER_SAVEDKEYS_STAT_RUN &&
4411 ar->user_saved_keys.keyOk == true)
4412 {
4413 key_op_ctrl = KEY_OP_VALID_MASK & ~KEY_OP_INIT_TSC;
4414
4415 if (ar->user_key_ctrl & AR6000_USER_SETKEYS_RSC_UNCHANGED) {
4416 key_op_ctrl &= ~KEY_OP_INIT_RSC;
4417 } else {
4418 key_op_ctrl |= KEY_OP_INIT_RSC;
4419 }
4420 ar6000_reinstall_keys(ar, key_op_ctrl);
4421 }
4422
4423 netif_wake_queue(ar->arNetDev);
4424
4425 /* Update connect & link status atomically */
4426 spin_lock_irqsave(&ar->arLock, flags);
4427 ar->arConnected = true;
4428 ar->arConnectPending = false;
4429 netif_carrier_on(ar->arNetDev);
4430 spin_unlock_irqrestore(&ar->arLock, flags);
4431 /* reset the rx aggr state */
4432 aggr_reset_state(ar->aggr_cntxt);
4433 reconnect_flag = 0;
4434
4435 A_MEMZERO(&wrqu, sizeof(wrqu));
4436 memcpy(wrqu.addr.sa_data, bssid, IEEE80211_ADDR_LEN);
4437 wrqu.addr.sa_family = ARPHRD_ETHER;
4438 wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
4439 if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable) {
4440 A_MEMZERO(ar->arNodeMap, sizeof(ar->arNodeMap));
4441 ar->arNodeNum = 0;
4442 ar->arNexEpId = ENDPOINT_2;
4443 }
4444 if (!ar->arUserBssFilter) {
4445 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4446 }
4447
4448}
4449
4450void ar6000_set_numdataendpts(struct ar6_softc *ar, u32 num)
4451{
4452 A_ASSERT(num <= (HTC_MAILBOX_NUM_MAX - 1));
4453 ar->arNumDataEndPts = num;
4454}
4455
4456void
4457sta_cleanup(struct ar6_softc *ar, u8 i)
4458{
4459 struct sk_buff *skb;
4460
4461 /* empty the queued pkts in the PS queue if any */
4462 A_MUTEX_LOCK(&ar->sta_list[i].psqLock);
4463 while (!A_NETBUF_QUEUE_EMPTY(&ar->sta_list[i].psq)) {
4464 skb = A_NETBUF_DEQUEUE(&ar->sta_list[i].psq);
4465 A_NETBUF_FREE(skb);
4466 }
4467 A_MUTEX_UNLOCK(&ar->sta_list[i].psqLock);
4468
4469 /* Zero out the state fields */
4470 A_MEMZERO(&ar->arAPStats.sta[ar->sta_list[i].aid-1], sizeof(WMI_PER_STA_STAT));
4471 A_MEMZERO(&ar->sta_list[i].mac, ATH_MAC_LEN);
4472 A_MEMZERO(&ar->sta_list[i].wpa_ie, IEEE80211_MAX_IE);
4473 ar->sta_list[i].aid = 0;
4474 ar->sta_list[i].flags = 0;
4475
4476 ar->sta_list_index = ar->sta_list_index & ~(1 << i);
4477
4478}
4479
4480u8 remove_sta(struct ar6_softc *ar, u8 *mac, u16 reason)
4481{
4482 u8 i, removed=0;
4483
4484 if(IS_MAC_NULL(mac)) {
4485 return removed;
4486 }
4487
4488 if(IS_MAC_BCAST(mac)) {
4489 A_PRINTF("DEL ALL STA\n");
4490 for(i=0; i < AP_MAX_NUM_STA; i++) {
4491 if(!IS_MAC_NULL(ar->sta_list[i].mac)) {
4492 sta_cleanup(ar, i);
4493 removed = 1;
4494 }
4495 }
4496 } else {
4497 for(i=0; i < AP_MAX_NUM_STA; i++) {
4498 if(memcmp(ar->sta_list[i].mac, mac, ATH_MAC_LEN)==0) {
4499 A_PRINTF("DEL STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
4500 " aid=%d REASON=%d\n", mac[0], mac[1], mac[2],
4501 mac[3], mac[4], mac[5], ar->sta_list[i].aid, reason);
4502
4503 sta_cleanup(ar, i);
4504 removed = 1;
4505 break;
4506 }
4507 }
4508 }
4509 return removed;
4510}
4511
4512void
4513ar6000_disconnect_event(struct ar6_softc *ar, u8 reason, u8 *bssid,
4514 u8 assocRespLen, u8 *assocInfo, u16 protocolReasonStatus)
4515{
4516 u8 i;
4517 unsigned long flags;
4518 union iwreq_data wrqu;
4519
4520 if(ar->arNetworkType & AP_NETWORK) {
4521 union iwreq_data wrqu;
4522 struct sk_buff *skb;
4523
4524 if(!remove_sta(ar, bssid, protocolReasonStatus)) {
4525 return;
4526 }
4527
4528 /* If there are no more associated STAs, empty the mcast PS q */
4529 if (ar->sta_list_index == 0) {
4530 A_MUTEX_LOCK(&ar->mcastpsqLock);
4531 while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
4532 skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
4533 A_NETBUF_FREE(skb);
4534 }
4535 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
4536
4537 /* Clear the LSB of the BitMapCtl field of the TIM IE */
4538 if (ar->arWmiReady) {
4539 wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
4540 }
4541 }
4542
4543 if(!IS_MAC_BCAST(bssid)) {
4544 /* Send event to application */
4545 A_MEMZERO(&wrqu, sizeof(wrqu));
4546 memcpy(wrqu.addr.sa_data, bssid, ATH_MAC_LEN);
4547 wireless_send_event(ar->arNetDev, IWEVEXPIRED, &wrqu, NULL);
4548 }
4549
4550 ar->arConnected = false;
4551 return;
4552 }
4553
4554 ar6k_cfg80211_disconnect_event(ar, reason, bssid,
4555 assocRespLen, assocInfo,
4556 protocolReasonStatus);
4557
4558 /* Send disconnect event to supplicant */
4559 A_MEMZERO(&wrqu, sizeof(wrqu));
4560 wrqu.addr.sa_family = ARPHRD_ETHER;
4561 wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
4562
4563 /* it is necessary to clear the host-side rx aggregation state */
4564 aggr_reset_state(ar->aggr_cntxt);
4565
4566 A_UNTIMEOUT(&ar->disconnect_timer);
4567
4568 A_PRINTF("AR6000 disconnected");
4569 if (bssid[0] || bssid[1] || bssid[2] || bssid[3] || bssid[4] || bssid[5]) {
4570 A_PRINTF(" from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
4571 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
4572 }
4573
4574 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nDisconnect Reason is %d", reason));
4575 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nProtocol Reason/Status Code is %d", protocolReasonStatus));
4576 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocResp Frame = %s",
4577 assocRespLen ? " " : "NULL"));
4578 for (i = 0; i < assocRespLen; i++) {
4579 if (!(i % 0x10)) {
4580 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4581 }
4582 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4583 }
4584 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4585 /*
4586 * If the event is due to disconnect cmd from the host, only they the target
4587 * would stop trying to connect. Under any other condition, target would
4588 * keep trying to connect.
4589 *
4590 */
4591 if( reason == DISCONNECT_CMD)
4592 {
4593 if ((!ar->arUserBssFilter) && (ar->arWmiReady)) {
4594 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4595 }
4596 } else {
4597 ar->arConnectPending = true;
4598 if (((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x11)) ||
4599 ((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x0) && (reconnect_flag == 1))) {
4600 ar->arConnected = true;
4601 return;
4602 }
4603 }
4604
4605 if ((reason == NO_NETWORK_AVAIL) && (ar->arWmiReady))
4606 {
4607 bss_t *pWmiSsidnode = NULL;
4608
4609 /* remove the current associated bssid node */
4610 wmi_free_node (ar->arWmi, bssid);
4611
4612 /*
4613 * In case any other same SSID nodes are present
4614 * remove it, since those nodes also not available now
4615 */
4616 do
4617 {
4618 /*
4619 * Find the nodes based on SSID and remove it
4620 * NOTE :: This case will not work out for Hidden-SSID
4621 */
4622 pWmiSsidnode = wmi_find_Ssidnode (ar->arWmi, ar->arSsid, ar->arSsidLen, false, true);
4623
4624 if (pWmiSsidnode)
4625 {
4626 wmi_free_node (ar->arWmi, pWmiSsidnode->ni_macaddr);
4627 }
4628
4629 } while (pWmiSsidnode);
4630 }
4631
4632 /* Update connect & link status atomically */
4633 spin_lock_irqsave(&ar->arLock, flags);
4634 ar->arConnected = false;
4635 netif_carrier_off(ar->arNetDev);
4636 spin_unlock_irqrestore(&ar->arLock, flags);
4637
4638 if( (reason != CSERV_DISCONNECT) || (reconnect_flag != 1) ) {
4639 reconnect_flag = 0;
4640 }
4641
4642 if (reason != CSERV_DISCONNECT)
4643 {
4644 ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
4645 ar->user_key_ctrl = 0;
4646 }
4647
4648 netif_stop_queue(ar->arNetDev);
4649 A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
4650 ar->arBssChannel = 0;
4651 ar->arBeaconInterval = 0;
4652
4653 ar6000_TxDataCleanup(ar);
4654}
4655
4656void
4657ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode)
4658{
4659 A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode);
4660 ar->arRegCode = regCode;
4661}
4662
4663void
4664ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *evt)
4665{
4666 if(evt->status == 0) {
4667 aggr_recv_addba_req_evt(ar->aggr_cntxt, evt->tid, evt->st_seq_no, evt->win_sz);
4668 }
4669}
4670
4671void
4672ar6000_aggr_rcv_addba_resp_evt(struct ar6_softc *ar, WMI_ADDBA_RESP_EVENT *evt)
4673{
4674 A_PRINTF("ADDBA RESP. tid %d status %d, sz %d\n", evt->tid, evt->status, evt->amsdu_sz);
4675 if(evt->status == 0) {
4676 }
4677}
4678
4679void
4680ar6000_aggr_rcv_delba_req_evt(struct ar6_softc *ar, WMI_DELBA_EVENT *evt)
4681{
4682 aggr_recv_delba_req_evt(ar->aggr_cntxt, evt->tid);
4683}
4684
4685void register_pal_cb(ar6k_pal_config_t *palConfig_p)
4686{
4687 ar6k_pal_config_g = *palConfig_p;
4688}
4689
4690void
4691ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd)
4692{
4693 void *osbuf = NULL;
4694 s8 i;
4695 u8 size, *buf;
4696 int ret = 0;
4697
4698 size = cmd->evt_buf_sz + 4;
4699 osbuf = A_NETBUF_ALLOC(size);
4700 if (osbuf == NULL) {
4701 ret = A_NO_MEMORY;
4702 A_PRINTF("Error in allocating netbuf \n");
4703 return;
4704 }
4705
4706 A_NETBUF_PUT(osbuf, size);
4707 buf = (u8 *)A_NETBUF_DATA(osbuf);
4708 /* First 2-bytes carry HCI event/ACL data type
4709 * the next 2 are free
4710 */
4711 *((short *)buf) = WMI_HCI_EVENT_EVENTID;
4712 buf += sizeof(int);
4713 memcpy(buf, cmd->buf, cmd->evt_buf_sz);
4714
4715 ar6000_deliver_frames_to_nw_stack(ar->arNetDev, osbuf);
4716 if(loghci) {
4717 A_PRINTF_LOG("HCI Event From PAL <-- \n");
4718 for(i = 0; i < cmd->evt_buf_sz; i++) {
4719 A_PRINTF_LOG("0x%02x ", cmd->buf[i]);
4720 if((i % 10) == 0) {
4721 A_PRINTF_LOG("\n");
4722 }
4723 }
4724 A_PRINTF_LOG("\n");
4725 A_PRINTF_LOG("==================================\n");
4726 }
4727}
4728
4729void
4730ar6000_neighborReport_event(struct ar6_softc *ar, int numAps, WMI_NEIGHBOR_INFO *info)
4731{
4732#if WIRELESS_EXT >= 18
4733 struct iw_pmkid_cand *pmkcand;
4734#else /* WIRELESS_EXT >= 18 */
4735 static const char *tag = "PRE-AUTH";
4736 char buf[128];
4737#endif /* WIRELESS_EXT >= 18 */
4738
4739 union iwreq_data wrqu;
4740 int i;
4741
4742 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("AR6000 Neighbor Report Event\n"));
4743 for (i=0; i < numAps; info++, i++) {
4744 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
4745 info->bssid[0], info->bssid[1], info->bssid[2],
4746 info->bssid[3], info->bssid[4], info->bssid[5]));
4747 if (info->bssFlags & WMI_PREAUTH_CAPABLE_BSS) {
4748 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("preauth-cap"));
4749 }
4750 if (info->bssFlags & WMI_PMKID_VALID_BSS) {
4751 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,(" pmkid-valid\n"));
4752 continue; /* we skip bss if the pmkid is already valid */
4753 }
4754 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("\n"));
4755 A_MEMZERO(&wrqu, sizeof(wrqu));
4756#if WIRELESS_EXT >= 18
4757 pmkcand = A_MALLOC_NOWAIT(sizeof(struct iw_pmkid_cand));
4758 A_MEMZERO(pmkcand, sizeof(struct iw_pmkid_cand));
4759 pmkcand->index = i;
4760 pmkcand->flags = info->bssFlags;
4761 memcpy(pmkcand->bssid.sa_data, info->bssid, ATH_MAC_LEN);
4762 wrqu.data.length = sizeof(struct iw_pmkid_cand);
4763 wireless_send_event(ar->arNetDev, IWEVPMKIDCAND, &wrqu, (char *)pmkcand);
4764 kfree(pmkcand);
4765#else /* WIRELESS_EXT >= 18 */
4766 snprintf(buf, sizeof(buf), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
4767 tag,
4768 info->bssid[0], info->bssid[1], info->bssid[2],
4769 info->bssid[3], info->bssid[4], info->bssid[5],
4770 i, info->bssFlags);
4771 wrqu.data.length = strlen(buf);
4772 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4773#endif /* WIRELESS_EXT >= 18 */
4774 }
4775}
4776
4777void
4778ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast)
4779{
4780 static const char *tag = "MLME-MICHAELMICFAILURE.indication";
4781 char buf[128];
4782 union iwreq_data wrqu;
4783
4784 /*
4785 * For AP case, keyid will have aid of STA which sent pkt with
4786 * MIC error. Use this aid to get MAC & send it to hostapd.
4787 */
4788 if (ar->arNetworkType == AP_NETWORK) {
4789 sta_t *s = ieee80211_find_conn_for_aid(ar, (keyid >> 2));
4790 if(!s){
4791 A_PRINTF("AP TKIP MIC error received from Invalid aid / STA not found =%d\n", keyid);
4792 return;
4793 }
4794 A_PRINTF("AP TKIP MIC error received from aid=%d\n", keyid);
4795 snprintf(buf,sizeof(buf), "%s addr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
4796 tag, s->mac[0],s->mac[1],s->mac[2],s->mac[3],s->mac[4],s->mac[5]);
4797 } else {
4798
4799 ar6k_cfg80211_tkip_micerr_event(ar, keyid, ismcast);
4800
4801 A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n",
4802 keyid & 0x3, ismcast ? "multi": "uni");
4803 snprintf(buf, sizeof(buf), "%s(keyid=%d %sicast)", tag, keyid & 0x3,
4804 ismcast ? "mult" : "un");
4805 }
4806
4807 memset(&wrqu, 0, sizeof(wrqu));
4808 wrqu.data.length = strlen(buf);
4809 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4810}
4811
4812void
4813ar6000_scanComplete_event(struct ar6_softc *ar, int status)
4814{
4815
4816 ar6k_cfg80211_scanComplete_event(ar, status);
4817
4818 if (!ar->arUserBssFilter) {
4819 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4820 }
4821 if (ar->scan_triggered) {
4822 if (status== 0) {
4823 union iwreq_data wrqu;
4824 A_MEMZERO(&wrqu, sizeof(wrqu));
4825 wireless_send_event(ar->arNetDev, SIOCGIWSCAN, &wrqu, NULL);
4826 }
4827 ar->scan_triggered = 0;
4828 }
4829
4830 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,( "AR6000 scan complete: %d\n", status));
4831}
4832
4833void
4834ar6000_targetStats_event(struct ar6_softc *ar, u8 *ptr, u32 len)
4835{
4836 u8 ac;
4837
4838 if(ar->arNetworkType == AP_NETWORK) {
4839 WMI_AP_MODE_STAT *p = (WMI_AP_MODE_STAT *)ptr;
4840 WMI_AP_MODE_STAT *ap = &ar->arAPStats;
4841
4842 if (len < sizeof(*p)) {
4843 return;
4844 }
4845
4846 for(ac=0;ac<AP_MAX_NUM_STA;ac++) {
4847 ap->sta[ac].tx_bytes += p->sta[ac].tx_bytes;
4848 ap->sta[ac].tx_pkts += p->sta[ac].tx_pkts;
4849 ap->sta[ac].tx_error += p->sta[ac].tx_error;
4850 ap->sta[ac].tx_discard += p->sta[ac].tx_discard;
4851 ap->sta[ac].rx_bytes += p->sta[ac].rx_bytes;
4852 ap->sta[ac].rx_pkts += p->sta[ac].rx_pkts;
4853 ap->sta[ac].rx_error += p->sta[ac].rx_error;
4854 ap->sta[ac].rx_discard += p->sta[ac].rx_discard;
4855 }
4856
4857 } else {
4858 WMI_TARGET_STATS *pTarget = (WMI_TARGET_STATS *)ptr;
4859 TARGET_STATS *pStats = &ar->arTargetStats;
4860
4861 if (len < sizeof(*pTarget)) {
4862 return;
4863 }
4864
4865 // Update the RSSI of the connected bss.
4866 if (ar->arConnected) {
4867 bss_t *pConnBss = NULL;
4868
4869 pConnBss = wmi_find_node(ar->arWmi,ar->arBssid);
4870 if (pConnBss)
4871 {
4872 pConnBss->ni_rssi = pTarget->cservStats.cs_aveBeacon_rssi;
4873 pConnBss->ni_snr = pTarget->cservStats.cs_aveBeacon_snr;
4874 wmi_node_return(ar->arWmi, pConnBss);
4875 }
4876 }
4877
4878 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 updating target stats\n"));
4879 pStats->tx_packets += pTarget->txrxStats.tx_stats.tx_packets;
4880 pStats->tx_bytes += pTarget->txrxStats.tx_stats.tx_bytes;
4881 pStats->tx_unicast_pkts += pTarget->txrxStats.tx_stats.tx_unicast_pkts;
4882 pStats->tx_unicast_bytes += pTarget->txrxStats.tx_stats.tx_unicast_bytes;
4883 pStats->tx_multicast_pkts += pTarget->txrxStats.tx_stats.tx_multicast_pkts;
4884 pStats->tx_multicast_bytes += pTarget->txrxStats.tx_stats.tx_multicast_bytes;
4885 pStats->tx_broadcast_pkts += pTarget->txrxStats.tx_stats.tx_broadcast_pkts;
4886 pStats->tx_broadcast_bytes += pTarget->txrxStats.tx_stats.tx_broadcast_bytes;
4887 pStats->tx_rts_success_cnt += pTarget->txrxStats.tx_stats.tx_rts_success_cnt;
4888 for(ac = 0; ac < WMM_NUM_AC; ac++)
4889 pStats->tx_packet_per_ac[ac] += pTarget->txrxStats.tx_stats.tx_packet_per_ac[ac];
4890 pStats->tx_errors += pTarget->txrxStats.tx_stats.tx_errors;
4891 pStats->tx_failed_cnt += pTarget->txrxStats.tx_stats.tx_failed_cnt;
4892 pStats->tx_retry_cnt += pTarget->txrxStats.tx_stats.tx_retry_cnt;
4893 pStats->tx_mult_retry_cnt += pTarget->txrxStats.tx_stats.tx_mult_retry_cnt;
4894 pStats->tx_rts_fail_cnt += pTarget->txrxStats.tx_stats.tx_rts_fail_cnt;
4895 pStats->tx_unicast_rate = wmi_get_rate(pTarget->txrxStats.tx_stats.tx_unicast_rate);
4896
4897 pStats->rx_packets += pTarget->txrxStats.rx_stats.rx_packets;
4898 pStats->rx_bytes += pTarget->txrxStats.rx_stats.rx_bytes;
4899 pStats->rx_unicast_pkts += pTarget->txrxStats.rx_stats.rx_unicast_pkts;
4900 pStats->rx_unicast_bytes += pTarget->txrxStats.rx_stats.rx_unicast_bytes;
4901 pStats->rx_multicast_pkts += pTarget->txrxStats.rx_stats.rx_multicast_pkts;
4902 pStats->rx_multicast_bytes += pTarget->txrxStats.rx_stats.rx_multicast_bytes;
4903 pStats->rx_broadcast_pkts += pTarget->txrxStats.rx_stats.rx_broadcast_pkts;
4904 pStats->rx_broadcast_bytes += pTarget->txrxStats.rx_stats.rx_broadcast_bytes;
4905 pStats->rx_fragment_pkt += pTarget->txrxStats.rx_stats.rx_fragment_pkt;
4906 pStats->rx_errors += pTarget->txrxStats.rx_stats.rx_errors;
4907 pStats->rx_crcerr += pTarget->txrxStats.rx_stats.rx_crcerr;
4908 pStats->rx_key_cache_miss += pTarget->txrxStats.rx_stats.rx_key_cache_miss;
4909 pStats->rx_decrypt_err += pTarget->txrxStats.rx_stats.rx_decrypt_err;
4910 pStats->rx_duplicate_frames += pTarget->txrxStats.rx_stats.rx_duplicate_frames;
4911 pStats->rx_unicast_rate = wmi_get_rate(pTarget->txrxStats.rx_stats.rx_unicast_rate);
4912
4913
4914 pStats->tkip_local_mic_failure
4915 += pTarget->txrxStats.tkipCcmpStats.tkip_local_mic_failure;
4916 pStats->tkip_counter_measures_invoked
4917 += pTarget->txrxStats.tkipCcmpStats.tkip_counter_measures_invoked;
4918 pStats->tkip_replays += pTarget->txrxStats.tkipCcmpStats.tkip_replays;
4919 pStats->tkip_format_errors += pTarget->txrxStats.tkipCcmpStats.tkip_format_errors;
4920 pStats->ccmp_format_errors += pTarget->txrxStats.tkipCcmpStats.ccmp_format_errors;
4921 pStats->ccmp_replays += pTarget->txrxStats.tkipCcmpStats.ccmp_replays;
4922
4923 pStats->power_save_failure_cnt += pTarget->pmStats.power_save_failure_cnt;
4924 pStats->noise_floor_calibation = pTarget->noise_floor_calibation;
4925
4926 pStats->cs_bmiss_cnt += pTarget->cservStats.cs_bmiss_cnt;
4927 pStats->cs_lowRssi_cnt += pTarget->cservStats.cs_lowRssi_cnt;
4928 pStats->cs_connect_cnt += pTarget->cservStats.cs_connect_cnt;
4929 pStats->cs_disconnect_cnt += pTarget->cservStats.cs_disconnect_cnt;
4930 pStats->cs_aveBeacon_snr = pTarget->cservStats.cs_aveBeacon_snr;
4931 pStats->cs_aveBeacon_rssi = pTarget->cservStats.cs_aveBeacon_rssi;
4932
4933 if (enablerssicompensation) {
4934 pStats->cs_aveBeacon_rssi =
4935 rssi_compensation_calc(ar, pStats->cs_aveBeacon_rssi);
4936 }
4937 pStats->cs_lastRoam_msec = pTarget->cservStats.cs_lastRoam_msec;
4938 pStats->cs_snr = pTarget->cservStats.cs_snr;
4939 pStats->cs_rssi = pTarget->cservStats.cs_rssi;
4940
4941 pStats->lq_val = pTarget->lqVal;
4942
4943 pStats->wow_num_pkts_dropped += pTarget->wowStats.wow_num_pkts_dropped;
4944 pStats->wow_num_host_pkt_wakeups += pTarget->wowStats.wow_num_host_pkt_wakeups;
4945 pStats->wow_num_host_event_wakeups += pTarget->wowStats.wow_num_host_event_wakeups;
4946 pStats->wow_num_events_discarded += pTarget->wowStats.wow_num_events_discarded;
4947 pStats->arp_received += pTarget->arpStats.arp_received;
4948 pStats->arp_matched += pTarget->arpStats.arp_matched;
4949 pStats->arp_replied += pTarget->arpStats.arp_replied;
4950
4951 if (ar->statsUpdatePending) {
4952 ar->statsUpdatePending = false;
4953 wake_up(&arEvent);
4954 }
4955 }
4956}
4957
4958void
4959ar6000_rssiThreshold_event(struct ar6_softc *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, s16 rssi)
4960{
4961 USER_RSSI_THOLD userRssiThold;
4962
4963 rssi = rssi + SIGNAL_QUALITY_NOISE_FLOOR;
4964
4965 if (enablerssicompensation) {
4966 rssi = rssi_compensation_calc(ar, rssi);
4967 }
4968
4969 /* Send an event to the app */
4970 userRssiThold.tag = ar->rssi_map[newThreshold].tag;
4971 userRssiThold.rssi = rssi;
4972 A_PRINTF("rssi Threshold range = %d tag = %d rssi = %d\n", newThreshold,
4973 userRssiThold.tag, userRssiThold.rssi);
4974}
4975
4976
4977void
4978ar6000_hbChallengeResp_event(struct ar6_softc *ar, u32 cookie, u32 source)
4979{
4980 if (source != APP_HB_CHALLENGE) {
4981 /* This would ignore the replys that come in after their due time */
4982 if (cookie == ar->arHBChallengeResp.seqNum) {
4983 ar->arHBChallengeResp.outstanding = false;
4984 }
4985 }
4986}
4987
4988
4989void
4990ar6000_reportError_event(struct ar6_softc *ar, WMI_TARGET_ERROR_VAL errorVal)
4991{
4992 static const char * const errString[] = {
4993 [WMI_TARGET_PM_ERR_FAIL] "WMI_TARGET_PM_ERR_FAIL",
4994 [WMI_TARGET_KEY_NOT_FOUND] "WMI_TARGET_KEY_NOT_FOUND",
4995 [WMI_TARGET_DECRYPTION_ERR] "WMI_TARGET_DECRYPTION_ERR",
4996 [WMI_TARGET_BMISS] "WMI_TARGET_BMISS",
4997 [WMI_PSDISABLE_NODE_JOIN] "WMI_PSDISABLE_NODE_JOIN"
4998 };
4999
5000 A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal);
5001
5002 /* One error is reported at a time, and errorval is a bitmask */
5003 if(errorVal & (errorVal - 1))
5004 return;
5005
5006 A_PRINTF("AR6000 Error type = ");
5007 switch(errorVal)
5008 {
5009 case WMI_TARGET_PM_ERR_FAIL:
5010 case WMI_TARGET_KEY_NOT_FOUND:
5011 case WMI_TARGET_DECRYPTION_ERR:
5012 case WMI_TARGET_BMISS:
5013 case WMI_PSDISABLE_NODE_JOIN:
5014 A_PRINTF("%s\n", errString[errorVal]);
5015 break;
5016 default:
5017 A_PRINTF("INVALID\n");
5018 break;
5019 }
5020
5021}
5022
5023
5024void
5025ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cacIndication,
5026 u8 statusCode, u8 *tspecSuggestion)
5027{
5028 WMM_TSPEC_IE *tspecIe;
5029
5030 /*
5031 * This is the TSPEC IE suggestion from AP.
5032 * Suggestion provided by AP under some error
5033 * cases, could be helpful for the host app.
5034 * Check documentation.
5035 */
5036 tspecIe = (WMM_TSPEC_IE *)tspecSuggestion;
5037
5038 /*
5039 * What do we do, if we get TSPEC rejection? One thought
5040 * that comes to mind is implictly delete the pstream...
5041 */
5042 A_PRINTF("AR6000 CAC notification. "
5043 "AC = %d, cacIndication = 0x%x, statusCode = 0x%x\n",
5044 ac, cacIndication, statusCode);
5045}
5046
5047void
5048ar6000_channel_change_event(struct ar6_softc *ar, u16 oldChannel,
5049 u16 newChannel)
5050{
5051 A_PRINTF("Channel Change notification\nOld Channel: %d, New Channel: %d\n",
5052 oldChannel, newChannel);
5053}
5054
5055#define AR6000_PRINT_BSSID(_pBss) do { \
5056 A_PRINTF("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",\
5057 (_pBss)[0],(_pBss)[1],(_pBss)[2],(_pBss)[3],\
5058 (_pBss)[4],(_pBss)[5]); \
5059} while(0)
5060
5061void
5062ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl)
5063{
5064 u8 i;
5065
5066 A_PRINTF("ROAM TABLE NO OF ENTRIES is %d ROAM MODE is %d\n",
5067 pTbl->numEntries, pTbl->roamMode);
5068 for (i= 0; i < pTbl->numEntries; i++) {
5069 A_PRINTF("[%d]bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", i,
5070 pTbl->bssRoamInfo[i].bssid[0], pTbl->bssRoamInfo[i].bssid[1],
5071 pTbl->bssRoamInfo[i].bssid[2],
5072 pTbl->bssRoamInfo[i].bssid[3],
5073 pTbl->bssRoamInfo[i].bssid[4],
5074 pTbl->bssRoamInfo[i].bssid[5]);
5075 A_PRINTF("RSSI %d RSSIDT %d LAST RSSI %d UTIL %d ROAM_UTIL %d"
5076 " BIAS %d\n",
5077 pTbl->bssRoamInfo[i].rssi,
5078 pTbl->bssRoamInfo[i].rssidt,
5079 pTbl->bssRoamInfo[i].last_rssi,
5080 pTbl->bssRoamInfo[i].util,
5081 pTbl->bssRoamInfo[i].roam_util,
5082 pTbl->bssRoamInfo[i].bias);
5083 }
5084}
5085
5086void
5087ar6000_wow_list_event(struct ar6_softc *ar, u8 num_filters, WMI_GET_WOW_LIST_REPLY *wow_reply)
5088{
5089 u8 i,j;
5090
5091 /*Each event now contains exactly one filter, see bug 26613*/
5092 A_PRINTF("WOW pattern %d of %d patterns\n", wow_reply->this_filter_num, wow_reply->num_filters);
5093 A_PRINTF("wow mode = %s host mode = %s\n",
5094 (wow_reply->wow_mode == 0? "disabled":"enabled"),
5095 (wow_reply->host_mode == 1 ? "awake":"asleep"));
5096
5097
5098 /*If there are no patterns, the reply will only contain generic
5099 WoW information. Pattern information will exist only if there are
5100 patterns present. Bug 26716*/
5101
5102 /* If this event contains pattern information, display it*/
5103 if (wow_reply->this_filter_num) {
5104 i=0;
5105 A_PRINTF("id=%d size=%d offset=%d\n",
5106 wow_reply->wow_filters[i].wow_filter_id,
5107 wow_reply->wow_filters[i].wow_filter_size,
5108 wow_reply->wow_filters[i].wow_filter_offset);
5109 A_PRINTF("wow pattern = ");
5110 for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
5111 A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_pattern[j]);
5112 }
5113
5114 A_PRINTF("\nwow mask = ");
5115 for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
5116 A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_mask[j]);
5117 }
5118 A_PRINTF("\n");
5119 }
5120}
5121
5122/*
5123 * Report the Roaming related data collected on the target
5124 */
5125void
5126ar6000_display_roam_time(WMI_TARGET_ROAM_TIME *p)
5127{
5128 A_PRINTF("Disconnect Data : BSSID: ");
5129 AR6000_PRINT_BSSID(p->disassoc_bssid);
5130 A_PRINTF(" RSSI %d DISASSOC Time %d NO_TXRX_TIME %d\n",
5131 p->disassoc_bss_rssi,p->disassoc_time,
5132 p->no_txrx_time);
5133 A_PRINTF("Connect Data: BSSID: ");
5134 AR6000_PRINT_BSSID(p->assoc_bssid);
5135 A_PRINTF(" RSSI %d ASSOC Time %d TXRX_TIME %d\n",
5136 p->assoc_bss_rssi,p->assoc_time,
5137 p->allow_txrx_time);
5138}
5139
5140void
5141ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p)
5142{
5143 switch (p->roamDataType) {
5144 case ROAM_DATA_TIME:
5145 ar6000_display_roam_time(&p->u.roamTime);
5146 break;
5147 default:
5148 break;
5149 }
5150}
5151
5152void
5153ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *datap, int len)
5154{
5155 struct sk_buff *skb;
5156 WMI_BSS_INFO_HDR *bih = (WMI_BSS_INFO_HDR *)datap;
5157
5158
5159 if (!ar->arMgmtFilter) {
5160 return;
5161 }
5162 if (((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_BEACON) &&
5163 (bih->frameType != BEACON_FTYPE)) ||
5164 ((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_PROBE_RESP) &&
5165 (bih->frameType != PROBERESP_FTYPE)))
5166 {
5167 return;
5168 }
5169
5170 if ((skb = A_NETBUF_ALLOC_RAW(len)) != NULL) {
5171
5172 A_NETBUF_PUT(skb, len);
5173 memcpy(A_NETBUF_DATA(skb), datap, len);
5174 skb->dev = ar->arNetDev;
5175 memcpy(skb_mac_header(skb), A_NETBUF_DATA(skb), 6);
5176 skb->ip_summed = CHECKSUM_NONE;
5177 skb->pkt_type = PACKET_OTHERHOST;
5178 skb->protocol = __constant_htons(0x0019);
5179 netif_rx(skb);
5180 }
5181}
5182
5183u32 wmiSendCmdNum;
5184
5185int
5186ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid)
5187{
5188 struct ar6_softc *ar = (struct ar6_softc *)devt;
5189 int status = 0;
5190 struct ar_cookie *cookie = NULL;
5191 int i;
5192#ifdef CONFIG_PM
5193 if (ar->arWowState != WLAN_WOW_STATE_NONE) {
5194 A_NETBUF_FREE(osbuf);
5195 return A_EACCES;
5196 }
5197#endif /* CONFIG_PM */
5198 /* take lock to protect ar6000_alloc_cookie() */
5199 AR6000_SPIN_LOCK(&ar->arLock, 0);
5200
5201 do {
5202
5203 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar_contrstatus = ol_tx: skb=0x%lx, len=0x%x eid =%d\n",
5204 (unsigned long)osbuf, A_NETBUF_LEN(osbuf), eid));
5205
5206 if (ar->arWMIControlEpFull && (eid == ar->arControlEp)) {
5207 /* control endpoint is full, don't allocate resources, we
5208 * are just going to drop this packet */
5209 cookie = NULL;
5210 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" WMI Control EP full, dropping packet : 0x%lX, len:%d \n",
5211 (unsigned long)osbuf, A_NETBUF_LEN(osbuf)));
5212 } else {
5213 cookie = ar6000_alloc_cookie(ar);
5214 }
5215
5216 if (cookie == NULL) {
5217 status = A_NO_MEMORY;
5218 break;
5219 }
5220
5221 if(logWmiRawMsgs) {
5222 A_PRINTF("WMI cmd send, msgNo %d :", wmiSendCmdNum);
5223 for(i = 0; i < a_netbuf_to_len(osbuf); i++)
5224 A_PRINTF("%x ", ((u8 *)a_netbuf_to_data(osbuf))[i]);
5225 A_PRINTF("\n");
5226 }
5227
5228 wmiSendCmdNum++;
5229
5230 } while (false);
5231
5232 if (cookie != NULL) {
5233 /* got a structure to send it out on */
5234 ar->arTxPending[eid]++;
5235
5236 if (eid != ar->arControlEp) {
5237 ar->arTotalTxDataPending++;
5238 }
5239 }
5240
5241 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
5242
5243 if (cookie != NULL) {
5244 cookie->arc_bp[0] = (unsigned long)osbuf;
5245 cookie->arc_bp[1] = 0;
5246 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
5247 cookie,
5248 A_NETBUF_DATA(osbuf),
5249 A_NETBUF_LEN(osbuf),
5250 eid,
5251 AR6K_CONTROL_PKT_TAG);
5252 /* this interface is asynchronous, if there is an error, cleanup will happen in the
5253 * TX completion callback */
5254 HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
5255 status = 0;
5256 }
5257
5258 if (status) {
5259 A_NETBUF_FREE(osbuf);
5260 }
5261 return status;
5262}
5263
5264/* indicate tx activity or inactivity on a WMI stream */
5265void ar6000_indicate_tx_activity(void *devt, u8 TrafficClass, bool Active)
5266{
5267 struct ar6_softc *ar = (struct ar6_softc *)devt;
5268 HTC_ENDPOINT_ID eid ;
5269 int i;
5270
5271 if (ar->arWmiEnabled) {
5272 eid = arAc2EndpointID(ar, TrafficClass);
5273
5274 AR6000_SPIN_LOCK(&ar->arLock, 0);
5275
5276 ar->arAcStreamActive[TrafficClass] = Active;
5277
5278 if (Active) {
5279 /* when a stream goes active, keep track of the active stream with the highest priority */
5280
5281 if (ar->arAcStreamPriMap[TrafficClass] > ar->arHiAcStreamActivePri) {
5282 /* set the new highest active priority */
5283 ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[TrafficClass];
5284 }
5285
5286 } else {
5287 /* when a stream goes inactive, we may have to search for the next active stream
5288 * that is the highest priority */
5289
5290 if (ar->arHiAcStreamActivePri == ar->arAcStreamPriMap[TrafficClass]) {
5291
5292 /* the highest priority stream just went inactive */
5293
5294 /* reset and search for the "next" highest "active" priority stream */
5295 ar->arHiAcStreamActivePri = 0;
5296 for (i = 0; i < WMM_NUM_AC; i++) {
5297 if (ar->arAcStreamActive[i]) {
5298 if (ar->arAcStreamPriMap[i] > ar->arHiAcStreamActivePri) {
5299 /* set the new highest active priority */
5300 ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[i];
5301 }
5302 }
5303 }
5304 }
5305 }
5306
5307 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
5308
5309 } else {
5310 /* for mbox ping testing, the traffic class is mapped directly as a stream ID,
5311 * see handling of AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE in ioctl.c
5312 * convert the stream ID to a endpoint */
5313 eid = arAc2EndpointID(ar, TrafficClass);
5314 }
5315
5316 /* notify HTC, this may cause credit distribution changes */
5317
5318 HTCIndicateActivityChange(ar->arHtcTarget,
5319 eid,
5320 Active);
5321
5322}
5323
5324void
5325ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, u32 len)
5326{
5327
5328 WMI_BTCOEX_CONFIG_EVENT *pBtcoexConfig = (WMI_BTCOEX_CONFIG_EVENT *)ptr;
5329 WMI_BTCOEX_CONFIG_EVENT *pArbtcoexConfig =&ar->arBtcoexConfig;
5330
5331 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n"));
5332
5333 A_PRINTF("received config event\n");
5334 pArbtcoexConfig->btProfileType = pBtcoexConfig->btProfileType;
5335 pArbtcoexConfig->linkId = pBtcoexConfig->linkId;
5336
5337 switch (pBtcoexConfig->btProfileType) {
5338 case WMI_BTCOEX_BT_PROFILE_SCO:
5339 memcpy(&pArbtcoexConfig->info.scoConfigCmd, &pBtcoexConfig->info.scoConfigCmd,
5340 sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
5341 break;
5342 case WMI_BTCOEX_BT_PROFILE_A2DP:
5343 memcpy(&pArbtcoexConfig->info.a2dpConfigCmd, &pBtcoexConfig->info.a2dpConfigCmd,
5344 sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
5345 break;
5346 case WMI_BTCOEX_BT_PROFILE_ACLCOEX:
5347 memcpy(&pArbtcoexConfig->info.aclcoexConfig, &pBtcoexConfig->info.aclcoexConfig,
5348 sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
5349 break;
5350 case WMI_BTCOEX_BT_PROFILE_INQUIRY_PAGE:
5351 memcpy(&pArbtcoexConfig->info.btinquiryPageConfigCmd, &pBtcoexConfig->info.btinquiryPageConfigCmd,
5352 sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
5353 break;
5354 }
5355 if (ar->statsUpdatePending) {
5356 ar->statsUpdatePending = false;
5357 wake_up(&arEvent);
5358 }
5359}
5360
5361void
5362ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, u32 len)
5363{
5364 WMI_BTCOEX_STATS_EVENT *pBtcoexStats = (WMI_BTCOEX_STATS_EVENT *)ptr;
5365
5366 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n"));
5367
5368 memcpy(&ar->arBtcoexStats, pBtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT));
5369
5370 if (ar->statsUpdatePending) {
5371 ar->statsUpdatePending = false;
5372 wake_up(&arEvent);
5373 }
5374
5375}
5376module_init(ar6000_init_module);
5377module_exit(ar6000_cleanup_module);
5378
5379/* Init cookie queue */
5380static void
5381ar6000_cookie_init(struct ar6_softc *ar)
5382{
5383 u32 i;
5384
5385 ar->arCookieList = NULL;
5386 ar->arCookieCount = 0;
5387
5388 A_MEMZERO(s_ar_cookie_mem, sizeof(s_ar_cookie_mem));
5389
5390 for (i = 0; i < MAX_COOKIE_NUM; i++) {
5391 ar6000_free_cookie(ar, &s_ar_cookie_mem[i]);
5392 }
5393}
5394
5395/* cleanup cookie queue */
5396static void
5397ar6000_cookie_cleanup(struct ar6_softc *ar)
5398{
5399 /* It is gone .... */
5400 ar->arCookieList = NULL;
5401 ar->arCookieCount = 0;
5402}
5403
5404/* Init cookie queue */
5405static void
5406ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie)
5407{
5408 /* Insert first */
5409 A_ASSERT(ar != NULL);
5410 A_ASSERT(cookie != NULL);
5411
5412 cookie->arc_list_next = ar->arCookieList;
5413 ar->arCookieList = cookie;
5414 ar->arCookieCount++;
5415}
5416
5417/* cleanup cookie queue */
5418static struct ar_cookie *
5419ar6000_alloc_cookie(struct ar6_softc *ar)
5420{
5421 struct ar_cookie *cookie;
5422
5423 cookie = ar->arCookieList;
5424 if(cookie != NULL)
5425 {
5426 ar->arCookieList = cookie->arc_list_next;
5427 ar->arCookieCount--;
5428 }
5429
5430 return cookie;
5431}
5432
5433void
5434ar6000_tx_retry_err_event(void *devt)
5435{
5436 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Tx retries reach maximum!\n"));
5437}
5438
5439void
5440ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, u8 snr)
5441{
5442 WMI_SNR_THRESHOLD_EVENT event;
5443
5444 event.range = newThreshold;
5445 event.snr = snr;
5446}
5447
5448void
5449ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL newThreshold, u8 lq)
5450{
5451 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("lq threshold range %d, lq %d\n", newThreshold, lq));
5452}
5453
5454
5455
5456u32 a_copy_to_user(void *to, const void *from, u32 n)
5457{
5458 return(copy_to_user(to, from, n));
5459}
5460
5461u32 a_copy_from_user(void *to, const void *from, u32 n)
5462{
5463 return(copy_from_user(to, from, n));
5464}
5465
5466
5467int
5468ar6000_get_driver_cfg(struct net_device *dev,
5469 u16 cfgParam,
5470 void *result)
5471{
5472
5473 int ret = 0;
5474
5475 switch(cfgParam)
5476 {
5477 case AR6000_DRIVER_CFG_GET_WLANNODECACHING:
5478 *((u32 *)result) = wlanNodeCaching;
5479 break;
5480 case AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS:
5481 *((u32 *)result) = logWmiRawMsgs;
5482 break;
5483 default:
5484 ret = EINVAL;
5485 break;
5486 }
5487
5488 return ret;
5489}
5490
5491void
5492ar6000_keepalive_rx(void *devt, u8 configured)
5493{
5494 struct ar6_softc *ar = (struct ar6_softc *)devt;
5495
5496 ar->arKeepaliveConfigured = configured;
5497 wake_up(&arEvent);
5498}
5499
5500void
5501ar6000_pmkid_list_event(void *devt, u8 numPMKID, WMI_PMKID *pmkidList,
5502 u8 *bssidList)
5503{
5504 u8 i, j;
5505
5506 A_PRINTF("Number of Cached PMKIDs is %d\n", numPMKID);
5507
5508 for (i = 0; i < numPMKID; i++) {
5509 A_PRINTF("\nBSSID %d ", i);
5510 for (j = 0; j < ATH_MAC_LEN; j++) {
5511 A_PRINTF("%2.2x", bssidList[j]);
5512 }
5513 bssidList += (ATH_MAC_LEN + WMI_PMKID_LEN);
5514 A_PRINTF("\nPMKID %d ", i);
5515 for (j = 0; j < WMI_PMKID_LEN; j++) {
5516 A_PRINTF("%2.2x", pmkidList->pmkid[j]);
5517 }
5518 pmkidList = (WMI_PMKID *)((u8 *)pmkidList + ATH_MAC_LEN +
5519 WMI_PMKID_LEN);
5520 }
5521}
5522
5523void ar6000_pspoll_event(struct ar6_softc *ar,u8 aid)
5524{
5525 sta_t *conn=NULL;
5526 bool isPsqEmpty = false;
5527
5528 conn = ieee80211_find_conn_for_aid(ar, aid);
5529
5530 /* If the PS q for this STA is not empty, dequeue and send a pkt from
5531 * the head of the q. Also update the More data bit in the WMI_DATA_HDR
5532 * if there are more pkts for this STA in the PS q. If there are no more
5533 * pkts for this STA, update the PVB for this STA.
5534 */
5535 A_MUTEX_LOCK(&conn->psqLock);
5536 isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
5537 A_MUTEX_UNLOCK(&conn->psqLock);
5538
5539 if (isPsqEmpty) {
5540 /* TODO:No buffered pkts for this STA. Send out a NULL data frame */
5541 } else {
5542 struct sk_buff *skb = NULL;
5543
5544 A_MUTEX_LOCK(&conn->psqLock);
5545 skb = A_NETBUF_DEQUEUE(&conn->psq);
5546 A_MUTEX_UNLOCK(&conn->psqLock);
5547 /* Set the STA flag to PSPolled, so that the frame will go out */
5548 STA_SET_PS_POLLED(conn);
5549 ar6000_data_tx(skb, ar->arNetDev);
5550 STA_CLR_PS_POLLED(conn);
5551
5552 /* Clear the PVB for this STA if the queue has become empty */
5553 A_MUTEX_LOCK(&conn->psqLock);
5554 isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
5555 A_MUTEX_UNLOCK(&conn->psqLock);
5556
5557 if (isPsqEmpty) {
5558 wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
5559 }
5560 }
5561}
5562
5563void ar6000_dtimexpiry_event(struct ar6_softc *ar)
5564{
5565 bool isMcastQueued = false;
5566 struct sk_buff *skb = NULL;
5567
5568 /* If there are no associated STAs, ignore the DTIM expiry event.
5569 * There can be potential race conditions where the last associated
5570 * STA may disconnect & before the host could clear the 'Indicate DTIM'
5571 * request to the firmware, the firmware would have just indicated a DTIM
5572 * expiry event. The race is between 'clear DTIM expiry cmd' going
5573 * from the host to the firmware & the DTIM expiry event happening from
5574 * the firmware to the host.
5575 */
5576 if (ar->sta_list_index == 0) {
5577 return;
5578 }
5579
5580 A_MUTEX_LOCK(&ar->mcastpsqLock);
5581 isMcastQueued = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
5582 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5583
5584 A_ASSERT(isMcastQueued == false);
5585
5586 /* Flush the mcast psq to the target */
5587 /* Set the STA flag to DTIMExpired, so that the frame will go out */
5588 ar->DTIMExpired = true;
5589
5590 A_MUTEX_LOCK(&ar->mcastpsqLock);
5591 while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
5592 skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
5593 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5594
5595 ar6000_data_tx(skb, ar->arNetDev);
5596
5597 A_MUTEX_LOCK(&ar->mcastpsqLock);
5598 }
5599 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5600
5601 /* Reset the DTIMExpired flag back to 0 */
5602 ar->DTIMExpired = false;
5603
5604 /* Clear the LSB of the BitMapCtl field of the TIM IE */
5605 wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
5606}
5607
5608void
5609read_rssi_compensation_param(struct ar6_softc *ar)
5610{
5611 u8 *cust_data_ptr;
5612
5613//#define RSSICOMPENSATION_PRINT
5614
5615#ifdef RSSICOMPENSATION_PRINT
5616 s16 i;
5617 cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType);
5618 for (i=0; i<16; i++) {
5619 A_PRINTF("cust_data_%d = %x \n", i, *(u8 *)cust_data_ptr);
5620 cust_data_ptr += 1;
5621 }
5622#endif
5623
5624 cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType);
5625
5626 rssi_compensation_param.customerID = *(u16 *)cust_data_ptr & 0xffff;
5627 rssi_compensation_param.enable = *(u16 *)(cust_data_ptr+2) & 0xffff;
5628 rssi_compensation_param.bg_param_a = *(u16 *)(cust_data_ptr+4) & 0xffff;
5629 rssi_compensation_param.bg_param_b = *(u16 *)(cust_data_ptr+6) & 0xffff;
5630 rssi_compensation_param.a_param_a = *(u16 *)(cust_data_ptr+8) & 0xffff;
5631 rssi_compensation_param.a_param_b = *(u16 *)(cust_data_ptr+10) &0xffff;
5632 rssi_compensation_param.reserved = *(u32 *)(cust_data_ptr+12);
5633
5634#ifdef RSSICOMPENSATION_PRINT
5635 A_PRINTF("customerID = 0x%x \n", rssi_compensation_param.customerID);
5636 A_PRINTF("enable = 0x%x \n", rssi_compensation_param.enable);
5637 A_PRINTF("bg_param_a = 0x%x and %d \n", rssi_compensation_param.bg_param_a, rssi_compensation_param.bg_param_a);
5638 A_PRINTF("bg_param_b = 0x%x and %d \n", rssi_compensation_param.bg_param_b, rssi_compensation_param.bg_param_b);
5639 A_PRINTF("a_param_a = 0x%x and %d \n", rssi_compensation_param.a_param_a, rssi_compensation_param.a_param_a);
5640 A_PRINTF("a_param_b = 0x%x and %d \n", rssi_compensation_param.a_param_b, rssi_compensation_param.a_param_b);
5641 A_PRINTF("Last 4 bytes = 0x%x \n", rssi_compensation_param.reserved);
5642#endif
5643
5644 if (rssi_compensation_param.enable != 0x1) {
5645 rssi_compensation_param.enable = 0;
5646 }
5647
5648 return;
5649}
5650
5651s32 rssi_compensation_calc_tcmd(u32 freq, s32 rssi, u32 totalPkt)
5652{
5653
5654 if (freq > 5000)
5655 {
5656 if (rssi_compensation_param.enable)
5657 {
5658 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5659 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d, totalPkt = %d\n", rssi,totalPkt));
5660 rssi = rssi * rssi_compensation_param.a_param_a + totalPkt * rssi_compensation_param.a_param_b;
5661 rssi = (rssi-50) /100;
5662 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5663 }
5664 }
5665 else
5666 {
5667 if (rssi_compensation_param.enable)
5668 {
5669 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5670 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d, totalPkt = %d\n", rssi,totalPkt));
5671 rssi = rssi * rssi_compensation_param.bg_param_a + totalPkt * rssi_compensation_param.bg_param_b;
5672 rssi = (rssi-50) /100;
5673 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5674 }
5675 }
5676
5677 return rssi;
5678}
5679
5680s16 rssi_compensation_calc(struct ar6_softc *ar, s16 rssi)
5681{
5682 if (ar->arBssChannel > 5000)
5683 {
5684 if (rssi_compensation_param.enable)
5685 {
5686 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5687 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d\n", rssi));
5688 rssi = rssi * rssi_compensation_param.a_param_a + rssi_compensation_param.a_param_b;
5689 rssi = (rssi-50) /100;
5690 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5691 }
5692 }
5693 else
5694 {
5695 if (rssi_compensation_param.enable)
5696 {
5697 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5698 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d\n", rssi));
5699 rssi = rssi * rssi_compensation_param.bg_param_a + rssi_compensation_param.bg_param_b;
5700 rssi = (rssi-50) /100;
5701 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5702 }
5703 }
5704
5705 return rssi;
5706}
5707
5708s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above)
5709{
5710 s16 i;
5711
5712 if (ar->arBssChannel > 5000)
5713 {
5714 if (rssi_compensation_param.enable)
5715 {
5716 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5717 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation = %d\n", rssi));
5718 rssi = rssi * 100;
5719 rssi = (rssi - rssi_compensation_param.a_param_b) / rssi_compensation_param.a_param_a;
5720 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n", rssi));
5721 }
5722 }
5723 else
5724 {
5725 if (rssi_compensation_param.enable)
5726 {
5727 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5728 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation = %d\n", rssi));
5729
5730 if (Above) {
5731 for (i=95; i>=0; i--) {
5732 if (rssi <= rssi_compensation_table[i]) {
5733 rssi = 0 - i;
5734 break;
5735 }
5736 }
5737 } else {
5738 for (i=0; i<=95; i++) {
5739 if (rssi >= rssi_compensation_table[i]) {
5740 rssi = 0 - i;
5741 break;
5742 }
5743 }
5744 }
5745 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n", rssi));
5746 }
5747 }
5748
5749 return rssi;
5750}
5751
5752#ifdef WAPI_ENABLE
5753void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac)
5754{
5755 union iwreq_data wrqu;
5756 char buf[20];
5757
5758 A_MEMZERO(buf, sizeof(buf));
5759
5760 strcpy(buf, "WAPI_REKEY");
5761 buf[10] = type;
5762 memcpy(&buf[11], mac, ATH_MAC_LEN);
5763
5764 A_MEMZERO(&wrqu, sizeof(wrqu));
5765 wrqu.data.length = 10+1+ATH_MAC_LEN;
5766 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
5767
5768 A_PRINTF("WAPI REKEY - %d - %02x:%02x\n", type, mac[4], mac[5]);
5769}
5770#endif
5771
5772static int
5773ar6000_reinstall_keys(struct ar6_softc *ar, u8 key_op_ctrl)
5774{
5775 int status = 0;
5776 struct ieee80211req_key *uik = &ar->user_saved_keys.ucast_ik;
5777 struct ieee80211req_key *bik = &ar->user_saved_keys.bcast_ik;
5778 CRYPTO_TYPE keyType = ar->user_saved_keys.keyType;
5779
5780 if (IEEE80211_CIPHER_CCKM_KRK != uik->ik_type) {
5781 if (NONE_CRYPT == keyType) {
5782 goto _reinstall_keys_out;
5783 }
5784
5785 if (uik->ik_keylen) {
5786 status = wmi_addKey_cmd(ar->arWmi, uik->ik_keyix,
5787 ar->user_saved_keys.keyType, PAIRWISE_USAGE,
5788 uik->ik_keylen, (u8 *)&uik->ik_keyrsc,
5789 uik->ik_keydata, key_op_ctrl, uik->ik_macaddr, SYNC_BEFORE_WMIFLAG);
5790 }
5791
5792 } else {
5793 status = wmi_add_krk_cmd(ar->arWmi, uik->ik_keydata);
5794 }
5795
5796 if (IEEE80211_CIPHER_CCKM_KRK != bik->ik_type) {
5797 if (NONE_CRYPT == keyType) {
5798 goto _reinstall_keys_out;
5799 }
5800
5801 if (bik->ik_keylen) {
5802 status = wmi_addKey_cmd(ar->arWmi, bik->ik_keyix,
5803 ar->user_saved_keys.keyType, GROUP_USAGE,
5804 bik->ik_keylen, (u8 *)&bik->ik_keyrsc,
5805 bik->ik_keydata, key_op_ctrl, bik->ik_macaddr, NO_SYNC_WMIFLAG);
5806 }
5807 } else {
5808 status = wmi_add_krk_cmd(ar->arWmi, bik->ik_keydata);
5809 }
5810
5811_reinstall_keys_out:
5812 ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
5813 ar->user_key_ctrl = 0;
5814
5815 return status;
5816}
5817
5818
5819void
5820ar6000_dset_open_req(
5821 void *context,
5822 u32 id,
5823 u32 targHandle,
5824 u32 targReplyFn,
5825 u32 targReplyArg)
5826{
5827}
5828
5829void
5830ar6000_dset_close(
5831 void *context,
5832 u32 access_cookie)
5833{
5834 return;
5835}
5836
5837void
5838ar6000_dset_data_req(
5839 void *context,
5840 u32 accessCookie,
5841 u32 offset,
5842 u32 length,
5843 u32 targBuf,
5844 u32 targReplyFn,
5845 u32 targReplyArg)
5846{
5847}
5848
5849int
5850ar6000_ap_mode_profile_commit(struct ar6_softc *ar)
5851{
5852 WMI_CONNECT_CMD p;
5853 unsigned long flags;
5854
5855 /* No change in AP's profile configuration */
5856 if(ar->ap_profile_flag==0) {
5857 A_PRINTF("COMMIT: No change in profile!!!\n");
5858 return -ENODATA;
5859 }
5860
5861 if(!ar->arSsidLen) {
5862 A_PRINTF("SSID not set!!!\n");
5863 return -ECHRNG;
5864 }
5865
5866 switch(ar->arAuthMode) {
5867 case NONE_AUTH:
5868 if((ar->arPairwiseCrypto != NONE_CRYPT) &&
5869#ifdef WAPI_ENABLE
5870 (ar->arPairwiseCrypto != WAPI_CRYPT) &&
5871#endif
5872 (ar->arPairwiseCrypto != WEP_CRYPT)) {
5873 A_PRINTF("Cipher not supported in AP mode Open auth\n");
5874 return -EOPNOTSUPP;
5875 }
5876 break;
5877 case WPA_PSK_AUTH:
5878 case WPA2_PSK_AUTH:
5879 case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
5880 break;
5881 default:
5882 A_PRINTF("This key mgmt type not supported in AP mode\n");
5883 return -EOPNOTSUPP;
5884 }
5885
5886 /* Update the arNetworkType */
5887 ar->arNetworkType = ar->arNextMode;
5888
5889 A_MEMZERO(&p,sizeof(p));
5890 p.ssidLength = ar->arSsidLen;
5891 memcpy(p.ssid,ar->arSsid,p.ssidLength);
5892 p.channel = ar->arChannelHint;
5893 p.networkType = ar->arNetworkType;
5894
5895 p.dot11AuthMode = ar->arDot11AuthMode;
5896 p.authMode = ar->arAuthMode;
5897 p.pairwiseCryptoType = ar->arPairwiseCrypto;
5898 p.pairwiseCryptoLen = ar->arPairwiseCryptoLen;
5899 p.groupCryptoType = ar->arGroupCrypto;
5900 p.groupCryptoLen = ar->arGroupCryptoLen;
5901 p.ctrl_flags = ar->arConnectCtrlFlags;
5902
5903 wmi_ap_profile_commit(ar->arWmi, &p);
5904 spin_lock_irqsave(&ar->arLock, flags);
5905 ar->arConnected = true;
5906 netif_carrier_on(ar->arNetDev);
5907 spin_unlock_irqrestore(&ar->arLock, flags);
5908 ar->ap_profile_flag = 0;
5909 return 0;
5910}
5911
5912int
5913ar6000_connect_to_ap(struct ar6_softc *ar)
5914{
5915 /* The ssid length check prevents second "essid off" from the user,
5916 to be treated as a connect cmd. The second "essid off" is ignored.
5917 */
5918 if((ar->arWmiReady == true) && (ar->arSsidLen > 0) && ar->arNetworkType!=AP_NETWORK)
5919 {
5920 int status;
5921 if((ADHOC_NETWORK != ar->arNetworkType) &&
5922 (NONE_AUTH==ar->arAuthMode) &&
5923 (WEP_CRYPT==ar->arPairwiseCrypto)) {
5924 ar6000_install_static_wep_keys(ar);
5925 }
5926
5927 if (!ar->arUserBssFilter) {
5928 if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) {
5929 return -EIO;
5930 }
5931 }
5932#ifdef WAPI_ENABLE
5933 if (ar->arWapiEnable) {
5934 ar->arPairwiseCrypto = WAPI_CRYPT;
5935 ar->arPairwiseCryptoLen = 0;
5936 ar->arGroupCrypto = WAPI_CRYPT;
5937 ar->arGroupCryptoLen = 0;
5938 ar->arAuthMode = NONE_AUTH;
5939 ar->arConnectCtrlFlags |= CONNECT_IGNORE_WPAx_GROUP_CIPHER;
5940 }
5941#endif
5942 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("Connect called with authmode %d dot11 auth %d"\
5943 " PW crypto %d PW crypto Len %d GRP crypto %d"\
5944 " GRP crypto Len %d\n",
5945 ar->arAuthMode, ar->arDot11AuthMode,
5946 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
5947 ar->arGroupCrypto, ar->arGroupCryptoLen));
5948 reconnect_flag = 0;
5949 /* Set the listen interval into 1000TUs or more. This value will be indicated to Ap in the conn.
5950 later set it back locally at the STA to 100/1000 TUs depending on the power mode */
5951 if ((ar->arNetworkType == INFRA_NETWORK)) {
5952 wmi_listeninterval_cmd(ar->arWmi, max(ar->arListenIntervalT, (u16)A_MAX_WOW_LISTEN_INTERVAL), 0);
5953 }
5954 status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
5955 ar->arDot11AuthMode, ar->arAuthMode,
5956 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
5957 ar->arGroupCrypto,ar->arGroupCryptoLen,
5958 ar->arSsidLen, ar->arSsid,
5959 ar->arReqBssid, ar->arChannelHint,
5960 ar->arConnectCtrlFlags);
5961 if (status) {
5962 wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB);
5963 if (!ar->arUserBssFilter) {
5964 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
5965 }
5966 return status;
5967 }
5968
5969 if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
5970 ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
5971 {
5972 A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
5973 }
5974
5975 ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
5976
5977 ar->arConnectPending = true;
5978 return status;
5979 }
5980 return A_ERROR;
5981}
5982
5983int
5984ar6000_disconnect(struct ar6_softc *ar)
5985{
5986 if ((ar->arConnected == true) || (ar->arConnectPending == true)) {
5987 wmi_disconnect_cmd(ar->arWmi);
5988 /*
5989 * Disconnect cmd is issued, clear connectPending.
5990 * arConnected will be cleard in disconnect_event notification.
5991 */
5992 ar->arConnectPending = false;
5993 }
5994
5995 return 0;
5996}
5997
5998int
5999ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie)
6000{
6001 sta_t *conn = NULL;
6002 conn = ieee80211_find_conn(ar, wpaie->wpa_macaddr);
6003
6004 A_MEMZERO(wpaie->wpa_ie, IEEE80211_MAX_IE);
6005 A_MEMZERO(wpaie->rsn_ie, IEEE80211_MAX_IE);
6006
6007 if(conn) {
6008 memcpy(wpaie->wpa_ie, conn->wpa_ie, IEEE80211_MAX_IE);
6009 }
6010
6011 return 0;
6012}
6013
6014int
6015is_iwioctl_allowed(u8 mode, u16 cmd)
6016{
6017 if(cmd >= SIOCSIWCOMMIT && cmd <= SIOCGIWPOWER) {
6018 cmd -= SIOCSIWCOMMIT;
6019 if(sioctl_filter[cmd] == 0xFF) return 0;
6020 if(sioctl_filter[cmd] & mode) return 0;
6021 } else if(cmd >= SIOCIWFIRSTPRIV && cmd <= (SIOCIWFIRSTPRIV+30)) {
6022 cmd -= SIOCIWFIRSTPRIV;
6023 if(pioctl_filter[cmd] == 0xFF) return 0;
6024 if(pioctl_filter[cmd] & mode) return 0;
6025 } else {
6026 return A_ERROR;
6027 }
6028 return A_ENOTSUP;
6029}
6030
6031int
6032is_xioctl_allowed(u8 mode, int cmd)
6033{
6034 if(sizeof(xioctl_filter)-1 < cmd) {
6035 A_PRINTF("Filter for this cmd=%d not defined\n",cmd);
6036 return 0;
6037 }
6038 if(xioctl_filter[cmd] == 0xFF) return 0;
6039 if(xioctl_filter[cmd] & mode) return 0;
6040 return A_ERROR;
6041}
6042
6043#ifdef WAPI_ENABLE
6044int
6045ap_set_wapi_key(struct ar6_softc *ar, void *ikey)
6046{
6047 struct ieee80211req_key *ik = (struct ieee80211req_key *)ikey;
6048 KEY_USAGE keyUsage = 0;
6049 int status;
6050
6051 if (memcmp(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN) == 0) {
6052 keyUsage = GROUP_USAGE;
6053 } else {
6054 keyUsage = PAIRWISE_USAGE;
6055 }
6056 A_PRINTF("WAPI_KEY: Type:%d ix:%d mac:%02x:%02x len:%d\n",
6057 keyUsage, ik->ik_keyix, ik->ik_macaddr[4], ik->ik_macaddr[5],
6058 ik->ik_keylen);
6059
6060 status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, WAPI_CRYPT, keyUsage,
6061 ik->ik_keylen, (u8 *)&ik->ik_keyrsc,
6062 ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
6063 SYNC_BOTH_WMIFLAG);
6064
6065 if (0 != status) {
6066 return -EIO;
6067 }
6068 return 0;
6069}
6070#endif
6071
6072void ar6000_peer_event(
6073 void *context,
6074 u8 eventCode,
6075 u8 *macAddr)
6076{
6077 u8 pos;
6078
6079 for (pos=0;pos<6;pos++)
6080 printk("%02x: ",*(macAddr+pos));
6081 printk("\n");
6082}
6083
6084#ifdef HTC_TEST_SEND_PKTS
6085#define HTC_TEST_DUPLICATE 8
6086static void DoHTCSendPktsTest(struct ar6_softc *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *dupskb)
6087{
6088 struct ar_cookie *cookie;
6089 struct ar_cookie *cookieArray[HTC_TEST_DUPLICATE];
6090 struct sk_buff *new_skb;
6091 int i;
6092 int pkts = 0;
6093 struct htc_packet_queue pktQueue;
6094 EPPING_HEADER *eppingHdr;
6095
6096 eppingHdr = A_NETBUF_DATA(dupskb);
6097
6098 if (eppingHdr->Cmd_h == EPPING_CMD_NO_ECHO) {
6099 /* skip test if this is already a tx perf test */
6100 return;
6101 }
6102
6103 for (i = 0; i < HTC_TEST_DUPLICATE; i++,pkts++) {
6104 AR6000_SPIN_LOCK(&ar->arLock, 0);
6105 cookie = ar6000_alloc_cookie(ar);
6106 if (cookie != NULL) {
6107 ar->arTxPending[eid]++;
6108 ar->arTotalTxDataPending++;
6109 }
6110
6111 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
6112
6113 if (NULL == cookie) {
6114 break;
6115 }
6116
6117 new_skb = A_NETBUF_ALLOC(A_NETBUF_LEN(dupskb));
6118
6119 if (new_skb == NULL) {
6120 AR6000_SPIN_LOCK(&ar->arLock, 0);
6121 ar6000_free_cookie(ar,cookie);
6122 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
6123 break;
6124 }
6125
6126 A_NETBUF_PUT_DATA(new_skb, A_NETBUF_DATA(dupskb), A_NETBUF_LEN(dupskb));
6127 cookie->arc_bp[0] = (unsigned long)new_skb;
6128 cookie->arc_bp[1] = MapNo;
6129 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
6130 cookie,
6131 A_NETBUF_DATA(new_skb),
6132 A_NETBUF_LEN(new_skb),
6133 eid,
6134 AR6K_DATA_PKT_TAG);
6135
6136 cookieArray[i] = cookie;
6137
6138 {
6139 EPPING_HEADER *pHdr = (EPPING_HEADER *)A_NETBUF_DATA(new_skb);
6140 pHdr->Cmd_h = EPPING_CMD_NO_ECHO; /* do not echo the packet */
6141 }
6142 }
6143
6144 if (pkts == 0) {
6145 return;
6146 }
6147
6148 INIT_HTC_PACKET_QUEUE(&pktQueue);
6149
6150 for (i = 0; i < pkts; i++) {
6151 HTC_PACKET_ENQUEUE(&pktQueue,&cookieArray[i]->HtcPkt);
6152 }
6153
6154 HTCSendPktsMultiple(ar->arHtcTarget, &pktQueue);
6155
6156}
6157#endif
6158
6159#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
6160/*
6161 * Add support for adding and removing a virtual adapter for soft AP.
6162 * Some OS requires different adapters names for station and soft AP mode.
6163 * To support these requirement, create and destroy a netdevice instance
6164 * when the AP mode is operational. A full fledged support for virual device
6165 * is not implemented. Rather a virtual interface is created and is linked
6166 * with the existing physical device instance during the operation of the
6167 * AP mode.
6168 */
6169
6170int ar6000_start_ap_interface(struct ar6_softc *ar)
6171{
6172 struct ar_virtual_interface *arApDev;
6173
6174 /* Change net_device to point to AP instance */
6175 arApDev = (struct ar_virtual_interface *)ar->arApDev;
6176 ar->arNetDev = arApDev->arNetDev;
6177
6178 return 0;
6179}
6180
6181int ar6000_stop_ap_interface(struct ar6_softc *ar)
6182{
6183 struct ar_virtual_interface *arApDev;
6184
6185 /* Change net_device to point to sta instance */
6186 arApDev = (struct ar_virtual_interface *)ar->arApDev;
6187 if (arApDev) {
6188 ar->arNetDev = arApDev->arStaNetDev;
6189 }
6190
6191 return 0;
6192}
6193
6194
6195int ar6000_create_ap_interface(struct ar6_softc *ar, char *ap_ifname)
6196{
6197 struct net_device *dev;
6198 struct ar_virtual_interface *arApDev;
6199
6200 dev = alloc_etherdev(sizeof(struct ar_virtual_interface));
6201 if (dev == NULL) {
6202 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: can't alloc etherdev\n"));
6203 return A_ERROR;
6204 }
6205
6206 ether_setup(dev);
6207 init_netdev(dev, ap_ifname);
6208 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
6209
6210 if (register_netdev(dev)) {
6211 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: register_netdev failed\n"));
6212 return A_ERROR;
6213 }
6214
6215 arApDev = netdev_priv(dev);
6216 arApDev->arDev = ar;
6217 arApDev->arNetDev = dev;
6218 arApDev->arStaNetDev = ar->arNetDev;
6219
6220 ar->arApDev = arApDev;
6221 arApNetDev = dev;
6222
6223 /* Copy the MAC address */
6224 memcpy(dev->dev_addr, ar->arNetDev->dev_addr, AR6000_ETH_ADDR_LEN);
6225
6226 return 0;
6227}
6228
6229int ar6000_add_ap_interface(struct ar6_softc *ar, char *ap_ifname)
6230{
6231 /* Interface already added, need not proceed further */
6232 if (ar->arApDev != NULL) {
6233 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_add_ap_interface: interface already present \n"));
6234 return 0;
6235 }
6236
6237 if (ar6000_create_ap_interface(ar, ap_ifname) != 0) {
6238 return A_ERROR;
6239 }
6240
6241 A_PRINTF("Add AP interface %s \n",ap_ifname);
6242
6243 return ar6000_start_ap_interface(ar);
6244}
6245
6246int ar6000_remove_ap_interface(struct ar6_softc *ar)
6247{
6248 if (arApNetDev) {
6249 ar6000_stop_ap_interface(ar);
6250
6251 unregister_netdev(arApNetDev);
6252 free_netdev(apApNetDev);
6253
6254 A_PRINTF("Remove AP interface\n");
6255 }
6256 ar->arApDev = NULL;
6257 arApNetDev = NULL;
6258
6259
6260 return 0;
6261}
6262#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
6263
6264
6265#ifdef EXPORT_HCI_BRIDGE_INTERFACE
6266EXPORT_SYMBOL(setupbtdev);
6267#endif
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c
new file mode 100644
index 00000000000..1e0ace8b6d1
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c
@@ -0,0 +1,626 @@
1/*
2 *
3 * Copyright (c) 2004-2010 Atheros Communications Inc.
4 * All rights reserved.
5 *
6 *
7//
8// Permission to use, copy, modify, and/or distribute this software for any
9// purpose with or without fee is hereby granted, provided that the above
10// copyright notice and this permission notice appear in all copies.
11//
12// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19//
20//
21 *
22 */
23
24/*
25 * Implementation of system power management
26 */
27
28#include "ar6000_drv.h"
29#include <linux/inetdevice.h>
30#include <linux/platform_device.h>
31#include "wlan_config.h"
32
33#define WOW_ENABLE_MAX_INTERVAL 0
34#define WOW_SET_SCAN_PARAMS 0
35
36extern unsigned int wmitimeout;
37extern wait_queue_head_t arEvent;
38
39#undef ATH_MODULE_NAME
40#define ATH_MODULE_NAME pm
41#define ATH_DEBUG_PM ATH_DEBUG_MAKE_MODULE_MASK(0)
42
43#ifdef DEBUG
44static struct ath_debug_mask_description pm_debug_desc[] = {
45 { ATH_DEBUG_PM , "System power management"},
46};
47
48ATH_DEBUG_INSTANTIATE_MODULE_VAR(pm,
49 "pm",
50 "System Power Management",
51 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_PM,
52 ATH_DEBUG_DESCRIPTION_COUNT(pm_debug_desc),
53 pm_debug_desc);
54
55#endif /* DEBUG */
56
57int ar6000_exit_cut_power_state(struct ar6_softc *ar);
58
59#ifdef CONFIG_PM
60static void ar6k_send_asleep_event_to_app(struct ar6_softc *ar, bool asleep)
61{
62 char buf[128];
63 union iwreq_data wrqu;
64
65 snprintf(buf, sizeof(buf), "HOST_ASLEEP=%s", asleep ? "asleep" : "awake");
66 A_MEMZERO(&wrqu, sizeof(wrqu));
67 wrqu.data.length = strlen(buf);
68 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
69}
70
71static void ar6000_wow_resume(struct ar6_softc *ar)
72{
73 if (ar->arWowState!= WLAN_WOW_STATE_NONE) {
74 u16 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period;
75 u16 bg_period = (ar->scParams.bg_period==0) ? 60 : ar->scParams.bg_period;
76 WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {true, false};
77 ar->arWowState = WLAN_WOW_STATE_NONE;
78 if (wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)!= 0) {
79 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup restore host awake\n"));
80 }
81#if WOW_SET_SCAN_PARAMS
82 wmi_scanparams_cmd(ar->arWmi, fg_start_period,
83 ar->scParams.fg_end_period,
84 bg_period,
85 ar->scParams.minact_chdwell_time,
86 ar->scParams.maxact_chdwell_time,
87 ar->scParams.pas_chdwell_time,
88 ar->scParams.shortScanRatio,
89 ar->scParams.scanCtrlFlags,
90 ar->scParams.max_dfsch_act_time,
91 ar->scParams.maxact_scan_per_ssid);
92#else
93 (void)fg_start_period;
94 (void)bg_period;
95#endif
96
97
98#if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */
99 if (wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB) == 0) {
100 }
101#endif
102 ar6k_send_asleep_event_to_app(ar, false);
103 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Resume WoW successfully\n"));
104 } else {
105 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WoW does not invoked. skip resume"));
106 }
107 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
108}
109
110static void ar6000_wow_suspend(struct ar6_softc *ar)
111{
112#define WOW_LIST_ID 1
113 if (ar->arNetworkType != AP_NETWORK) {
114 /* Setup WoW for unicast & Arp request for our own IP
115 disable background scan. Set listen interval into 1000 TUs
116 Enable keepliave for 110 seconds
117 */
118 struct in_ifaddr **ifap = NULL;
119 struct in_ifaddr *ifa = NULL;
120 struct in_device *in_dev;
121 u8 macMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
122 int status;
123 WMI_ADD_WOW_PATTERN_CMD addWowCmd = { .filter = { 0 } };
124 WMI_DEL_WOW_PATTERN_CMD delWowCmd;
125 WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {false, true};
126 WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = true,
127 .hostReqDelay = 500 };/*500 ms delay*/
128
129 if (ar->arWowState!= WLAN_WOW_STATE_NONE) {
130 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("System already go into wow mode!\n"));
131 return;
132 }
133
134 ar6000_TxDataCleanup(ar); /* IMPORTANT, otherwise there will be 11mA after listen interval as 1000*/
135
136#if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */
137 if (wmi_listeninterval_cmd(ar->arWmi, A_MAX_WOW_LISTEN_INTERVAL, 0) == 0) {
138 }
139#endif
140
141#if WOW_SET_SCAN_PARAMS
142 status = wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0xFFFF, 0, 0, 0, 0, 0, 0, 0);
143#endif
144 /* clear up our WoW pattern first */
145 delWowCmd.filter_list_id = WOW_LIST_ID;
146 delWowCmd.filter_id = 0;
147 wmi_del_wow_pattern_cmd(ar->arWmi, &delWowCmd);
148
149 /* setup unicast packet pattern for WoW */
150 if (ar->arNetDev->dev_addr[1]) {
151 addWowCmd.filter_list_id = WOW_LIST_ID;
152 addWowCmd.filter_size = 6; /* MAC address */
153 addWowCmd.filter_offset = 0;
154 status = wmi_add_wow_pattern_cmd(ar->arWmi, &addWowCmd, ar->arNetDev->dev_addr, macMask, addWowCmd.filter_size);
155 if (status) {
156 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to add WoW pattern\n"));
157 }
158 }
159 /* setup ARP request for our own IP */
160 if ((in_dev = __in_dev_get_rtnl(ar->arNetDev)) != NULL) {
161 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; ifap = &ifa->ifa_next) {
162 if (!strcmp(ar->arNetDev->name, ifa->ifa_label)) {
163 break; /* found */
164 }
165 }
166 }
167 if (ifa && ifa->ifa_local) {
168 WMI_SET_IP_CMD ipCmd;
169 memset(&ipCmd, 0, sizeof(ipCmd));
170 ipCmd.ips[0] = ifa->ifa_local;
171 status = wmi_set_ip_cmd(ar->arWmi, &ipCmd);
172 if (status) {
173 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup IP for ARP agent\n"));
174 }
175 }
176
177#ifndef ATH6K_CONFIG_OTA_MODE
178 wmi_powermode_cmd(ar->arWmi, REC_POWER);
179#endif
180
181 status = wmi_set_wow_mode_cmd(ar->arWmi, &wowMode);
182 if (status) {
183 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enable wow mode\n"));
184 }
185 ar6k_send_asleep_event_to_app(ar, true);
186
187 status = wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode);
188 if (status) {
189 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to set host asleep\n"));
190 }
191
192 ar->arWowState = WLAN_WOW_STATE_SUSPENDING;
193 if (ar->arTxPending[ar->arControlEp]) {
194 u32 timeleft = wait_event_interruptible_timeout(arEvent,
195 ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ);
196 if (!timeleft || signal_pending(current)) {
197 /* what can I do? wow resume at once */
198 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WoW. Pending wmi control data %d\n", ar->arTxPending[ar->arControlEp]));
199 }
200 }
201
202 status = hifWaitForPendingRecv(ar->arHifDevice);
203
204 ar->arWowState = WLAN_WOW_STATE_SUSPENDED;
205 ar->arWlanPowerState = WLAN_POWER_STATE_WOW;
206 } else {
207 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Not allowed to go to WOW at this moment.\n"));
208 }
209}
210
211int ar6000_suspend_ev(void *context)
212{
213 int status = 0;
214 struct ar6_softc *ar = (struct ar6_softc *)context;
215 s16 pmmode = ar->arSuspendConfig;
216wow_not_connected:
217 switch (pmmode) {
218 case WLAN_SUSPEND_WOW:
219 if (ar->arWmiReady && ar->arWlanState==WLAN_ENABLED && ar->arConnected) {
220 ar6000_wow_suspend(ar);
221 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for wow mode %d\n", __func__, ar->arWlanPowerState));
222 } else {
223 pmmode = ar->arWow2Config;
224 goto wow_not_connected;
225 }
226 break;
227 case WLAN_SUSPEND_CUT_PWR:
228 /* fall through */
229 case WLAN_SUSPEND_CUT_PWR_IF_BT_OFF:
230 /* fall through */
231 case WLAN_SUSPEND_DEEP_SLEEP:
232 /* fall through */
233 default:
234 status = ar6000_update_wlan_pwr_state(ar, WLAN_DISABLED, true);
235 if (ar->arWlanPowerState==WLAN_POWER_STATE_ON ||
236 ar->arWlanPowerState==WLAN_POWER_STATE_WOW) {
237 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Strange suspend state for not wow mode %d", ar->arWlanPowerState));
238 }
239 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for %d mode pwr %d status %d\n", __func__, pmmode, ar->arWlanPowerState, status));
240 status = (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) ? 0 : A_EBUSY;
241 break;
242 }
243
244 ar->scan_triggered = 0;
245 return status;
246}
247
248int ar6000_resume_ev(void *context)
249{
250 struct ar6_softc *ar = (struct ar6_softc *)context;
251 u16 powerState = ar->arWlanPowerState;
252
253 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: enter previous state %d wowState %d\n", __func__, powerState, ar->arWowState));
254 switch (powerState) {
255 case WLAN_POWER_STATE_WOW:
256 ar6000_wow_resume(ar);
257 break;
258 case WLAN_POWER_STATE_CUT_PWR:
259 /* fall through */
260 case WLAN_POWER_STATE_DEEP_SLEEP:
261 ar6000_update_wlan_pwr_state(ar, WLAN_ENABLED, true);
262 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Resume for %d mode pwr %d\n", __func__, powerState, ar->arWlanPowerState));
263 break;
264 case WLAN_POWER_STATE_ON:
265 break;
266 default:
267 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange SDIO bus power mode!!\n"));
268 break;
269 }
270 return 0;
271}
272
273void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent)
274{
275 if (ar->arWowState!=WLAN_WOW_STATE_NONE) {
276 if (ar->arWowState==WLAN_WOW_STATE_SUSPENDING) {
277 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("\n%s: Received IRQ while we are wow suspending!!!\n\n", __func__));
278 return;
279 }
280 /* Wow resume from irq interrupt */
281 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: WoW resume from irq thread status %d\n", __func__, ar->arWlanPowerState));
282 ar6000_wow_resume(ar);
283 }
284}
285
286int ar6000_power_change_ev(void *context, u32 config)
287{
288 struct ar6_softc *ar = (struct ar6_softc *)context;
289 int status = 0;
290
291 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: power change event callback %d \n", __func__, config));
292 switch (config) {
293 case HIF_DEVICE_POWER_UP:
294 ar6000_restart_endpoint(ar->arNetDev);
295 status = 0;
296 break;
297 case HIF_DEVICE_POWER_DOWN:
298 case HIF_DEVICE_POWER_CUT:
299 status = 0;
300 break;
301 }
302 return status;
303}
304
305#endif /* CONFIG_PM */
306
307int
308ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
309{
310 int status = 0;
311 HIF_DEVICE_POWER_CHANGE_TYPE config;
312
313 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Cut power %d %d \n", __func__,state, ar->arWlanPowerState));
314#ifdef CONFIG_PM
315 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff));
316#endif
317 do {
318 if (state == WLAN_ENABLED) {
319 /* Not in cut power state.. exit */
320 if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) {
321 break;
322 }
323
324 /* Change the state to ON */
325 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
326
327
328 /* Indicate POWER_UP to HIF */
329 config = HIF_DEVICE_POWER_UP;
330 status = HIFConfigureDevice(ar->arHifDevice,
331 HIF_DEVICE_POWER_STATE_CHANGE,
332 &config,
333 sizeof(HIF_DEVICE_POWER_CHANGE_TYPE));
334
335 if (status == A_PENDING) {
336 } else if (status == 0) {
337 ar6000_restart_endpoint(ar->arNetDev);
338 status = 0;
339 }
340 } else if (state == WLAN_DISABLED) {
341
342
343 /* Already in cut power state.. exit */
344 if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) {
345 break;
346 }
347 ar6000_stop_endpoint(ar->arNetDev, true, false);
348
349 config = HIF_DEVICE_POWER_CUT;
350 status = HIFConfigureDevice(ar->arHifDevice,
351 HIF_DEVICE_POWER_STATE_CHANGE,
352 &config,
353 sizeof(HIF_DEVICE_POWER_CHANGE_TYPE));
354
355 ar->arWlanPowerState = WLAN_POWER_STATE_CUT_PWR;
356 }
357 } while (0);
358
359 return status;
360}
361
362int
363ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
364{
365 int status = 0;
366
367 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Deep sleep %d %d \n", __func__,state, ar->arWlanPowerState));
368#ifdef CONFIG_PM
369 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff));
370#endif
371 do {
372 WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode;
373
374 if (state == WLAN_ENABLED) {
375 u16 fg_start_period;
376
377 /* Not in deep sleep state.. exit */
378 if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) {
379 if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) {
380 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange state when we resume from deep sleep %d\n", ar->arWlanPowerState));
381 }
382 break;
383 }
384
385 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period;
386 hostSleepMode.awake = true;
387 hostSleepMode.asleep = false;
388
389 if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)) != 0) {
390 break;
391 }
392
393 /* Change the state to ON */
394 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
395
396 /* Enable foreground scanning */
397 if ((status=wmi_scanparams_cmd(ar->arWmi, fg_start_period,
398 ar->scParams.fg_end_period,
399 ar->scParams.bg_period,
400 ar->scParams.minact_chdwell_time,
401 ar->scParams.maxact_chdwell_time,
402 ar->scParams.pas_chdwell_time,
403 ar->scParams.shortScanRatio,
404 ar->scParams.scanCtrlFlags,
405 ar->scParams.max_dfsch_act_time,
406 ar->scParams.maxact_scan_per_ssid)) != 0)
407 {
408 break;
409 }
410
411 if (ar->arNetworkType != AP_NETWORK)
412 {
413 if (ar->arSsidLen) {
414 if (ar6000_connect_to_ap(ar) != 0) {
415 /* no need to report error if connection failed */
416 break;
417 }
418 }
419 }
420 } else if (state == WLAN_DISABLED){
421 WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = false };
422
423 /* Already in deep sleep state.. exit */
424 if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) {
425 if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) {
426 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange state when we suspend for deep sleep %d\n", ar->arWlanPowerState));
427 }
428 break;
429 }
430
431 if (ar->arNetworkType != AP_NETWORK)
432 {
433 /* Disconnect from the AP and disable foreground scanning */
434 AR6000_SPIN_LOCK(&ar->arLock, 0);
435 if (ar->arConnected == true || ar->arConnectPending == true) {
436 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
437 wmi_disconnect_cmd(ar->arWmi);
438 } else {
439 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
440 }
441 }
442
443 ar->scan_triggered = 0;
444
445 if ((status=wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0)) != 0) {
446 break;
447 }
448
449 /* make sure we disable wow for deep sleep */
450 if ((status=wmi_set_wow_mode_cmd(ar->arWmi, &wowMode))!= 0)
451 {
452 break;
453 }
454
455 ar6000_TxDataCleanup(ar);
456#ifndef ATH6K_CONFIG_OTA_MODE
457 wmi_powermode_cmd(ar->arWmi, REC_POWER);
458#endif
459
460 hostSleepMode.awake = false;
461 hostSleepMode.asleep = true;
462 if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode))!= 0) {
463 break;
464 }
465 if (ar->arTxPending[ar->arControlEp]) {
466 u32 timeleft = wait_event_interruptible_timeout(arEvent,
467 ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ);
468 if (!timeleft || signal_pending(current)) {
469 status = A_ERROR;
470 break;
471 }
472 }
473 status = hifWaitForPendingRecv(ar->arHifDevice);
474
475 ar->arWlanPowerState = WLAN_POWER_STATE_DEEP_SLEEP;
476 }
477 } while (0);
478
479 if (status) {
480 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enter/exit deep sleep %d\n", state));
481 }
482
483 return status;
484}
485
486int
487ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool pmEvent)
488{
489 int status = 0;
490 u16 powerState, oldPowerState;
491 AR6000_WLAN_STATE oldstate = ar->arWlanState;
492 bool wlanOff = ar->arWlanOff;
493#ifdef CONFIG_PM
494 bool btOff = ar->arBTOff;
495#endif /* CONFIG_PM */
496
497 if ((state!=WLAN_DISABLED && state!=WLAN_ENABLED)) {
498 return A_ERROR;
499 }
500
501 if (ar->bIsDestroyProgress) {
502 return A_EBUSY;
503 }
504
505 if (down_interruptible(&ar->arSem)) {
506 return A_ERROR;
507 }
508
509 if (ar->bIsDestroyProgress) {
510 up(&ar->arSem);
511 return A_EBUSY;
512 }
513
514 ar->arWlanState = wlanOff ? WLAN_DISABLED : state;
515 oldPowerState = ar->arWlanPowerState;
516 if (state == WLAN_ENABLED) {
517 powerState = ar->arWlanPowerState;
518 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WLAN PWR set to ENABLE^^\n"));
519 if (!wlanOff) {
520 if (powerState == WLAN_POWER_STATE_DEEP_SLEEP) {
521 status = ar6000_setup_deep_sleep_state(ar, WLAN_ENABLED);
522 } else if (powerState == WLAN_POWER_STATE_CUT_PWR) {
523 status = ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
524 }
525 }
526#ifdef CONFIG_PM
527 else if (pmEvent && wlanOff) {
528 bool allowCutPwr = ((!ar->arBTSharing) || btOff);
529 if ((powerState==WLAN_POWER_STATE_CUT_PWR) && (!allowCutPwr)) {
530 /* Come out of cut power */
531 ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
532 status = ar6000_setup_deep_sleep_state(ar, WLAN_DISABLED);
533 }
534 }
535#endif /* CONFIG_PM */
536 } else if (state == WLAN_DISABLED) {
537 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WLAN PWR set to DISABLED~\n"));
538 powerState = WLAN_POWER_STATE_DEEP_SLEEP;
539#ifdef CONFIG_PM
540 if (pmEvent) { /* disable due to suspend */
541 bool suspendCutPwr = (ar->arSuspendConfig == WLAN_SUSPEND_CUT_PWR ||
542 (ar->arSuspendConfig == WLAN_SUSPEND_WOW &&
543 ar->arWow2Config==WLAN_SUSPEND_CUT_PWR));
544 bool suspendCutIfBtOff = ((ar->arSuspendConfig ==
545 WLAN_SUSPEND_CUT_PWR_IF_BT_OFF ||
546 (ar->arSuspendConfig == WLAN_SUSPEND_WOW &&
547 ar->arWow2Config==WLAN_SUSPEND_CUT_PWR_IF_BT_OFF)) &&
548 (!ar->arBTSharing || btOff));
549 if ((suspendCutPwr) ||
550 (suspendCutIfBtOff) ||
551 (ar->arWlanState==WLAN_POWER_STATE_CUT_PWR))
552 {
553 powerState = WLAN_POWER_STATE_CUT_PWR;
554 }
555 } else {
556 if ((wlanOff) &&
557 (ar->arWlanOffConfig == WLAN_OFF_CUT_PWR) &&
558 (!ar->arBTSharing || btOff))
559 {
560 /* For BT clock sharing designs, CUT_POWER depend on BT state */
561 powerState = WLAN_POWER_STATE_CUT_PWR;
562 }
563 }
564#endif /* CONFIG_PM */
565
566 if (powerState == WLAN_POWER_STATE_DEEP_SLEEP) {
567 if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) {
568 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Load firmware before set to deep sleep\n"));
569 ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
570 }
571 status = ar6000_setup_deep_sleep_state(ar, WLAN_DISABLED);
572 } else if (powerState == WLAN_POWER_STATE_CUT_PWR) {
573 status = ar6000_setup_cut_power_state(ar, WLAN_DISABLED);
574 }
575
576 }
577
578 if (status) {
579 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WLAN state %d\n", ar->arWlanState));
580 ar->arWlanState = oldstate;
581 } else if (status == 0) {
582 WMI_REPORT_SLEEP_STATE_EVENT wmiSleepEvent, *pSleepEvent = NULL;
583 if ((ar->arWlanPowerState == WLAN_POWER_STATE_ON) && (oldPowerState != WLAN_POWER_STATE_ON)) {
584 wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE;
585 pSleepEvent = &wmiSleepEvent;
586 } else if ((ar->arWlanPowerState != WLAN_POWER_STATE_ON) && (oldPowerState == WLAN_POWER_STATE_ON)) {
587 wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP;
588 pSleepEvent = &wmiSleepEvent;
589 }
590 if (pSleepEvent) {
591 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("SENT WLAN Sleep Event %d\n", wmiSleepEvent.sleepState));
592 }
593 }
594 up(&ar->arSem);
595 return status;
596}
597
598int
599ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 enable)
600{
601#ifdef CONFIG_PM
602 bool off = (enable == 0);
603 int status;
604 if (ar->arBTOff == off) {
605 return 0;
606 }
607 ar->arBTOff = off;
608 status = ar6000_update_wlan_pwr_state(ar, ar->arWlanOff ? WLAN_DISABLED : WLAN_ENABLED, false);
609 return status;
610#else
611 return 0;
612#endif
613}
614
615int
616ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
617{
618 int status;
619 bool off = (state == WLAN_DISABLED);
620 if (ar->arWlanOff == off) {
621 return 0;
622 }
623 ar->arWlanOff = off;
624 status = ar6000_update_wlan_pwr_state(ar, state, false);
625 return status;
626}
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c
new file mode 100644
index 00000000000..ae7c1dd96d8
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c
@@ -0,0 +1,455 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#include "ar6000_drv.h"
25
26#ifdef HTC_RAW_INTERFACE
27
28static void
29ar6000_htc_raw_read_cb(void *Context, struct htc_packet *pPacket)
30{
31 struct ar6_softc *ar = (struct ar6_softc *)Context;
32 raw_htc_buffer *busy;
33 HTC_RAW_STREAM_ID streamID;
34 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
35
36 busy = (raw_htc_buffer *)pPacket->pPktContext;
37 A_ASSERT(busy != NULL);
38
39 if (pPacket->Status == A_ECANCELED) {
40 /*
41 * HTC provides A_ECANCELED status when it doesn't want to be refilled
42 * (probably due to a shutdown)
43 */
44 return;
45 }
46
47 streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
48 A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
49
50#ifdef CF
51 if (down_trylock(&arRaw->raw_htc_read_sem[streamID])) {
52#else
53 if (down_interruptible(&arRaw->raw_htc_read_sem[streamID])) {
54#endif /* CF */
55 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
56 }
57
58 A_ASSERT((pPacket->Status != 0) ||
59 (pPacket->pBuffer == (busy->data + HTC_HEADER_LEN)));
60
61 busy->length = pPacket->ActualLength + HTC_HEADER_LEN;
62 busy->currPtr = HTC_HEADER_LEN;
63 arRaw->read_buffer_available[streamID] = true;
64 //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("raw read cb: 0x%X 0x%X \n", busy->currPtr,busy->length);
65 up(&arRaw->raw_htc_read_sem[streamID]);
66
67 /* Signal the waiting process */
68 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) read process\n", streamID));
69 wake_up_interruptible(&arRaw->raw_htc_read_queue[streamID]);
70}
71
72static void
73ar6000_htc_raw_write_cb(void *Context, struct htc_packet *pPacket)
74{
75 struct ar6_softc *ar = (struct ar6_softc *)Context;
76 raw_htc_buffer *free;
77 HTC_RAW_STREAM_ID streamID;
78 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
79
80 free = (raw_htc_buffer *)pPacket->pPktContext;
81 A_ASSERT(free != NULL);
82
83 if (pPacket->Status == A_ECANCELED) {
84 /*
85 * HTC provides A_ECANCELED status when it doesn't want to be refilled
86 * (probably due to a shutdown)
87 */
88 return;
89 }
90
91 streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
92 A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
93
94#ifdef CF
95 if (down_trylock(&arRaw->raw_htc_write_sem[streamID])) {
96#else
97 if (down_interruptible(&arRaw->raw_htc_write_sem[streamID])) {
98#endif
99 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
100 }
101
102 A_ASSERT(pPacket->pBuffer == (free->data + HTC_HEADER_LEN));
103
104 free->length = 0;
105 arRaw->write_buffer_available[streamID] = true;
106 up(&arRaw->raw_htc_write_sem[streamID]);
107
108 /* Signal the waiting process */
109 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) write process\n", streamID));
110 wake_up_interruptible(&arRaw->raw_htc_write_queue[streamID]);
111}
112
113/* connect to a service */
114static int ar6000_connect_raw_service(struct ar6_softc *ar,
115 HTC_RAW_STREAM_ID StreamID)
116{
117 int status;
118 struct htc_service_connect_resp response;
119 u8 streamNo;
120 struct htc_service_connect_req connect;
121
122 do {
123
124 A_MEMZERO(&connect,sizeof(connect));
125 /* pass the stream ID as meta data to the RAW streams service */
126 streamNo = (u8)StreamID;
127 connect.pMetaData = &streamNo;
128 connect.MetaDataLength = sizeof(u8);
129 /* these fields are the same for all endpoints */
130 connect.EpCallbacks.pContext = ar;
131 connect.EpCallbacks.EpTxComplete = ar6000_htc_raw_write_cb;
132 connect.EpCallbacks.EpRecv = ar6000_htc_raw_read_cb;
133 /* simple interface, we don't need these optional callbacks */
134 connect.EpCallbacks.EpRecvRefill = NULL;
135 connect.EpCallbacks.EpSendFull = NULL;
136 connect.MaxSendQueueDepth = RAW_HTC_WRITE_BUFFERS_NUM;
137
138 /* connect to the raw streams service, we may be able to get 1 or more
139 * connections, depending on WHAT is running on the target */
140 connect.ServiceID = HTC_RAW_STREAMS_SVC;
141
142 A_MEMZERO(&response,sizeof(response));
143
144 /* try to connect to the raw stream, it is okay if this fails with
145 * status HTC_SERVICE_NO_MORE_EP */
146 status = HTCConnectService(ar->arHtcTarget,
147 &connect,
148 &response);
149
150 if (status) {
151 if (response.ConnectRespCode == HTC_SERVICE_NO_MORE_EP) {
152 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC RAW , No more streams allowed \n"));
153 status = 0;
154 }
155 break;
156 }
157
158 /* set endpoint mapping for the RAW HTC streams */
159 arSetRawStream2EndpointIDMap(ar,StreamID,response.Endpoint);
160
161 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("HTC RAW : stream ID: %d, endpoint: %d\n",
162 StreamID, arRawStream2EndpointID(ar,StreamID)));
163
164 } while (false);
165
166 return status;
167}
168
169int ar6000_htc_raw_open(struct ar6_softc *ar)
170{
171 int status;
172 int streamID, endPt, count2;
173 raw_htc_buffer *buffer;
174 HTC_SERVICE_ID servicepriority;
175 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
176 if (!arRaw) {
177 arRaw = ar->arRawHtc = A_MALLOC(sizeof(AR_RAW_HTC_T));
178 if (arRaw) {
179 A_MEMZERO(arRaw, sizeof(AR_RAW_HTC_T));
180 }
181 }
182 A_ASSERT(ar->arHtcTarget != NULL);
183 if (!arRaw) {
184 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Faile to allocate memory for HTC RAW interface\n"));
185 return -ENOMEM;
186 }
187 /* wait for target */
188 status = HTCWaitTarget(ar->arHtcTarget);
189
190 if (status) {
191 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTCWaitTarget failed (%d)\n", status));
192 return -ENODEV;
193 }
194
195 for (endPt = 0; endPt < ENDPOINT_MAX; endPt++) {
196 arRaw->arEp2RawMapping[endPt] = HTC_RAW_STREAM_NOT_MAPPED;
197 }
198
199 for (streamID = HTC_RAW_STREAM_0; streamID < HTC_RAW_STREAM_NUM_MAX; streamID++) {
200 /* Initialize the data structures */
201 sema_init(&arRaw->raw_htc_read_sem[streamID], 1);
202 sema_init(&arRaw->raw_htc_write_sem[streamID], 1);
203 init_waitqueue_head(&arRaw->raw_htc_read_queue[streamID]);
204 init_waitqueue_head(&arRaw->raw_htc_write_queue[streamID]);
205
206 /* try to connect to the raw service */
207 status = ar6000_connect_raw_service(ar,streamID);
208
209 if (status) {
210 break;
211 }
212
213 if (arRawStream2EndpointID(ar,streamID) == 0) {
214 break;
215 }
216
217 for (count2 = 0; count2 < RAW_HTC_READ_BUFFERS_NUM; count2 ++) {
218 /* Initialize the receive buffers */
219 buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
220 memset(buffer, 0, sizeof(raw_htc_buffer));
221 buffer = &arRaw->raw_htc_read_buffer[streamID][count2];
222 memset(buffer, 0, sizeof(raw_htc_buffer));
223
224 SET_HTC_PACKET_INFO_RX_REFILL(&buffer->HTCPacket,
225 buffer,
226 buffer->data,
227 HTC_RAW_BUFFER_SIZE,
228 arRawStream2EndpointID(ar,streamID));
229
230 /* Queue buffers to HTC for receive */
231 if ((status = HTCAddReceivePkt(ar->arHtcTarget, &buffer->HTCPacket)) != 0)
232 {
233 BMIInit();
234 return -EIO;
235 }
236 }
237
238 for (count2 = 0; count2 < RAW_HTC_WRITE_BUFFERS_NUM; count2 ++) {
239 /* Initialize the receive buffers */
240 buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
241 memset(buffer, 0, sizeof(raw_htc_buffer));
242 }
243
244 arRaw->read_buffer_available[streamID] = false;
245 arRaw->write_buffer_available[streamID] = true;
246 }
247
248 if (status) {
249 return -EIO;
250 }
251
252 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("HTC RAW, number of streams the target supports: %d \n", streamID));
253
254 servicepriority = HTC_RAW_STREAMS_SVC; /* only 1 */
255
256 /* set callbacks and priority list */
257 HTCSetCreditDistribution(ar->arHtcTarget,
258 ar,
259 NULL, /* use default */
260 NULL, /* use default */
261 &servicepriority,
262 1);
263
264 /* Start the HTC component */
265 if ((status = HTCStart(ar->arHtcTarget)) != 0) {
266 BMIInit();
267 return -EIO;
268 }
269
270 (ar)->arRawIfInit = true;
271
272 return 0;
273}
274
275int ar6000_htc_raw_close(struct ar6_softc *ar)
276{
277 A_PRINTF("ar6000_htc_raw_close called \n");
278 HTCStop(ar->arHtcTarget);
279
280 /* reset the device */
281 ar6000_reset_device(ar->arHifDevice, ar->arTargetType, true, false);
282 /* Initialize the BMI component */
283 BMIInit();
284
285 return 0;
286}
287
288raw_htc_buffer *
289get_filled_buffer(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID)
290{
291 int count;
292 raw_htc_buffer *busy;
293 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
294
295 /* Check for data */
296 for (count = 0; count < RAW_HTC_READ_BUFFERS_NUM; count ++) {
297 busy = &arRaw->raw_htc_read_buffer[StreamID][count];
298 if (busy->length) {
299 break;
300 }
301 }
302 if (busy->length) {
303 arRaw->read_buffer_available[StreamID] = true;
304 } else {
305 arRaw->read_buffer_available[StreamID] = false;
306 }
307
308 return busy;
309}
310
311ssize_t ar6000_htc_raw_read(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID,
312 char __user *buffer, size_t length)
313{
314 int readPtr;
315 raw_htc_buffer *busy;
316 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
317
318 if (arRawStream2EndpointID(ar,StreamID) == 0) {
319 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID));
320 return -EFAULT;
321 }
322
323 if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) {
324 return -ERESTARTSYS;
325 }
326
327 busy = get_filled_buffer(ar,StreamID);
328 while (!arRaw->read_buffer_available[StreamID]) {
329 up(&arRaw->raw_htc_read_sem[StreamID]);
330
331 /* Wait for the data */
332 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) read process\n", StreamID));
333 if (wait_event_interruptible(arRaw->raw_htc_read_queue[StreamID],
334 arRaw->read_buffer_available[StreamID]))
335 {
336 return -EINTR;
337 }
338 if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) {
339 return -ERESTARTSYS;
340 }
341 busy = get_filled_buffer(ar,StreamID);
342 }
343
344 /* Read the data */
345 readPtr = busy->currPtr;
346 if (length > busy->length - HTC_HEADER_LEN) {
347 length = busy->length - HTC_HEADER_LEN;
348 }
349 if (copy_to_user(buffer, &busy->data[readPtr], length)) {
350 up(&arRaw->raw_htc_read_sem[StreamID]);
351 return -EFAULT;
352 }
353
354 busy->currPtr += length;
355
356 if (busy->currPtr == busy->length)
357 {
358 busy->currPtr = 0;
359 busy->length = 0;
360 HTC_PACKET_RESET_RX(&busy->HTCPacket);
361 //AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("raw read ioctl: ep for packet:%d \n", busy->HTCPacket.Endpoint));
362 HTCAddReceivePkt(ar->arHtcTarget, &busy->HTCPacket);
363 }
364 arRaw->read_buffer_available[StreamID] = false;
365 up(&arRaw->raw_htc_read_sem[StreamID]);
366
367 return length;
368}
369
370static raw_htc_buffer *
371get_free_buffer(struct ar6_softc *ar, HTC_ENDPOINT_ID StreamID)
372{
373 int count;
374 raw_htc_buffer *free;
375 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
376
377 free = NULL;
378 for (count = 0; count < RAW_HTC_WRITE_BUFFERS_NUM; count ++) {
379 free = &arRaw->raw_htc_write_buffer[StreamID][count];
380 if (free->length == 0) {
381 break;
382 }
383 }
384 if (!free->length) {
385 arRaw->write_buffer_available[StreamID] = true;
386 } else {
387 arRaw->write_buffer_available[StreamID] = false;
388 }
389
390 return free;
391}
392
393ssize_t ar6000_htc_raw_write(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID,
394 char __user *buffer, size_t length)
395{
396 int writePtr;
397 raw_htc_buffer *free;
398 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
399 if (arRawStream2EndpointID(ar,StreamID) == 0) {
400 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID));
401 return -EFAULT;
402 }
403
404 if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) {
405 return -ERESTARTSYS;
406 }
407
408 /* Search for a free buffer */
409 free = get_free_buffer(ar,StreamID);
410
411 /* Check if there is space to write else wait */
412 while (!arRaw->write_buffer_available[StreamID]) {
413 up(&arRaw->raw_htc_write_sem[StreamID]);
414
415 /* Wait for buffer to become free */
416 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) write process\n", StreamID));
417 if (wait_event_interruptible(arRaw->raw_htc_write_queue[StreamID],
418 arRaw->write_buffer_available[StreamID]))
419 {
420 return -EINTR;
421 }
422 if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) {
423 return -ERESTARTSYS;
424 }
425 free = get_free_buffer(ar,StreamID);
426 }
427
428 /* Send the data */
429 writePtr = HTC_HEADER_LEN;
430 if (length > (HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN)) {
431 length = HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN;
432 }
433
434 if (copy_from_user(&free->data[writePtr], buffer, length)) {
435 up(&arRaw->raw_htc_read_sem[StreamID]);
436 return -EFAULT;
437 }
438
439 free->length = length;
440
441 SET_HTC_PACKET_INFO_TX(&free->HTCPacket,
442 free,
443 &free->data[writePtr],
444 length,
445 arRawStream2EndpointID(ar,StreamID),
446 AR6K_DATA_PKT_TAG);
447
448 HTCSendPkt(ar->arHtcTarget,&free->HTCPacket);
449
450 arRaw->write_buffer_available[StreamID] = false;
451 up(&arRaw->raw_htc_write_sem[StreamID]);
452
453 return length;
454}
455#endif /* HTC_RAW_INTERFACE */
diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c
new file mode 100644
index 00000000000..5fdda4aa2fe
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/cfg80211.c
@@ -0,0 +1,1892 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#include <linux/wireless.h>
25#include <linux/ieee80211.h>
26#include <net/cfg80211.h>
27#include <net/netlink.h>
28
29#include "ar6000_drv.h"
30
31
32extern A_WAITQUEUE_HEAD arEvent;
33extern unsigned int wmitimeout;
34extern int reconnect_flag;
35
36
37#define RATETAB_ENT(_rate, _rateid, _flags) { \
38 .bitrate = (_rate), \
39 .flags = (_flags), \
40 .hw_value = (_rateid), \
41}
42
43#define CHAN2G(_channel, _freq, _flags) { \
44 .band = IEEE80211_BAND_2GHZ, \
45 .hw_value = (_channel), \
46 .center_freq = (_freq), \
47 .flags = (_flags), \
48 .max_antenna_gain = 0, \
49 .max_power = 30, \
50}
51
52#define CHAN5G(_channel, _flags) { \
53 .band = IEEE80211_BAND_5GHZ, \
54 .hw_value = (_channel), \
55 .center_freq = 5000 + (5 * (_channel)), \
56 .flags = (_flags), \
57 .max_antenna_gain = 0, \
58 .max_power = 30, \
59}
60
61static struct
62ieee80211_rate ar6k_rates[] = {
63 RATETAB_ENT(10, 0x1, 0),
64 RATETAB_ENT(20, 0x2, 0),
65 RATETAB_ENT(55, 0x4, 0),
66 RATETAB_ENT(110, 0x8, 0),
67 RATETAB_ENT(60, 0x10, 0),
68 RATETAB_ENT(90, 0x20, 0),
69 RATETAB_ENT(120, 0x40, 0),
70 RATETAB_ENT(180, 0x80, 0),
71 RATETAB_ENT(240, 0x100, 0),
72 RATETAB_ENT(360, 0x200, 0),
73 RATETAB_ENT(480, 0x400, 0),
74 RATETAB_ENT(540, 0x800, 0),
75};
76
77#define ar6k_a_rates (ar6k_rates + 4)
78#define ar6k_a_rates_size 8
79#define ar6k_g_rates (ar6k_rates + 0)
80#define ar6k_g_rates_size 12
81
82static struct
83ieee80211_channel ar6k_2ghz_channels[] = {
84 CHAN2G(1, 2412, 0),
85 CHAN2G(2, 2417, 0),
86 CHAN2G(3, 2422, 0),
87 CHAN2G(4, 2427, 0),
88 CHAN2G(5, 2432, 0),
89 CHAN2G(6, 2437, 0),
90 CHAN2G(7, 2442, 0),
91 CHAN2G(8, 2447, 0),
92 CHAN2G(9, 2452, 0),
93 CHAN2G(10, 2457, 0),
94 CHAN2G(11, 2462, 0),
95 CHAN2G(12, 2467, 0),
96 CHAN2G(13, 2472, 0),
97 CHAN2G(14, 2484, 0),
98};
99
100static struct
101ieee80211_channel ar6k_5ghz_a_channels[] = {
102 CHAN5G(34, 0), CHAN5G(36, 0),
103 CHAN5G(38, 0), CHAN5G(40, 0),
104 CHAN5G(42, 0), CHAN5G(44, 0),
105 CHAN5G(46, 0), CHAN5G(48, 0),
106 CHAN5G(52, 0), CHAN5G(56, 0),
107 CHAN5G(60, 0), CHAN5G(64, 0),
108 CHAN5G(100, 0), CHAN5G(104, 0),
109 CHAN5G(108, 0), CHAN5G(112, 0),
110 CHAN5G(116, 0), CHAN5G(120, 0),
111 CHAN5G(124, 0), CHAN5G(128, 0),
112 CHAN5G(132, 0), CHAN5G(136, 0),
113 CHAN5G(140, 0), CHAN5G(149, 0),
114 CHAN5G(153, 0), CHAN5G(157, 0),
115 CHAN5G(161, 0), CHAN5G(165, 0),
116 CHAN5G(184, 0), CHAN5G(188, 0),
117 CHAN5G(192, 0), CHAN5G(196, 0),
118 CHAN5G(200, 0), CHAN5G(204, 0),
119 CHAN5G(208, 0), CHAN5G(212, 0),
120 CHAN5G(216, 0),
121};
122
123static struct
124ieee80211_supported_band ar6k_band_2ghz = {
125 .n_channels = ARRAY_SIZE(ar6k_2ghz_channels),
126 .channels = ar6k_2ghz_channels,
127 .n_bitrates = ar6k_g_rates_size,
128 .bitrates = ar6k_g_rates,
129};
130
131static struct
132ieee80211_supported_band ar6k_band_5ghz = {
133 .n_channels = ARRAY_SIZE(ar6k_5ghz_a_channels),
134 .channels = ar6k_5ghz_a_channels,
135 .n_bitrates = ar6k_a_rates_size,
136 .bitrates = ar6k_a_rates,
137};
138
139static int
140ar6k_set_wpa_version(struct ar6_softc *ar, enum nl80211_wpa_versions wpa_version)
141{
142
143 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: %u\n", __func__, wpa_version));
144
145 if (!wpa_version) {
146 ar->arAuthMode = NONE_AUTH;
147 } else if (wpa_version & NL80211_WPA_VERSION_1) {
148 ar->arAuthMode = WPA_AUTH;
149 } else if (wpa_version & NL80211_WPA_VERSION_2) {
150 ar->arAuthMode = WPA2_AUTH;
151 } else {
152 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
153 ("%s: %u not spported\n", __func__, wpa_version));
154 return -ENOTSUPP;
155 }
156
157 return 0;
158}
159
160static int
161ar6k_set_auth_type(struct ar6_softc *ar, enum nl80211_auth_type auth_type)
162{
163
164 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, auth_type));
165
166 switch (auth_type) {
167 case NL80211_AUTHTYPE_OPEN_SYSTEM:
168 ar->arDot11AuthMode = OPEN_AUTH;
169 break;
170 case NL80211_AUTHTYPE_SHARED_KEY:
171 ar->arDot11AuthMode = SHARED_AUTH;
172 break;
173 case NL80211_AUTHTYPE_NETWORK_EAP:
174 ar->arDot11AuthMode = LEAP_AUTH;
175 break;
176
177 case NL80211_AUTHTYPE_AUTOMATIC:
178 ar->arDot11AuthMode = OPEN_AUTH;
179 ar->arAutoAuthStage = AUTH_OPEN_IN_PROGRESS;
180 break;
181
182 default:
183 ar->arDot11AuthMode = OPEN_AUTH;
184 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
185 ("%s: 0x%x not spported\n", __func__, auth_type));
186 return -ENOTSUPP;
187 }
188
189 return 0;
190}
191
192static int
193ar6k_set_cipher(struct ar6_softc *ar, u32 cipher, bool ucast)
194{
195 u8 *ar_cipher = ucast ? &ar->arPairwiseCrypto :
196 &ar->arGroupCrypto;
197 u8 *ar_cipher_len = ucast ? &ar->arPairwiseCryptoLen :
198 &ar->arGroupCryptoLen;
199
200 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
201 ("%s: cipher 0x%x, ucast %u\n", __func__, cipher, ucast));
202
203 switch (cipher) {
204 case 0:
205 case IW_AUTH_CIPHER_NONE:
206 *ar_cipher = NONE_CRYPT;
207 *ar_cipher_len = 0;
208 break;
209 case WLAN_CIPHER_SUITE_WEP40:
210 *ar_cipher = WEP_CRYPT;
211 *ar_cipher_len = 5;
212 break;
213 case WLAN_CIPHER_SUITE_WEP104:
214 *ar_cipher = WEP_CRYPT;
215 *ar_cipher_len = 13;
216 break;
217 case WLAN_CIPHER_SUITE_TKIP:
218 *ar_cipher = TKIP_CRYPT;
219 *ar_cipher_len = 0;
220 break;
221 case WLAN_CIPHER_SUITE_CCMP:
222 *ar_cipher = AES_CRYPT;
223 *ar_cipher_len = 0;
224 break;
225 default:
226 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
227 ("%s: cipher 0x%x not supported\n", __func__, cipher));
228 return -ENOTSUPP;
229 }
230
231 return 0;
232}
233
234static void
235ar6k_set_key_mgmt(struct ar6_softc *ar, u32 key_mgmt)
236{
237 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, key_mgmt));
238
239 if (WLAN_AKM_SUITE_PSK == key_mgmt) {
240 if (WPA_AUTH == ar->arAuthMode) {
241 ar->arAuthMode = WPA_PSK_AUTH;
242 } else if (WPA2_AUTH == ar->arAuthMode) {
243 ar->arAuthMode = WPA2_PSK_AUTH;
244 }
245 } else if (WLAN_AKM_SUITE_8021X != key_mgmt) {
246 ar->arAuthMode = NONE_AUTH;
247 }
248}
249
250static int
251ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
252 struct cfg80211_connect_params *sme)
253{
254 struct ar6_softc *ar = ar6k_priv(dev);
255 int status;
256
257 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
258 ar->smeState = SME_CONNECTING;
259
260 if(ar->arWmiReady == false) {
261 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n", __func__));
262 return -EIO;
263 }
264
265 if(ar->arWlanState == WLAN_DISABLED) {
266 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
267 return -EIO;
268 }
269
270 if(ar->bIsDestroyProgress) {
271 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: destroy in progress\n", __func__));
272 return -EBUSY;
273 }
274
275 if(!sme->ssid_len || IEEE80211_MAX_SSID_LEN < sme->ssid_len) {
276 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
277 return -EINVAL;
278 }
279
280 if(ar->arSkipScan == true &&
281 ((sme->channel && sme->channel->center_freq == 0) ||
282 (sme->bssid && !sme->bssid[0] && !sme->bssid[1] && !sme->bssid[2] &&
283 !sme->bssid[3] && !sme->bssid[4] && !sme->bssid[5])))
284 {
285 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s:SkipScan: channel or bssid invalid\n", __func__));
286 return -EINVAL;
287 }
288
289 if(down_interruptible(&ar->arSem)) {
290 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
291 return -ERESTARTSYS;
292 }
293
294 if(ar->bIsDestroyProgress) {
295 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
296 up(&ar->arSem);
297 return -EBUSY;
298 }
299
300 if(ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) {
301 /*
302 * sleep until the command queue drains
303 */
304 wait_event_interruptible_timeout(arEvent,
305 ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ);
306 if (signal_pending(current)) {
307 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: cmd queue drain timeout\n", __func__));
308 up(&ar->arSem);
309 return -EINTR;
310 }
311 }
312
313 if(ar->arConnected == true &&
314 ar->arSsidLen == sme->ssid_len &&
315 !memcmp(ar->arSsid, sme->ssid, ar->arSsidLen)) {
316 reconnect_flag = true;
317 status = wmi_reconnect_cmd(ar->arWmi,
318 ar->arReqBssid,
319 ar->arChannelHint);
320
321 up(&ar->arSem);
322 if (status) {
323 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_reconnect_cmd failed\n", __func__));
324 return -EIO;
325 }
326 return 0;
327 } else if(ar->arSsidLen == sme->ssid_len &&
328 !memcmp(ar->arSsid, sme->ssid, ar->arSsidLen)) {
329 ar6000_disconnect(ar);
330 }
331
332 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
333 ar->arSsidLen = sme->ssid_len;
334 memcpy(ar->arSsid, sme->ssid, sme->ssid_len);
335
336 if(sme->channel){
337 ar->arChannelHint = sme->channel->center_freq;
338 }
339
340 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
341 if(sme->bssid){
342 if(memcmp(&sme->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
343 memcpy(ar->arReqBssid, sme->bssid, sizeof(ar->arReqBssid));
344 }
345 }
346
347 ar6k_set_wpa_version(ar, sme->crypto.wpa_versions);
348 ar6k_set_auth_type(ar, sme->auth_type);
349
350 if(sme->crypto.n_ciphers_pairwise) {
351 ar6k_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
352 } else {
353 ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
354 }
355 ar6k_set_cipher(ar, sme->crypto.cipher_group, false);
356
357 if(sme->crypto.n_akm_suites) {
358 ar6k_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
359 }
360
361 if((sme->key_len) &&
362 (NONE_AUTH == ar->arAuthMode) &&
363 (WEP_CRYPT == ar->arPairwiseCrypto)) {
364 struct ar_key *key = NULL;
365
366 if(sme->key_idx < WMI_MIN_KEY_INDEX || sme->key_idx > WMI_MAX_KEY_INDEX) {
367 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
368 ("%s: key index %d out of bounds\n", __func__, sme->key_idx));
369 up(&ar->arSem);
370 return -ENOENT;
371 }
372
373 key = &ar->keys[sme->key_idx];
374 key->key_len = sme->key_len;
375 memcpy(key->key, sme->key, key->key_len);
376 key->cipher = ar->arPairwiseCrypto;
377 ar->arDefTxKeyIndex = sme->key_idx;
378
379 wmi_addKey_cmd(ar->arWmi, sme->key_idx,
380 ar->arPairwiseCrypto,
381 GROUP_USAGE | TX_USAGE,
382 key->key_len,
383 NULL,
384 key->key, KEY_OP_INIT_VAL, NULL,
385 NO_SYNC_WMIFLAG);
386 }
387
388 if (!ar->arUserBssFilter) {
389 if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) {
390 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
391 up(&ar->arSem);
392 return -EIO;
393 }
394 }
395
396 ar->arNetworkType = ar->arNextMode;
397
398 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
399 " PW crypto %d PW crypto Len %d GRP crypto %d"\
400 " GRP crypto Len %d channel hint %u\n",
401 __func__, ar->arAuthMode, ar->arDot11AuthMode,
402 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
403 ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
404
405 reconnect_flag = 0;
406 status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
407 ar->arDot11AuthMode, ar->arAuthMode,
408 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
409 ar->arGroupCrypto,ar->arGroupCryptoLen,
410 ar->arSsidLen, ar->arSsid,
411 ar->arReqBssid, ar->arChannelHint,
412 ar->arConnectCtrlFlags);
413
414 up(&ar->arSem);
415
416 if (A_EINVAL == status) {
417 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
418 ar->arSsidLen = 0;
419 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Invalid request\n", __func__));
420 return -ENOENT;
421 } else if (status) {
422 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_connect_cmd failed\n", __func__));
423 return -EIO;
424 }
425
426 if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
427 ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
428 {
429 A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
430 }
431
432 ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
433 ar->arConnectPending = true;
434
435 return 0;
436}
437
438void
439ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel,
440 u8 *bssid, u16 listenInterval,
441 u16 beaconInterval,NETWORK_TYPE networkType,
442 u8 beaconIeLen, u8 assocReqLen,
443 u8 assocRespLen, u8 *assocInfo)
444{
445 u16 size = 0;
446 u16 capability = 0;
447 struct cfg80211_bss *bss = NULL;
448 struct ieee80211_mgmt *mgmt = NULL;
449 struct ieee80211_channel *ibss_channel = NULL;
450 s32 signal = 50 * 100;
451 u8 ie_buf_len = 0;
452 unsigned char ie_buf[256];
453 unsigned char *ptr_ie_buf = ie_buf;
454 unsigned char *ieeemgmtbuf = NULL;
455 u8 source_mac[ATH_MAC_LEN];
456
457 u8 assocReqIeOffset = sizeof(u16) + /* capinfo*/
458 sizeof(u16); /* listen interval */
459 u8 assocRespIeOffset = sizeof(u16) + /* capinfo*/
460 sizeof(u16) + /* status Code */
461 sizeof(u16); /* associd */
462 u8 *assocReqIe = assocInfo + beaconIeLen + assocReqIeOffset;
463 u8 *assocRespIe = assocInfo + beaconIeLen + assocReqLen + assocRespIeOffset;
464
465 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
466
467 assocReqLen -= assocReqIeOffset;
468 assocRespLen -= assocRespIeOffset;
469
470 ar->arAutoAuthStage = AUTH_IDLE;
471
472 if((ADHOC_NETWORK & networkType)) {
473 if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
474 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
475 ("%s: ath6k not in ibss mode\n", __func__));
476 return;
477 }
478 }
479
480 if((INFRA_NETWORK & networkType)) {
481 if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
482 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
483 ("%s: ath6k not in station mode\n", __func__));
484 return;
485 }
486 }
487
488 /* Before informing the join/connect event, make sure that
489 * bss entry is present in scan list, if it not present
490 * construct and insert into scan list, otherwise that
491 * event will be dropped on the way by cfg80211, due to
492 * this keys will not be plumbed in case of WEP and
493 * application will not be aware of join/connect status. */
494 bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid,
495 ar->wdev->ssid, ar->wdev->ssid_len,
496 ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS),
497 ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS));
498
499 /*
500 * Earlier we were updating the cfg about bss by making a beacon frame
501 * only if the entry for bss is not there. This can have some issue if
502 * ROAM event is generated and a heavy traffic is ongoing. The ROAM
503 * event is handled through a work queue and by the time it really gets
504 * handled, BSS would have been aged out. So it is better to update the
505 * cfg about BSS irrespective of its entry being present right now or
506 * not.
507 */
508
509 if (ADHOC_NETWORK & networkType) {
510 /* construct 802.11 mgmt beacon */
511 if(ptr_ie_buf) {
512 *ptr_ie_buf++ = WLAN_EID_SSID;
513 *ptr_ie_buf++ = ar->arSsidLen;
514 memcpy(ptr_ie_buf, ar->arSsid, ar->arSsidLen);
515 ptr_ie_buf +=ar->arSsidLen;
516
517 *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
518 *ptr_ie_buf++ = 2; /* length */
519 *ptr_ie_buf++ = 0; /* ATIM window */
520 *ptr_ie_buf++ = 0; /* ATIM window */
521
522 /* TODO: update ibss params and include supported rates,
523 * DS param set, extened support rates, wmm. */
524
525 ie_buf_len = ptr_ie_buf - ie_buf;
526 }
527
528 capability |= IEEE80211_CAPINFO_IBSS;
529 if(WEP_CRYPT == ar->arPairwiseCrypto) {
530 capability |= IEEE80211_CAPINFO_PRIVACY;
531 }
532 memcpy(source_mac, ar->arNetDev->dev_addr, ATH_MAC_LEN);
533 ptr_ie_buf = ie_buf;
534 } else {
535 capability = *(u16 *)(&assocInfo[beaconIeLen]);
536 memcpy(source_mac, bssid, ATH_MAC_LEN);
537 ptr_ie_buf = assocReqIe;
538 ie_buf_len = assocReqLen;
539 }
540
541 size = offsetof(struct ieee80211_mgmt, u)
542 + sizeof(mgmt->u.beacon)
543 + ie_buf_len;
544
545 ieeemgmtbuf = A_MALLOC_NOWAIT(size);
546 if(!ieeemgmtbuf) {
547 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
548 ("%s: ieeeMgmtbuf alloc error\n", __func__));
549 cfg80211_put_bss(bss);
550 return;
551 }
552
553 A_MEMZERO(ieeemgmtbuf, size);
554 mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
555 mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
556 memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
557 memcpy(mgmt->sa, source_mac, ATH_MAC_LEN);
558 memcpy(mgmt->bssid, bssid, ATH_MAC_LEN);
559 mgmt->u.beacon.beacon_int = beaconInterval;
560 mgmt->u.beacon.capab_info = capability;
561 memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
562
563 ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
564
565 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
566 ("%s: inform bss with bssid %pM channel %d beaconInterval %d "
567 "capability 0x%x\n", __func__, mgmt->bssid,
568 ibss_channel->hw_value, beaconInterval, capability));
569
570 bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
571 ibss_channel, mgmt,
572 le16_to_cpu(size),
573 signal, GFP_KERNEL);
574 kfree(ieeemgmtbuf);
575 cfg80211_put_bss(bss);
576
577 if((ADHOC_NETWORK & networkType)) {
578 cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
579 return;
580 }
581
582 if (false == ar->arConnected) {
583 /* inform connect result to cfg80211 */
584 ar->smeState = SME_DISCONNECTED;
585 cfg80211_connect_result(ar->arNetDev, bssid,
586 assocReqIe, assocReqLen,
587 assocRespIe, assocRespLen,
588 WLAN_STATUS_SUCCESS, GFP_KERNEL);
589 } else {
590 /* inform roam event to cfg80211 */
591 cfg80211_roamed(ar->arNetDev, ibss_channel, bssid,
592 assocReqIe, assocReqLen,
593 assocRespIe, assocRespLen,
594 GFP_KERNEL);
595 }
596}
597
598static int
599ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
600 u16 reason_code)
601{
602 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
603
604 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason_code));
605
606 if(ar->arWmiReady == false) {
607 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
608 return -EIO;
609 }
610
611 if(ar->arWlanState == WLAN_DISABLED) {
612 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
613 return -EIO;
614 }
615
616 if(ar->bIsDestroyProgress) {
617 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
618 return -EBUSY;
619 }
620
621 if(down_interruptible(&ar->arSem)) {
622 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
623 return -ERESTARTSYS;
624 }
625
626 reconnect_flag = 0;
627 ar6000_disconnect(ar);
628 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
629 ar->arSsidLen = 0;
630
631 if (ar->arSkipScan == false) {
632 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
633 }
634
635 up(&ar->arSem);
636
637 return 0;
638}
639
640void
641ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason,
642 u8 *bssid, u8 assocRespLen,
643 u8 *assocInfo, u16 protocolReasonStatus)
644{
645
646 u16 status;
647
648 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
649
650 if (ar->scan_request) {
651 cfg80211_scan_done(ar->scan_request, true);
652 ar->scan_request = NULL;
653 }
654 if((ADHOC_NETWORK & ar->arNetworkType)) {
655 if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
656 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
657 ("%s: ath6k not in ibss mode\n", __func__));
658 return;
659 }
660 A_MEMZERO(bssid, ETH_ALEN);
661 cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
662 return;
663 }
664
665 if((INFRA_NETWORK & ar->arNetworkType)) {
666 if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
667 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
668 ("%s: ath6k not in station mode\n", __func__));
669 return;
670 }
671 }
672
673 if(true == ar->arConnectPending) {
674 if(NO_NETWORK_AVAIL == reason) {
675 /* connect cmd failed */
676 wmi_disconnect_cmd(ar->arWmi);
677 } else if (reason == DISCONNECT_CMD) {
678 if (ar->arAutoAuthStage) {
679 /*
680 * If the current auth algorithm is open try shared
681 * and make autoAuthStage idle. We do not make it
682 * leap for now being.
683 */
684 if (ar->arDot11AuthMode == OPEN_AUTH) {
685 struct ar_key *key = NULL;
686 key = &ar->keys[ar->arDefTxKeyIndex];
687 if (down_interruptible(&ar->arSem)) {
688 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
689 return;
690 }
691
692
693 ar->arDot11AuthMode = SHARED_AUTH;
694 ar->arAutoAuthStage = AUTH_IDLE;
695
696 wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
697 ar->arPairwiseCrypto,
698 GROUP_USAGE | TX_USAGE,
699 key->key_len,
700 NULL,
701 key->key, KEY_OP_INIT_VAL, NULL,
702 NO_SYNC_WMIFLAG);
703
704 status = wmi_connect_cmd(ar->arWmi,
705 ar->arNetworkType,
706 ar->arDot11AuthMode,
707 ar->arAuthMode,
708 ar->arPairwiseCrypto,
709 ar->arPairwiseCryptoLen,
710 ar->arGroupCrypto,
711 ar->arGroupCryptoLen,
712 ar->arSsidLen,
713 ar->arSsid,
714 ar->arReqBssid,
715 ar->arChannelHint,
716 ar->arConnectCtrlFlags);
717 up(&ar->arSem);
718
719 } else if (ar->arDot11AuthMode == SHARED_AUTH) {
720 /* should not reach here */
721 }
722 } else {
723 ar->arConnectPending = false;
724 if (ar->smeState == SME_CONNECTING) {
725 cfg80211_connect_result(ar->arNetDev, bssid,
726 NULL, 0,
727 NULL, 0,
728 WLAN_STATUS_UNSPECIFIED_FAILURE,
729 GFP_KERNEL);
730 } else {
731 cfg80211_disconnected(ar->arNetDev,
732 reason,
733 NULL, 0,
734 GFP_KERNEL);
735 }
736 ar->smeState = SME_DISCONNECTED;
737 }
738 }
739 } else {
740 if (reason != DISCONNECT_CMD)
741 wmi_disconnect_cmd(ar->arWmi);
742 }
743}
744
745void
746ar6k_cfg80211_scan_node(void *arg, bss_t *ni)
747{
748 struct wiphy *wiphy = (struct wiphy *)arg;
749 u16 size;
750 unsigned char *ieeemgmtbuf = NULL;
751 struct ieee80211_mgmt *mgmt;
752 struct ieee80211_channel *channel;
753 struct ieee80211_supported_band *band;
754 struct ieee80211_common_ie *cie;
755 s32 signal;
756 int freq;
757
758 cie = &ni->ni_cie;
759
760#define CHAN_IS_11A(x) (!((x >= 2412) && (x <= 2484)))
761 if(CHAN_IS_11A(cie->ie_chan)) {
762 /* 11a */
763 band = wiphy->bands[IEEE80211_BAND_5GHZ];
764 } else if((cie->ie_erp) || (cie->ie_xrates)) {
765 /* 11g */
766 band = wiphy->bands[IEEE80211_BAND_2GHZ];
767 } else {
768 /* 11b */
769 band = wiphy->bands[IEEE80211_BAND_2GHZ];
770 }
771
772 size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
773 ieeemgmtbuf = A_MALLOC_NOWAIT(size);
774 if(!ieeemgmtbuf)
775 {
776 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ieeeMgmtbuf alloc error\n", __func__));
777 return;
778 }
779
780 /* Note:
781 TODO: Update target to include 802.11 mac header while sending bss info.
782 Target removes 802.11 mac header while sending the bss info to host,
783 cfg80211 needs it, for time being just filling the da, sa and bssid fields alone.
784 */
785 mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
786 memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
787 memcpy(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN);
788 memcpy(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN);
789 memcpy(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
790 ni->ni_buf, ni->ni_framelen);
791
792 freq = cie->ie_chan;
793 channel = ieee80211_get_channel(wiphy, freq);
794 signal = ni->ni_snr * 100;
795
796 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
797 ("%s: bssid %pM channel %d freq %d size %d\n", __func__,
798 mgmt->bssid, channel->hw_value, freq, size));
799 cfg80211_inform_bss_frame(wiphy, channel, mgmt,
800 le16_to_cpu(size),
801 signal, GFP_KERNEL);
802
803 kfree (ieeemgmtbuf);
804}
805
806static int
807ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
808 struct cfg80211_scan_request *request)
809{
810 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
811 int ret = 0;
812 u32 forceFgScan = 0;
813
814 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
815
816 if(ar->arWmiReady == false) {
817 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
818 return -EIO;
819 }
820
821 if(ar->arWlanState == WLAN_DISABLED) {
822 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
823 return -EIO;
824 }
825
826 if (!ar->arUserBssFilter) {
827 if (wmi_bssfilter_cmd(ar->arWmi,
828 (ar->arConnected ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER),
829 0) != 0) {
830 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
831 return -EIO;
832 }
833 }
834
835 if(request->n_ssids &&
836 request->ssids[0].ssid_len) {
837 u8 i;
838
839 if(request->n_ssids > (MAX_PROBED_SSID_INDEX - 1)) {
840 request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
841 }
842
843 for (i = 0; i < request->n_ssids; i++) {
844 wmi_probedSsid_cmd(ar->arWmi, i+1, SPECIFIC_SSID_FLAG,
845 request->ssids[i].ssid_len,
846 request->ssids[i].ssid);
847 }
848 }
849
850 if(ar->arConnected) {
851 forceFgScan = 1;
852 }
853
854 if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, false, \
855 0, 0, 0, NULL) != 0) {
856 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_startscan_cmd failed\n", __func__));
857 ret = -EIO;
858 }
859
860 ar->scan_request = request;
861
862 return ret;
863}
864
865void
866ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status)
867{
868
869 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status));
870
871 if (!ar->scan_request)
872 return;
873
874 if ((status == A_ECANCELED) || (status == A_EBUSY)) {
875 cfg80211_scan_done(ar->scan_request, true);
876 goto out;
877 }
878
879 /* Translate data to cfg80211 mgmt format */
880 wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
881
882 cfg80211_scan_done(ar->scan_request, false);
883
884 if(ar->scan_request->n_ssids &&
885 ar->scan_request->ssids[0].ssid_len) {
886 u8 i;
887
888 for (i = 0; i < ar->scan_request->n_ssids; i++) {
889 wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG,
890 0, NULL);
891 }
892 }
893
894out:
895 ar->scan_request = NULL;
896}
897
898static int
899ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
900 u8 key_index, bool pairwise, const u8 *mac_addr,
901 struct key_params *params)
902{
903 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
904 struct ar_key *key = NULL;
905 u8 key_usage;
906 u8 key_type;
907 int status = 0;
908
909 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__));
910
911 if(ar->arWmiReady == false) {
912 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
913 return -EIO;
914 }
915
916 if(ar->arWlanState == WLAN_DISABLED) {
917 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
918 return -EIO;
919 }
920
921 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
922 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
923 ("%s: key index %d out of bounds\n", __func__, key_index));
924 return -ENOENT;
925 }
926
927 key = &ar->keys[key_index];
928 A_MEMZERO(key, sizeof(struct ar_key));
929
930 if(!mac_addr || is_broadcast_ether_addr(mac_addr)) {
931 key_usage = GROUP_USAGE;
932 } else {
933 key_usage = PAIRWISE_USAGE;
934 }
935
936 if(params) {
937 if(params->key_len > WLAN_MAX_KEY_LEN ||
938 params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
939 return -EINVAL;
940
941 key->key_len = params->key_len;
942 memcpy(key->key, params->key, key->key_len);
943 key->seq_len = params->seq_len;
944 memcpy(key->seq, params->seq, key->seq_len);
945 key->cipher = params->cipher;
946 }
947
948 switch (key->cipher) {
949 case WLAN_CIPHER_SUITE_WEP40:
950 case WLAN_CIPHER_SUITE_WEP104:
951 key_type = WEP_CRYPT;
952 break;
953
954 case WLAN_CIPHER_SUITE_TKIP:
955 key_type = TKIP_CRYPT;
956 break;
957
958 case WLAN_CIPHER_SUITE_CCMP:
959 key_type = AES_CRYPT;
960 break;
961
962 default:
963 return -ENOTSUPP;
964 }
965
966 if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
967 (GROUP_USAGE & key_usage))
968 {
969 A_UNTIMEOUT(&ar->disconnect_timer);
970 }
971
972 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
973 ("%s: index %d, key_len %d, key_type 0x%x,"\
974 " key_usage 0x%x, seq_len %d\n",
975 __func__, key_index, key->key_len, key_type,
976 key_usage, key->seq_len));
977
978 ar->arDefTxKeyIndex = key_index;
979 status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, key_type, key_usage,
980 key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
981 (u8 *)mac_addr, SYNC_BOTH_WMIFLAG);
982
983
984 if (status) {
985 return -EIO;
986 }
987
988 return 0;
989}
990
991static int
992ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
993 u8 key_index, bool pairwise, const u8 *mac_addr)
994{
995 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
996
997 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
998
999 if(ar->arWmiReady == false) {
1000 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1001 return -EIO;
1002 }
1003
1004 if(ar->arWlanState == WLAN_DISABLED) {
1005 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1006 return -EIO;
1007 }
1008
1009 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1010 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1011 ("%s: key index %d out of bounds\n", __func__, key_index));
1012 return -ENOENT;
1013 }
1014
1015 if(!ar->keys[key_index].key_len) {
1016 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d is empty\n", __func__, key_index));
1017 return 0;
1018 }
1019
1020 ar->keys[key_index].key_len = 0;
1021
1022 return wmi_deleteKey_cmd(ar->arWmi, key_index);
1023}
1024
1025
1026static int
1027ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1028 u8 key_index, bool pairwise, const u8 *mac_addr,
1029 void *cookie,
1030 void (*callback)(void *cookie, struct key_params*))
1031{
1032 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1033 struct ar_key *key = NULL;
1034 struct key_params params;
1035
1036 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1037
1038 if(ar->arWmiReady == false) {
1039 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1040 return -EIO;
1041 }
1042
1043 if(ar->arWlanState == WLAN_DISABLED) {
1044 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1045 return -EIO;
1046 }
1047
1048 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1049 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1050 ("%s: key index %d out of bounds\n", __func__, key_index));
1051 return -ENOENT;
1052 }
1053
1054 key = &ar->keys[key_index];
1055 A_MEMZERO(&params, sizeof(params));
1056 params.cipher = key->cipher;
1057 params.key_len = key->key_len;
1058 params.seq_len = key->seq_len;
1059 params.seq = key->seq;
1060 params.key = key->key;
1061
1062 callback(cookie, &params);
1063
1064 return key->key_len ? 0 : -ENOENT;
1065}
1066
1067
1068static int
1069ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev,
1070 u8 key_index, bool unicast, bool multicast)
1071{
1072 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1073 struct ar_key *key = NULL;
1074 int status = 0;
1075 u8 key_usage;
1076
1077 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1078
1079 if(ar->arWmiReady == false) {
1080 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1081 return -EIO;
1082 }
1083
1084 if(ar->arWlanState == WLAN_DISABLED) {
1085 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1086 return -EIO;
1087 }
1088
1089 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1090 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1091 ("%s: key index %d out of bounds\n",
1092 __func__, key_index));
1093 return -ENOENT;
1094 }
1095
1096 if(!ar->keys[key_index].key_len) {
1097 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: invalid key index %d\n",
1098 __func__, key_index));
1099 return -EINVAL;
1100 }
1101
1102 ar->arDefTxKeyIndex = key_index;
1103 key = &ar->keys[ar->arDefTxKeyIndex];
1104 key_usage = GROUP_USAGE;
1105 if (WEP_CRYPT == ar->arPairwiseCrypto) {
1106 key_usage |= TX_USAGE;
1107 }
1108
1109 status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
1110 ar->arPairwiseCrypto, key_usage,
1111 key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
1112 NULL, SYNC_BOTH_WMIFLAG);
1113 if (status) {
1114 return -EIO;
1115 }
1116
1117 return 0;
1118}
1119
1120static int
1121ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev,
1122 u8 key_index)
1123{
1124 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1125
1126 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1127
1128 if(ar->arWmiReady == false) {
1129 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1130 return -EIO;
1131 }
1132
1133 if(ar->arWlanState == WLAN_DISABLED) {
1134 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1135 return -EIO;
1136 }
1137
1138 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1139 return -ENOTSUPP;
1140}
1141
1142void
1143ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast)
1144{
1145 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1146 ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast));
1147
1148 cfg80211_michael_mic_failure(ar->arNetDev, ar->arBssid,
1149 (ismcast ? NL80211_KEYTYPE_GROUP : NL80211_KEYTYPE_PAIRWISE),
1150 keyid, NULL, GFP_KERNEL);
1151}
1152
1153static int
1154ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1155{
1156 struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1157
1158 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: changed 0x%x\n", __func__, changed));
1159
1160 if(ar->arWmiReady == false) {
1161 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1162 return -EIO;
1163 }
1164
1165 if(ar->arWlanState == WLAN_DISABLED) {
1166 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1167 return -EIO;
1168 }
1169
1170 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1171 if (wmi_set_rts_cmd(ar->arWmi,wiphy->rts_threshold) != 0){
1172 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_set_rts_cmd failed\n", __func__));
1173 return -EIO;
1174 }
1175 }
1176
1177 return 0;
1178}
1179
1180static int
1181ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1182 const u8 *peer,
1183 const struct cfg80211_bitrate_mask *mask)
1184{
1185 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Setting rates: Not supported\n"));
1186 return -EIO;
1187}
1188
1189/* The type nl80211_tx_power_setting replaces the following data type from 2.6.36 onwards */
1190static int
1191ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm)
1192{
1193 struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1194 u8 ar_dbm;
1195
1196 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm));
1197
1198 if(ar->arWmiReady == false) {
1199 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1200 return -EIO;
1201 }
1202
1203 if(ar->arWlanState == WLAN_DISABLED) {
1204 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1205 return -EIO;
1206 }
1207
1208 ar->arTxPwrSet = false;
1209 switch(type) {
1210 case NL80211_TX_POWER_AUTOMATIC:
1211 return 0;
1212 case NL80211_TX_POWER_LIMITED:
1213 ar->arTxPwr = ar_dbm = dbm;
1214 ar->arTxPwrSet = true;
1215 break;
1216 default:
1217 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x not supported\n", __func__, type));
1218 return -EOPNOTSUPP;
1219 }
1220
1221 wmi_set_txPwr_cmd(ar->arWmi, ar_dbm);
1222
1223 return 0;
1224}
1225
1226static int
1227ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1228{
1229 struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1230
1231 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1232
1233 if(ar->arWmiReady == false) {
1234 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1235 return -EIO;
1236 }
1237
1238 if(ar->arWlanState == WLAN_DISABLED) {
1239 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1240 return -EIO;
1241 }
1242
1243 if((ar->arConnected == true)) {
1244 ar->arTxPwr = 0;
1245
1246 if(wmi_get_txPwr_cmd(ar->arWmi) != 0) {
1247 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_get_txPwr_cmd failed\n", __func__));
1248 return -EIO;
1249 }
1250
1251 wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, 5 * HZ);
1252
1253 if(signal_pending(current)) {
1254 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Target did not respond\n", __func__));
1255 return -EINTR;
1256 }
1257 }
1258
1259 *dbm = ar->arTxPwr;
1260 return 0;
1261}
1262
1263static int
1264ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1265 struct net_device *dev,
1266 bool pmgmt, int timeout)
1267{
1268 struct ar6_softc *ar = ar6k_priv(dev);
1269 WMI_POWER_MODE_CMD pwrMode;
1270
1271 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: pmgmt %d, timeout %d\n", __func__, pmgmt, timeout));
1272
1273 if(ar->arWmiReady == false) {
1274 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1275 return -EIO;
1276 }
1277
1278 if(ar->arWlanState == WLAN_DISABLED) {
1279 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1280 return -EIO;
1281 }
1282
1283 if(pmgmt) {
1284 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Max Perf\n", __func__));
1285 pwrMode.powerMode = REC_POWER;
1286 } else {
1287 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Rec Power\n", __func__));
1288 pwrMode.powerMode = MAX_PERF_POWER;
1289 }
1290
1291 if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != 0) {
1292 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_powermode_cmd failed\n", __func__));
1293 return -EIO;
1294 }
1295
1296 return 0;
1297}
1298
1299static struct net_device *
1300ar6k_cfg80211_add_virtual_intf(struct wiphy *wiphy, char *name,
1301 enum nl80211_iftype type, u32 *flags,
1302 struct vif_params *params)
1303{
1304
1305 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1306
1307 /* Multiple virtual interface is not supported.
1308 * The default interface supports STA and IBSS type
1309 */
1310 return ERR_PTR(-EOPNOTSUPP);
1311}
1312
1313static int
1314ar6k_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
1315{
1316
1317 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1318
1319 /* Multiple virtual interface is not supported.
1320 * The default interface supports STA and IBSS type
1321 */
1322 return -EOPNOTSUPP;
1323}
1324
1325static int
1326ar6k_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
1327 enum nl80211_iftype type, u32 *flags,
1328 struct vif_params *params)
1329{
1330 struct ar6_softc *ar = ar6k_priv(ndev);
1331 struct wireless_dev *wdev = ar->wdev;
1332
1333 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type %u\n", __func__, type));
1334
1335 if(ar->arWmiReady == false) {
1336 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1337 return -EIO;
1338 }
1339
1340 if(ar->arWlanState == WLAN_DISABLED) {
1341 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1342 return -EIO;
1343 }
1344
1345 switch (type) {
1346 case NL80211_IFTYPE_STATION:
1347 ar->arNextMode = INFRA_NETWORK;
1348 break;
1349 case NL80211_IFTYPE_ADHOC:
1350 ar->arNextMode = ADHOC_NETWORK;
1351 break;
1352 default:
1353 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: type %u\n", __func__, type));
1354 return -EOPNOTSUPP;
1355 }
1356
1357 wdev->iftype = type;
1358
1359 return 0;
1360}
1361
1362static int
1363ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1364 struct cfg80211_ibss_params *ibss_param)
1365{
1366 struct ar6_softc *ar = ar6k_priv(dev);
1367 int status;
1368
1369 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1370
1371 if(ar->arWmiReady == false) {
1372 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1373 return -EIO;
1374 }
1375
1376 if(ar->arWlanState == WLAN_DISABLED) {
1377 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1378 return -EIO;
1379 }
1380
1381 if(!ibss_param->ssid_len || IEEE80211_MAX_SSID_LEN < ibss_param->ssid_len) {
1382 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
1383 return -EINVAL;
1384 }
1385
1386 ar->arSsidLen = ibss_param->ssid_len;
1387 memcpy(ar->arSsid, ibss_param->ssid, ar->arSsidLen);
1388
1389 if(ibss_param->channel) {
1390 ar->arChannelHint = ibss_param->channel->center_freq;
1391 }
1392
1393 if(ibss_param->channel_fixed) {
1394 /* TODO: channel_fixed: The channel should be fixed, do not search for
1395 * IBSSs to join on other channels. Target firmware does not support this
1396 * feature, needs to be updated.*/
1397 }
1398
1399 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
1400 if(ibss_param->bssid) {
1401 if(memcmp(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
1402 memcpy(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid));
1403 }
1404 }
1405
1406 ar6k_set_wpa_version(ar, 0);
1407 ar6k_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1408
1409 if(ibss_param->privacy) {
1410 ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1411 ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1412 } else {
1413 ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
1414 ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, false);
1415 }
1416
1417 ar->arNetworkType = ar->arNextMode;
1418
1419 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
1420 " PW crypto %d PW crypto Len %d GRP crypto %d"\
1421 " GRP crypto Len %d channel hint %u\n",
1422 __func__, ar->arAuthMode, ar->arDot11AuthMode,
1423 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1424 ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
1425
1426 status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
1427 ar->arDot11AuthMode, ar->arAuthMode,
1428 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1429 ar->arGroupCrypto,ar->arGroupCryptoLen,
1430 ar->arSsidLen, ar->arSsid,
1431 ar->arReqBssid, ar->arChannelHint,
1432 ar->arConnectCtrlFlags);
1433 ar->arConnectPending = true;
1434
1435 return 0;
1436}
1437
1438static int
1439ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1440{
1441 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
1442
1443 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1444
1445 if(ar->arWmiReady == false) {
1446 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1447 return -EIO;
1448 }
1449
1450 if(ar->arWlanState == WLAN_DISABLED) {
1451 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1452 return -EIO;
1453 }
1454
1455 ar6000_disconnect(ar);
1456 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1457 ar->arSsidLen = 0;
1458
1459 return 0;
1460}
1461
1462#ifdef CONFIG_NL80211_TESTMODE
1463enum ar6k_testmode_attr {
1464 __AR6K_TM_ATTR_INVALID = 0,
1465 AR6K_TM_ATTR_CMD = 1,
1466 AR6K_TM_ATTR_DATA = 2,
1467
1468 /* keep last */
1469 __AR6K_TM_ATTR_AFTER_LAST,
1470 AR6K_TM_ATTR_MAX = __AR6K_TM_ATTR_AFTER_LAST - 1
1471};
1472
1473enum ar6k_testmode_cmd {
1474 AR6K_TM_CMD_TCMD = 0,
1475 AR6K_TM_CMD_RX_REPORT = 1,
1476};
1477
1478#define AR6K_TM_DATA_MAX_LEN 5000
1479
1480static const struct nla_policy ar6k_testmode_policy[AR6K_TM_ATTR_MAX + 1] = {
1481 [AR6K_TM_ATTR_CMD] = { .type = NLA_U32 },
1482 [AR6K_TM_ATTR_DATA] = { .type = NLA_BINARY,
1483 .len = AR6K_TM_DATA_MAX_LEN },
1484};
1485
1486void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf,
1487 int buf_len)
1488{
1489 if (down_interruptible(&ar->arSem))
1490 return;
1491
1492 kfree(ar->tcmd_rx_report);
1493
1494 ar->tcmd_rx_report = kmemdup(buf, buf_len, GFP_KERNEL);
1495 ar->tcmd_rx_report_len = buf_len;
1496
1497 up(&ar->arSem);
1498
1499 wake_up(&arEvent);
1500}
1501
1502static int ar6000_testmode_rx_report(struct ar6_softc *ar, void *buf,
1503 int buf_len, struct sk_buff *skb)
1504{
1505 int ret = 0;
1506 long left;
1507
1508 if (down_interruptible(&ar->arSem))
1509 return -ERESTARTSYS;
1510
1511 if (ar->arWmiReady == false) {
1512 ret = -EIO;
1513 goto out;
1514 }
1515
1516 if (ar->bIsDestroyProgress) {
1517 ret = -EBUSY;
1518 goto out;
1519 }
1520
1521 WARN_ON(ar->tcmd_rx_report != NULL);
1522 WARN_ON(ar->tcmd_rx_report_len > 0);
1523
1524 if (wmi_test_cmd(ar->arWmi, buf, buf_len) < 0) {
1525 up(&ar->arSem);
1526 return -EIO;
1527 }
1528
1529 left = wait_event_interruptible_timeout(arEvent,
1530 ar->tcmd_rx_report != NULL,
1531 wmitimeout * HZ);
1532
1533 if (left == 0) {
1534 ret = -ETIMEDOUT;
1535 goto out;
1536 } else if (left < 0) {
1537 ret = left;
1538 goto out;
1539 }
1540
1541 if (ar->tcmd_rx_report == NULL || ar->tcmd_rx_report_len == 0) {
1542 ret = -EINVAL;
1543 goto out;
1544 }
1545
1546 NLA_PUT(skb, AR6K_TM_ATTR_DATA, ar->tcmd_rx_report_len,
1547 ar->tcmd_rx_report);
1548
1549 kfree(ar->tcmd_rx_report);
1550 ar->tcmd_rx_report = NULL;
1551
1552out:
1553 up(&ar->arSem);
1554
1555 return ret;
1556
1557nla_put_failure:
1558 ret = -ENOBUFS;
1559 goto out;
1560}
1561
1562static int ar6k_testmode_cmd(struct wiphy *wiphy, void *data, int len)
1563{
1564 struct ar6_softc *ar = wiphy_priv(wiphy);
1565 struct nlattr *tb[AR6K_TM_ATTR_MAX + 1];
1566 int err, buf_len, reply_len;
1567 struct sk_buff *skb;
1568 void *buf;
1569
1570 err = nla_parse(tb, AR6K_TM_ATTR_MAX, data, len,
1571 ar6k_testmode_policy);
1572 if (err)
1573 return err;
1574
1575 if (!tb[AR6K_TM_ATTR_CMD])
1576 return -EINVAL;
1577
1578 switch (nla_get_u32(tb[AR6K_TM_ATTR_CMD])) {
1579 case AR6K_TM_CMD_TCMD:
1580 if (!tb[AR6K_TM_ATTR_DATA])
1581 return -EINVAL;
1582
1583 buf = nla_data(tb[AR6K_TM_ATTR_DATA]);
1584 buf_len = nla_len(tb[AR6K_TM_ATTR_DATA]);
1585
1586 wmi_test_cmd(ar->arWmi, buf, buf_len);
1587
1588 return 0;
1589
1590 break;
1591 case AR6K_TM_CMD_RX_REPORT:
1592 if (!tb[AR6K_TM_ATTR_DATA])
1593 return -EINVAL;
1594
1595 buf = nla_data(tb[AR6K_TM_ATTR_DATA]);
1596 buf_len = nla_len(tb[AR6K_TM_ATTR_DATA]);
1597
1598 reply_len = nla_total_size(AR6K_TM_DATA_MAX_LEN);
1599 skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len);
1600 if (!skb)
1601 return -ENOMEM;
1602
1603 err = ar6000_testmode_rx_report(ar, buf, buf_len, skb);
1604 if (err < 0) {
1605 kfree_skb(skb);
1606 return err;
1607 }
1608
1609 return cfg80211_testmode_reply(skb);
1610 default:
1611 return -EOPNOTSUPP;
1612 }
1613}
1614#endif
1615
1616static const
1617u32 cipher_suites[] = {
1618 WLAN_CIPHER_SUITE_WEP40,
1619 WLAN_CIPHER_SUITE_WEP104,
1620 WLAN_CIPHER_SUITE_TKIP,
1621 WLAN_CIPHER_SUITE_CCMP,
1622};
1623
1624bool is_rate_legacy(s32 rate)
1625{
1626 static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1627 6000, 9000, 12000, 18000, 24000,
1628 36000, 48000, 54000 };
1629 u8 i;
1630
1631 for (i = 0; i < ARRAY_SIZE(legacy); i++) {
1632 if (rate == legacy[i])
1633 return true;
1634 }
1635
1636 return false;
1637}
1638
1639bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1640{
1641 static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1642 52000, 58500, 65000, 72200 };
1643 u8 i;
1644
1645 for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1646 if (rate == ht20[i]) {
1647 if (i == ARRAY_SIZE(ht20) - 1)
1648 /* last rate uses sgi */
1649 *sgi = true;
1650 else
1651 *sgi = false;
1652
1653 *mcs = i;
1654 return true;
1655 }
1656 }
1657 return false;
1658}
1659
1660bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1661{
1662 static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1663 81000, 108000, 121500, 135000,
1664 150000 };
1665 u8 i;
1666
1667 for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1668 if (rate == ht40[i]) {
1669 if (i == ARRAY_SIZE(ht40) - 1)
1670 /* last rate uses sgi */
1671 *sgi = true;
1672 else
1673 *sgi = false;
1674
1675 *mcs = i;
1676 return true;
1677 }
1678 }
1679
1680 return false;
1681}
1682
1683static int ar6k_get_station(struct wiphy *wiphy, struct net_device *dev,
1684 u8 *mac, struct station_info *sinfo)
1685{
1686 struct ar6_softc *ar = ar6k_priv(dev);
1687 long left;
1688 bool sgi;
1689 s32 rate;
1690 int ret;
1691 u8 mcs;
1692
1693 if (memcmp(mac, ar->arBssid, ETH_ALEN) != 0)
1694 return -ENOENT;
1695
1696 if (down_interruptible(&ar->arSem))
1697 return -EBUSY;
1698
1699 ar->statsUpdatePending = true;
1700
1701 ret = wmi_get_stats_cmd(ar->arWmi);
1702
1703 if (ret != 0) {
1704 up(&ar->arSem);
1705 return -EIO;
1706 }
1707
1708 left = wait_event_interruptible_timeout(arEvent,
1709 ar->statsUpdatePending == false,
1710 wmitimeout * HZ);
1711
1712 up(&ar->arSem);
1713
1714 if (left == 0)
1715 return -ETIMEDOUT;
1716 else if (left < 0)
1717 return left;
1718
1719 if (ar->arTargetStats.rx_bytes) {
1720 sinfo->rx_bytes = ar->arTargetStats.rx_bytes;
1721 sinfo->filled |= STATION_INFO_RX_BYTES;
1722 sinfo->rx_packets = ar->arTargetStats.rx_packets;
1723 sinfo->filled |= STATION_INFO_RX_PACKETS;
1724 }
1725
1726 if (ar->arTargetStats.tx_bytes) {
1727 sinfo->tx_bytes = ar->arTargetStats.tx_bytes;
1728 sinfo->filled |= STATION_INFO_TX_BYTES;
1729 sinfo->tx_packets = ar->arTargetStats.tx_packets;
1730 sinfo->filled |= STATION_INFO_TX_PACKETS;
1731 }
1732
1733 sinfo->signal = ar->arTargetStats.cs_rssi;
1734 sinfo->filled |= STATION_INFO_SIGNAL;
1735
1736 rate = ar->arTargetStats.tx_unicast_rate;
1737
1738 if (is_rate_legacy(rate)) {
1739 sinfo->txrate.legacy = rate / 100;
1740 } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1741 if (sgi) {
1742 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1743 sinfo->txrate.mcs = mcs - 1;
1744 } else {
1745 sinfo->txrate.mcs = mcs;
1746 }
1747
1748 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1749 } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1750 if (sgi) {
1751 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1752 sinfo->txrate.mcs = mcs - 1;
1753 } else {
1754 sinfo->txrate.mcs = mcs;
1755 }
1756
1757 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1758 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1759 } else {
1760 WARN(1, "invalid rate: %d", rate);
1761 return 0;
1762 }
1763
1764 sinfo->filled |= STATION_INFO_TX_BITRATE;
1765
1766 return 0;
1767}
1768
1769static int ar6k_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1770 struct cfg80211_pmksa *pmksa)
1771{
1772 struct ar6_softc *ar = ar6k_priv(netdev);
1773 return wmi_setPmkid_cmd(ar->arWmi, pmksa->bssid, pmksa->pmkid, true);
1774}
1775
1776static int ar6k_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1777 struct cfg80211_pmksa *pmksa)
1778{
1779 struct ar6_softc *ar = ar6k_priv(netdev);
1780 return wmi_setPmkid_cmd(ar->arWmi, pmksa->bssid, pmksa->pmkid, false);
1781}
1782
1783static int ar6k_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1784{
1785 struct ar6_softc *ar = ar6k_priv(netdev);
1786 if (ar->arConnected)
1787 return wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, false);
1788 return 0;
1789}
1790
1791static struct
1792cfg80211_ops ar6k_cfg80211_ops = {
1793 .change_virtual_intf = ar6k_cfg80211_change_iface,
1794 .add_virtual_intf = ar6k_cfg80211_add_virtual_intf,
1795 .del_virtual_intf = ar6k_cfg80211_del_virtual_intf,
1796 .scan = ar6k_cfg80211_scan,
1797 .connect = ar6k_cfg80211_connect,
1798 .disconnect = ar6k_cfg80211_disconnect,
1799 .add_key = ar6k_cfg80211_add_key,
1800 .get_key = ar6k_cfg80211_get_key,
1801 .del_key = ar6k_cfg80211_del_key,
1802 .set_default_key = ar6k_cfg80211_set_default_key,
1803 .set_default_mgmt_key = ar6k_cfg80211_set_default_mgmt_key,
1804 .set_wiphy_params = ar6k_cfg80211_set_wiphy_params,
1805 .set_bitrate_mask = ar6k_cfg80211_set_bitrate_mask,
1806 .set_tx_power = ar6k_cfg80211_set_txpower,
1807 .get_tx_power = ar6k_cfg80211_get_txpower,
1808 .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
1809 .join_ibss = ar6k_cfg80211_join_ibss,
1810 .leave_ibss = ar6k_cfg80211_leave_ibss,
1811 .get_station = ar6k_get_station,
1812 .set_pmksa = ar6k_set_pmksa,
1813 .del_pmksa = ar6k_del_pmksa,
1814 .flush_pmksa = ar6k_flush_pmksa,
1815 CFG80211_TESTMODE_CMD(ar6k_testmode_cmd)
1816};
1817
1818struct wireless_dev *
1819ar6k_cfg80211_init(struct device *dev)
1820{
1821 int ret = 0;
1822 struct wireless_dev *wdev;
1823
1824 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1825
1826 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1827 if(!wdev) {
1828 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1829 ("%s: Couldn't allocate wireless device\n", __func__));
1830 return ERR_PTR(-ENOMEM);
1831 }
1832
1833 /* create a new wiphy for use with cfg80211 */
1834 wdev->wiphy = wiphy_new(&ar6k_cfg80211_ops, sizeof(struct ar6_softc));
1835 if(!wdev->wiphy) {
1836 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1837 ("%s: Couldn't allocate wiphy device\n", __func__));
1838 kfree(wdev);
1839 return ERR_PTR(-ENOMEM);
1840 }
1841
1842 /* set device pointer for wiphy */
1843 set_wiphy_dev(wdev->wiphy, dev);
1844
1845 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1846 BIT(NL80211_IFTYPE_ADHOC);
1847 /* max num of ssids that can be probed during scanning */
1848 wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
1849 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar6k_band_2ghz;
1850 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar6k_band_5ghz;
1851 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1852
1853 wdev->wiphy->cipher_suites = cipher_suites;
1854 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1855
1856 ret = wiphy_register(wdev->wiphy);
1857 if(ret < 0) {
1858 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1859 ("%s: Couldn't register wiphy device\n", __func__));
1860 wiphy_free(wdev->wiphy);
1861 return ERR_PTR(ret);
1862 }
1863
1864 return wdev;
1865}
1866
1867void
1868ar6k_cfg80211_deinit(struct ar6_softc *ar)
1869{
1870 struct wireless_dev *wdev = ar->wdev;
1871
1872 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1873
1874 if(ar->scan_request) {
1875 cfg80211_scan_done(ar->scan_request, true);
1876 ar->scan_request = NULL;
1877 }
1878
1879 if(!wdev)
1880 return;
1881
1882 wiphy_unregister(wdev->wiphy);
1883 wiphy_free(wdev->wiphy);
1884 kfree(wdev);
1885}
1886
1887
1888
1889
1890
1891
1892
diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c
new file mode 100644
index 00000000000..430998edacc
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/export_hci_transport.c
@@ -0,0 +1,124 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// HCI bridge implementation
21//
22// Author(s): ="Atheros"
23//==============================================================================
24#include <a_config.h>
25#include <athdefs.h>
26#include "a_osapi.h"
27#include "htc_api.h"
28#include "a_drv.h"
29#include "hif.h"
30#include "common_drv.h"
31#include "a_debug.h"
32#include "hci_transport_api.h"
33
34#include "AR6002/hw4.0/hw/apb_athr_wlan_map.h"
35#include "AR6002/hw4.0/hw/uart_reg.h"
36#include "AR6002/hw4.0/hw/rtc_wlan_reg.h"
37
38HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo);
39void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans);
40int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue);
41int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous);
42void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans);
43int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans);
44int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
45int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans,
46 struct htc_packet *pPacket,
47 int MaxPollMS);
48int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud);
49int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
50
51extern struct hci_transport_callbacks ar6kHciTransCallbacks;
52
53int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallbacks)
54{
55 ar6kHciTransCallbacks = *hciTransCallbacks;
56
57 _HCI_TransportAttach = HCI_TransportAttach;
58 _HCI_TransportDetach = HCI_TransportDetach;
59 _HCI_TransportAddReceivePkts = HCI_TransportAddReceivePkts;
60 _HCI_TransportSendPkt = HCI_TransportSendPkt;
61 _HCI_TransportStop = HCI_TransportStop;
62 _HCI_TransportStart = HCI_TransportStart;
63 _HCI_TransportEnableDisableAsyncRecv = HCI_TransportEnableDisableAsyncRecv;
64 _HCI_TransportRecvHCIEventSync = HCI_TransportRecvHCIEventSync;
65 _HCI_TransportSetBaudRate = HCI_TransportSetBaudRate;
66 _HCI_TransportEnablePowerMgmt = HCI_TransportEnablePowerMgmt;
67
68 return 0;
69}
70
71int
72ar6000_get_hif_dev(struct hif_device *device, void *config)
73{
74 int status;
75
76 status = HIFConfigureDevice(device,
77 HIF_DEVICE_GET_OS_DEVICE,
78 (struct hif_device_os_device_info *)config,
79 sizeof(struct hif_device_os_device_info));
80 return status;
81}
82
83int ar6000_set_uart_config(struct hif_device *hifDevice,
84 u32 scale,
85 u32 step)
86{
87 u32 regAddress;
88 u32 regVal;
89 int status;
90
91 regAddress = WLAN_UART_BASE_ADDRESS | UART_CLKDIV_ADDRESS;
92 regVal = ((u32)scale << 16) | step;
93 /* change the HCI UART scale/step values through the diagnostic window */
94 status = ar6000_WriteRegDiag(hifDevice, &regAddress, &regVal);
95
96 return status;
97}
98
99int ar6000_get_core_clock_config(struct hif_device *hifDevice, u32 *data)
100{
101 u32 regAddress;
102 int status;
103
104 regAddress = WLAN_RTC_BASE_ADDRESS | WLAN_CPU_CLOCK_ADDRESS;
105 /* read CPU clock settings*/
106 status = ar6000_ReadRegDiag(hifDevice, &regAddress, data);
107
108 return status;
109}
110
111EXPORT_SYMBOL(ar6000_register_hci_transport);
112EXPORT_SYMBOL(ar6000_get_hif_dev);
113EXPORT_SYMBOL(ar6000_set_uart_config);
114EXPORT_SYMBOL(ar6000_get_core_clock_config);
115EXPORT_SYMBOL(_HCI_TransportAttach);
116EXPORT_SYMBOL(_HCI_TransportDetach);
117EXPORT_SYMBOL(_HCI_TransportAddReceivePkts);
118EXPORT_SYMBOL(_HCI_TransportSendPkt);
119EXPORT_SYMBOL(_HCI_TransportStop);
120EXPORT_SYMBOL(_HCI_TransportStart);
121EXPORT_SYMBOL(_HCI_TransportEnableDisableAsyncRecv);
122EXPORT_SYMBOL(_HCI_TransportRecvHCIEventSync);
123EXPORT_SYMBOL(_HCI_TransportSetBaudRate);
124EXPORT_SYMBOL(_HCI_TransportEnablePowerMgmt);
diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c
new file mode 100644
index 00000000000..6087edcb1d6
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c
@@ -0,0 +1,1141 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// HCI bridge implementation
21//
22// Author(s): ="Atheros"
23//==============================================================================
24
25#ifdef EXPORT_HCI_BRIDGE_INTERFACE
26#include <linux/etherdevice.h>
27#include <a_config.h>
28#include <athdefs.h>
29#include "a_osapi.h"
30#include "htc_api.h"
31#include "wmi.h"
32#include "a_drv.h"
33#include "hif.h"
34#include "common_drv.h"
35#include "a_debug.h"
36#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
37#define ATH_DEBUG_HCI_RECV ATH_DEBUG_MAKE_MODULE_MASK(7)
38#define ATH_DEBUG_HCI_SEND ATH_DEBUG_MAKE_MODULE_MASK(8)
39#define ATH_DEBUG_HCI_DUMP ATH_DEBUG_MAKE_MODULE_MASK(9)
40#else
41#include "ar6000_drv.h"
42#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
43
44#ifdef ATH_AR6K_ENABLE_GMBOX
45#ifdef EXPORT_HCI_BRIDGE_INTERFACE
46#include "export_hci_transport.h"
47#else
48#include "hci_transport_api.h"
49#endif
50#include "epping_test.h"
51#include "gmboxif.h"
52#include "ar3kconfig.h"
53#include <net/bluetooth/bluetooth.h>
54#include <net/bluetooth/hci_core.h>
55
56 /* only build on newer kernels which have BT configured */
57#if defined(CONFIG_BT_MODULE) || defined(CONFIG_BT)
58#define CONFIG_BLUEZ_HCI_BRIDGE
59#endif
60
61#ifdef EXPORT_HCI_BRIDGE_INTERFACE
62unsigned int ar3khcibaud = 0;
63unsigned int hciuartscale = 0;
64unsigned int hciuartstep = 0;
65
66module_param(ar3khcibaud, int, 0644);
67module_param(hciuartscale, int, 0644);
68module_param(hciuartstep, int, 0644);
69#else
70extern unsigned int ar3khcibaud;
71extern unsigned int hciuartscale;
72extern unsigned int hciuartstep;
73#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
74
75struct ar6k_hci_bridge_info {
76 void *pHCIDev; /* HCI bridge device */
77 struct hci_transport_properties HCIProps; /* HCI bridge props */
78 struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */
79 bool HciNormalMode; /* Actual HCI mode enabled (non-TEST)*/
80 bool HciRegistered; /* HCI device registered with stack */
81 struct htc_packet_queue HTCPacketStructHead;
82 u8 *pHTCStructAlloc;
83 spinlock_t BridgeLock;
84#ifdef EXPORT_HCI_BRIDGE_INTERFACE
85 struct hci_transport_misc_handles HCITransHdl;
86#else
87 struct ar6_softc *ar;
88#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
89};
90
91#define MAX_ACL_RECV_BUFS 16
92#define MAX_EVT_RECV_BUFS 8
93#define MAX_HCI_WRITE_QUEUE_DEPTH 32
94#define MAX_ACL_RECV_LENGTH 1200
95#define MAX_EVT_RECV_LENGTH 257
96#define TX_PACKET_RSV_OFFSET 32
97#define NUM_HTC_PACKET_STRUCTS ((MAX_ACL_RECV_BUFS + MAX_EVT_RECV_BUFS + MAX_HCI_WRITE_QUEUE_DEPTH) * 2)
98
99#define HCI_GET_OP_CODE(p) (((u16)((p)[1])) << 8) | ((u16)((p)[0]))
100
101extern unsigned int setupbtdev;
102struct ar3k_config_info ar3kconfig;
103
104#ifdef EXPORT_HCI_BRIDGE_INTERFACE
105struct ar6k_hci_bridge_info *g_pHcidevInfo;
106#endif
107
108static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo);
109static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo);
110static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo);
111static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo,
112 HCI_TRANSPORT_PACKET_TYPE Type,
113 struct sk_buff *skb);
114static struct sk_buff *bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length);
115static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb);
116
117#ifdef EXPORT_HCI_BRIDGE_INTERFACE
118int ar6000_setup_hci(void *ar);
119void ar6000_cleanup_hci(void *ar);
120int hci_test_send(void *ar, struct sk_buff *skb);
121#else
122int ar6000_setup_hci(struct ar6_softc *ar);
123void ar6000_cleanup_hci(struct ar6_softc *ar);
124/* HCI bridge testing */
125int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb);
126#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
127
128#define LOCK_BRIDGE(dev) spin_lock_bh(&(dev)->BridgeLock)
129#define UNLOCK_BRIDGE(dev) spin_unlock_bh(&(dev)->BridgeLock)
130
131static inline void FreeBtOsBuf(struct ar6k_hci_bridge_info *pHcidevInfo, void *osbuf)
132{
133 if (pHcidevInfo->HciNormalMode) {
134 bt_free_buffer(pHcidevInfo, (struct sk_buff *)osbuf);
135 } else {
136 /* in test mode, these are just ordinary netbuf allocations */
137 A_NETBUF_FREE(osbuf);
138 }
139}
140
141static void FreeHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo, struct htc_packet *pPacket)
142{
143 LOCK_BRIDGE(pHcidevInfo);
144 HTC_PACKET_ENQUEUE(&pHcidevInfo->HTCPacketStructHead,pPacket);
145 UNLOCK_BRIDGE(pHcidevInfo);
146}
147
148static struct htc_packet * AllocHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo)
149{
150 struct htc_packet *pPacket = NULL;
151 LOCK_BRIDGE(pHcidevInfo);
152 pPacket = HTC_PACKET_DEQUEUE(&pHcidevInfo->HTCPacketStructHead);
153 UNLOCK_BRIDGE(pHcidevInfo);
154 return pPacket;
155}
156
157#define BLOCK_ROUND_UP_PWR2(x, align) (((int) (x) + ((align)-1)) & ~((align)-1))
158
159static void RefillRecvBuffers(struct ar6k_hci_bridge_info *pHcidevInfo,
160 HCI_TRANSPORT_PACKET_TYPE Type,
161 int NumBuffers)
162{
163 int length, i;
164 void *osBuf = NULL;
165 struct htc_packet_queue queue;
166 struct htc_packet *pPacket;
167
168 INIT_HTC_PACKET_QUEUE(&queue);
169
170 if (Type == HCI_ACL_TYPE) {
171 if (pHcidevInfo->HciNormalMode) {
172 length = HCI_MAX_FRAME_SIZE;
173 } else {
174 length = MAX_ACL_RECV_LENGTH;
175 }
176 } else {
177 length = MAX_EVT_RECV_LENGTH;
178 }
179
180 /* add on transport head and tail room */
181 length += pHcidevInfo->HCIProps.HeadRoom + pHcidevInfo->HCIProps.TailRoom;
182 /* round up to the required I/O padding */
183 length = BLOCK_ROUND_UP_PWR2(length,pHcidevInfo->HCIProps.IOBlockPad);
184
185 for (i = 0; i < NumBuffers; i++) {
186
187 if (pHcidevInfo->HciNormalMode) {
188 osBuf = bt_alloc_buffer(pHcidevInfo,length);
189 } else {
190 osBuf = A_NETBUF_ALLOC(length);
191 }
192
193 if (NULL == osBuf) {
194 break;
195 }
196
197 pPacket = AllocHTCStruct(pHcidevInfo);
198 if (NULL == pPacket) {
199 FreeBtOsBuf(pHcidevInfo,osBuf);
200 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
201 break;
202 }
203
204 SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),length,Type);
205 /* add to queue */
206 HTC_PACKET_ENQUEUE(&queue,pPacket);
207 }
208
209 if (i > 0) {
210 HCI_TransportAddReceivePkts(pHcidevInfo->pHCIDev, &queue);
211 }
212}
213
214#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
215 (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
216 (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0))
217static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle,
218 struct hci_transport_properties *pProps,
219 void *pContext)
220{
221 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
222 int status;
223 u32 address, hci_uart_pwr_mgmt_params;
224// struct ar3k_config_info ar3kconfig;
225
226 pHcidevInfo->pHCIDev = HCIHandle;
227
228 memcpy(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps));
229
230 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE,("HCI ready (hci:0x%lX, headroom:%d, tailroom:%d blockpad:%d) \n",
231 (unsigned long)HCIHandle,
232 pHcidevInfo->HCIProps.HeadRoom,
233 pHcidevInfo->HCIProps.TailRoom,
234 pHcidevInfo->HCIProps.IOBlockPad));
235
236#ifdef EXPORT_HCI_BRIDGE_INTERFACE
237 A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice)->hard_header_len);
238#else
239 A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= pHcidevInfo->ar->arNetDev->hard_header_len);
240#endif
241
242 /* provide buffers */
243 RefillRecvBuffers(pHcidevInfo, HCI_ACL_TYPE, MAX_ACL_RECV_BUFS);
244 RefillRecvBuffers(pHcidevInfo, HCI_EVENT_TYPE, MAX_EVT_RECV_BUFS);
245
246 do {
247 /* start transport */
248 status = HCI_TransportStart(pHcidevInfo->pHCIDev);
249
250 if (status) {
251 break;
252 }
253
254 if (!pHcidevInfo->HciNormalMode) {
255 /* in test mode, no need to go any further */
256 break;
257 }
258
259 // The delay is required when AR6K is driving the BT reset line
260 // where time is needed after the BT chip is out of reset (HCI_TransportStart)
261 // and before the first HCI command is issued (AR3KConfigure)
262 // FIXME
263 // The delay should be configurable and be only applied when AR6K driving the BT
264 // reset line. This could be done by some module parameter or based on some HW config
265 // info. For now apply 100ms delay blindly
266 A_MDELAY(100);
267
268 A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
269 ar3kconfig.pHCIDev = pHcidevInfo->pHCIDev;
270 ar3kconfig.pHCIProps = &pHcidevInfo->HCIProps;
271#ifdef EXPORT_HCI_BRIDGE_INTERFACE
272 ar3kconfig.pHIFDevice = (struct hif_device *)(pHcidevInfo->HCITransHdl.hifDevice);
273#else
274 ar3kconfig.pHIFDevice = pHcidevInfo->ar->arHifDevice;
275#endif
276 ar3kconfig.pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
277
278 if (ar3khcibaud != 0) {
279 /* user wants ar3k baud rate change */
280 ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD;
281 ar3kconfig.Flags |= AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY;
282 ar3kconfig.AR3KBaudRate = ar3khcibaud;
283 }
284
285 if ((hciuartscale != 0) || (hciuartstep != 0)) {
286 /* user wants to tune HCI bridge UART scale/step values */
287 ar3kconfig.AR6KScale = (u16)hciuartscale;
288 ar3kconfig.AR6KStep = (u16)hciuartstep;
289 ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP;
290 }
291
292 /* Fetch the address of the hi_hci_uart_pwr_mgmt_params instance in the host interest area */
293 address = TARG_VTOP(pHcidevInfo->ar->arTargetType,
294 HOST_INTEREST_ITEM_ADDRESS(pHcidevInfo->ar, hi_hci_uart_pwr_mgmt_params));
295 status = ar6000_ReadRegDiag(pHcidevInfo->ar->arHifDevice, &address, &hci_uart_pwr_mgmt_params);
296 if (0 == status) {
297 ar3kconfig.PwrMgmtEnabled = (hci_uart_pwr_mgmt_params & 0x1);
298 ar3kconfig.IdleTimeout = (hci_uart_pwr_mgmt_params & 0xFFFF0000) >> 16;
299 ar3kconfig.WakeupTimeout = (hci_uart_pwr_mgmt_params & 0xFF00) >> 8;
300 } else {
301 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to read hci_uart_pwr_mgmt_params! \n"));
302 }
303 /* configure the AR3K device */
304 memcpy(ar3kconfig.bdaddr,pHcidevInfo->ar->bdaddr,6);
305 status = AR3KConfigure(&ar3kconfig);
306 if (status) {
307 break;
308 }
309
310 /* Make sure both AR6K and AR3K have power management enabled */
311 if (ar3kconfig.PwrMgmtEnabled) {
312 status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, true);
313 if (status) {
314 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to enable TLPM for AR6K! \n"));
315 }
316 }
317
318 status = bt_register_hci(pHcidevInfo);
319
320 } while (false);
321
322 return status;
323}
324
325static void ar6000_hci_transport_failure(void *pContext, int Status)
326{
327 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
328
329 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: transport failure! \n"));
330
331 if (pHcidevInfo->HciNormalMode) {
332 /* TODO .. */
333 }
334}
335
336static void ar6000_hci_transport_removed(void *pContext)
337{
338 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
339
340 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: transport removed. \n"));
341
342 A_ASSERT(pHcidevInfo->pHCIDev != NULL);
343
344 HCI_TransportDetach(pHcidevInfo->pHCIDev);
345 bt_cleanup_hci(pHcidevInfo);
346 pHcidevInfo->pHCIDev = NULL;
347}
348
349static void ar6000_hci_send_complete(void *pContext, struct htc_packet *pPacket)
350{
351 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
352 void *osbuf = pPacket->pPktContext;
353 A_ASSERT(osbuf != NULL);
354 A_ASSERT(pHcidevInfo != NULL);
355
356 if (pPacket->Status) {
357 if ((pPacket->Status != A_ECANCELED) && (pPacket->Status != A_NO_RESOURCE)) {
358 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: Send Packet Failed: %d \n",pPacket->Status));
359 }
360 }
361
362 FreeHTCStruct(pHcidevInfo,pPacket);
363 FreeBtOsBuf(pHcidevInfo,osbuf);
364
365}
366
367static void ar6000_hci_pkt_recv(void *pContext, struct htc_packet *pPacket)
368{
369 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
370 struct sk_buff *skb;
371
372 A_ASSERT(pHcidevInfo != NULL);
373 skb = (struct sk_buff *)pPacket->pPktContext;
374 A_ASSERT(skb != NULL);
375
376 do {
377
378 if (pPacket->Status) {
379 break;
380 }
381
382 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV,
383 ("HCI Bridge, packet received type : %d len:%d \n",
384 HCI_GET_PACKET_TYPE(pPacket),pPacket->ActualLength));
385
386 /* set the actual buffer position in the os buffer, HTC recv buffers posted to HCI are set
387 * to fill the front of the buffer */
388 A_NETBUF_PUT(skb,pPacket->ActualLength + pHcidevInfo->HCIProps.HeadRoom);
389 A_NETBUF_PULL(skb,pHcidevInfo->HCIProps.HeadRoom);
390
391 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
392 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("<<< Recv HCI %s packet len:%d \n",
393 (HCI_GET_PACKET_TYPE(pPacket) == HCI_EVENT_TYPE) ? "EVENT" : "ACL",
394 skb->len));
395 AR_DEBUG_PRINTBUF(skb->data, skb->len,"BT HCI RECV Packet Dump");
396 }
397
398 if (pHcidevInfo->HciNormalMode) {
399 /* indicate the packet */
400 if (bt_indicate_recv(pHcidevInfo,HCI_GET_PACKET_TYPE(pPacket),skb)) {
401 /* bt stack accepted the packet */
402 skb = NULL;
403 }
404 break;
405 }
406
407 /* for testing, indicate packet to the network stack */
408#ifdef EXPORT_HCI_BRIDGE_INTERFACE
409 skb->dev = (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice);
410 if ((((struct net_device *)pHcidevInfo->HCITransHdl.netDevice)->flags & IFF_UP) == IFF_UP) {
411 skb->protocol = eth_type_trans(skb, (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice));
412#else
413 skb->dev = pHcidevInfo->ar->arNetDev;
414 if ((pHcidevInfo->ar->arNetDev->flags & IFF_UP) == IFF_UP) {
415 skb->protocol = eth_type_trans(skb, pHcidevInfo->ar->arNetDev);
416#endif
417 netif_rx(skb);
418 skb = NULL;
419 }
420
421 } while (false);
422
423 FreeHTCStruct(pHcidevInfo,pPacket);
424
425 if (skb != NULL) {
426 /* packet was not accepted, free it */
427 FreeBtOsBuf(pHcidevInfo,skb);
428 }
429
430}
431
432static void ar6000_hci_pkt_refill(void *pContext, HCI_TRANSPORT_PACKET_TYPE Type, int BuffersAvailable)
433{
434 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
435 int refillCount;
436
437 if (Type == HCI_ACL_TYPE) {
438 refillCount = MAX_ACL_RECV_BUFS - BuffersAvailable;
439 } else {
440 refillCount = MAX_EVT_RECV_BUFS - BuffersAvailable;
441 }
442
443 if (refillCount > 0) {
444 RefillRecvBuffers(pHcidevInfo,Type,refillCount);
445 }
446
447}
448
449static HCI_SEND_FULL_ACTION ar6000_hci_pkt_send_full(void *pContext, struct htc_packet *pPacket)
450{
451 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
452 HCI_SEND_FULL_ACTION action = HCI_SEND_FULL_KEEP;
453
454 if (!pHcidevInfo->HciNormalMode) {
455 /* for epping testing, check packet tag, some epping packets are
456 * special and cannot be dropped */
457 if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_DATA_PKT_TAG) {
458 action = HCI_SEND_FULL_DROP;
459 }
460 }
461
462 return action;
463}
464
465#ifdef EXPORT_HCI_BRIDGE_INTERFACE
466int ar6000_setup_hci(void *ar)
467#else
468int ar6000_setup_hci(struct ar6_softc *ar)
469#endif
470{
471 struct hci_transport_config_info config;
472 int status = 0;
473 int i;
474 struct htc_packet *pPacket;
475 struct ar6k_hci_bridge_info *pHcidevInfo;
476
477
478 do {
479
480 pHcidevInfo = (struct ar6k_hci_bridge_info *)A_MALLOC(sizeof(struct ar6k_hci_bridge_info));
481
482 if (NULL == pHcidevInfo) {
483 status = A_NO_MEMORY;
484 break;
485 }
486
487 A_MEMZERO(pHcidevInfo, sizeof(struct ar6k_hci_bridge_info));
488#ifdef EXPORT_HCI_BRIDGE_INTERFACE
489 g_pHcidevInfo = pHcidevInfo;
490 pHcidevInfo->HCITransHdl = *(struct hci_transport_misc_handles *)ar;
491#else
492 ar->hcidev_info = pHcidevInfo;
493 pHcidevInfo->ar = ar;
494#endif
495 spin_lock_init(&pHcidevInfo->BridgeLock);
496 INIT_HTC_PACKET_QUEUE(&pHcidevInfo->HTCPacketStructHead);
497
498 ar->exitCallback = AR3KConfigureExit;
499
500 status = bt_setup_hci(pHcidevInfo);
501 if (status) {
502 break;
503 }
504
505 if (pHcidevInfo->HciNormalMode) {
506 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in normal mode... \n"));
507 } else {
508 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in test mode... \n"));
509 }
510
511 pHcidevInfo->pHTCStructAlloc = (u8 *)A_MALLOC((sizeof(struct htc_packet)) * NUM_HTC_PACKET_STRUCTS);
512
513 if (NULL == pHcidevInfo->pHTCStructAlloc) {
514 status = A_NO_MEMORY;
515 break;
516 }
517
518 pPacket = (struct htc_packet *)pHcidevInfo->pHTCStructAlloc;
519 for (i = 0; i < NUM_HTC_PACKET_STRUCTS; i++,pPacket++) {
520 FreeHTCStruct(pHcidevInfo,pPacket);
521 }
522
523 A_MEMZERO(&config,sizeof(struct hci_transport_config_info));
524 config.ACLRecvBufferWaterMark = MAX_ACL_RECV_BUFS / 2;
525 config.EventRecvBufferWaterMark = MAX_EVT_RECV_BUFS / 2;
526 config.MaxSendQueueDepth = MAX_HCI_WRITE_QUEUE_DEPTH;
527 config.pContext = pHcidevInfo;
528 config.TransportFailure = ar6000_hci_transport_failure;
529 config.TransportReady = ar6000_hci_transport_ready;
530 config.TransportRemoved = ar6000_hci_transport_removed;
531 config.pHCISendComplete = ar6000_hci_send_complete;
532 config.pHCIPktRecv = ar6000_hci_pkt_recv;
533 config.pHCIPktRecvRefill = ar6000_hci_pkt_refill;
534 config.pHCISendFull = ar6000_hci_pkt_send_full;
535
536#ifdef EXPORT_HCI_BRIDGE_INTERFACE
537 pHcidevInfo->pHCIDev = HCI_TransportAttach(pHcidevInfo->HCITransHdl.htcHandle, &config);
538#else
539 pHcidevInfo->pHCIDev = HCI_TransportAttach(ar->arHtcTarget, &config);
540#endif
541
542 if (NULL == pHcidevInfo->pHCIDev) {
543 status = A_ERROR;
544 }
545
546 } while (false);
547
548 if (status) {
549 if (pHcidevInfo != NULL) {
550 if (NULL == pHcidevInfo->pHCIDev) {
551 /* GMBOX may not be present in older chips */
552 /* just return success */
553 status = 0;
554 }
555 }
556 ar6000_cleanup_hci(ar);
557 }
558
559 return status;
560}
561
562#ifdef EXPORT_HCI_BRIDGE_INTERFACE
563void ar6000_cleanup_hci(void *ar)
564#else
565void ar6000_cleanup_hci(struct ar6_softc *ar)
566#endif
567{
568#ifdef EXPORT_HCI_BRIDGE_INTERFACE
569 struct ar6k_hci_bridge_info *pHcidevInfo = g_pHcidevInfo;
570#else
571 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info;
572#endif
573
574 if (pHcidevInfo != NULL) {
575 bt_cleanup_hci(pHcidevInfo);
576
577 if (pHcidevInfo->pHCIDev != NULL) {
578 HCI_TransportStop(pHcidevInfo->pHCIDev);
579 HCI_TransportDetach(pHcidevInfo->pHCIDev);
580 pHcidevInfo->pHCIDev = NULL;
581 }
582
583 if (pHcidevInfo->pHTCStructAlloc != NULL) {
584 kfree(pHcidevInfo->pHTCStructAlloc);
585 pHcidevInfo->pHTCStructAlloc = NULL;
586 }
587
588 kfree(pHcidevInfo);
589#ifndef EXPORT_HCI_BRIDGE_INTERFACE
590 ar->hcidev_info = NULL;
591#endif
592 }
593
594
595}
596
597#ifdef EXPORT_HCI_BRIDGE_INTERFACE
598int hci_test_send(void *ar, struct sk_buff *skb)
599#else
600int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb)
601#endif
602{
603 int status = 0;
604 int length;
605 EPPING_HEADER *pHeader;
606 struct htc_packet *pPacket;
607 HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG;
608#ifdef EXPORT_HCI_BRIDGE_INTERFACE
609 struct ar6k_hci_bridge_info *pHcidevInfo = g_pHcidevInfo;
610#else
611 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info;
612#endif
613
614 do {
615
616 if (NULL == pHcidevInfo) {
617 status = A_ERROR;
618 break;
619 }
620
621 if (NULL == pHcidevInfo->pHCIDev) {
622 status = A_ERROR;
623 break;
624 }
625
626 if (pHcidevInfo->HciNormalMode) {
627 /* this interface cannot run when normal WMI is running */
628 status = A_ERROR;
629 break;
630 }
631
632 pHeader = (EPPING_HEADER *)A_NETBUF_DATA(skb);
633
634 if (!IS_EPPING_PACKET(pHeader)) {
635 status = A_EINVAL;
636 break;
637 }
638
639 if (IS_EPING_PACKET_NO_DROP(pHeader)) {
640 htc_tag = AR6K_CONTROL_PKT_TAG;
641 }
642
643 length = sizeof(EPPING_HEADER) + pHeader->DataLength;
644
645 pPacket = AllocHTCStruct(pHcidevInfo);
646 if (NULL == pPacket) {
647 status = A_NO_MEMORY;
648 break;
649 }
650
651 SET_HTC_PACKET_INFO_TX(pPacket,
652 skb,
653 A_NETBUF_DATA(skb),
654 length,
655 HCI_ACL_TYPE, /* send every thing out as ACL */
656 htc_tag);
657
658 HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,false);
659 pPacket = NULL;
660
661 } while (false);
662
663 return status;
664}
665
666void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig)
667{
668 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info;
669 struct ar3k_config_info *config = (struct ar3k_config_info *)ar3kconfig;
670
671 config->pHCIDev = pHcidevInfo->pHCIDev;
672 config->pHCIProps = &pHcidevInfo->HCIProps;
673 config->pHIFDevice = ar->arHifDevice;
674 config->pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
675 config->Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD;
676 config->AR3KBaudRate = 115200;
677}
678
679#ifdef CONFIG_BLUEZ_HCI_BRIDGE
680/*** BT Stack Entrypoints *******/
681
682/*
683 * bt_open - open a handle to the device
684*/
685static int bt_open(struct hci_dev *hdev)
686{
687
688 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_open - enter - x\n"));
689 set_bit(HCI_RUNNING, &hdev->flags);
690 set_bit(HCI_UP, &hdev->flags);
691 set_bit(HCI_INIT, &hdev->flags);
692 return 0;
693}
694
695/*
696 * bt_close - close handle to the device
697*/
698static int bt_close(struct hci_dev *hdev)
699{
700 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_close - enter\n"));
701 clear_bit(HCI_RUNNING, &hdev->flags);
702 return 0;
703}
704
705/*
706 * bt_send_frame - send data frames
707*/
708static int bt_send_frame(struct sk_buff *skb)
709{
710 struct hci_dev *hdev = (struct hci_dev *)skb->dev;
711 HCI_TRANSPORT_PACKET_TYPE type;
712 struct ar6k_hci_bridge_info *pHcidevInfo;
713 struct htc_packet *pPacket;
714 int status = 0;
715 struct sk_buff *txSkb = NULL;
716
717 if (!hdev) {
718 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_send_frame - no device\n"));
719 return -ENODEV;
720 }
721
722 if (!test_bit(HCI_RUNNING, &hdev->flags)) {
723 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_send_frame - not open\n"));
724 return -EBUSY;
725 }
726
727 pHcidevInfo = (struct ar6k_hci_bridge_info *)hdev->driver_data;
728 A_ASSERT(pHcidevInfo != NULL);
729
730 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("+bt_send_frame type: %d \n",bt_cb(skb)->pkt_type));
731 type = HCI_COMMAND_TYPE;
732
733 switch (bt_cb(skb)->pkt_type) {
734 case HCI_COMMAND_PKT:
735 type = HCI_COMMAND_TYPE;
736 hdev->stat.cmd_tx++;
737 break;
738
739 case HCI_ACLDATA_PKT:
740 type = HCI_ACL_TYPE;
741 hdev->stat.acl_tx++;
742 break;
743
744 case HCI_SCODATA_PKT:
745 /* we don't support SCO over the bridge */
746 kfree_skb(skb);
747 return 0;
748 default:
749 A_ASSERT(false);
750 kfree_skb(skb);
751 return 0;
752 }
753
754 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
755 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(">>> Send HCI %s packet len: %d\n",
756 (type == HCI_COMMAND_TYPE) ? "COMMAND" : "ACL",
757 skb->len));
758 if (type == HCI_COMMAND_TYPE) {
759 u16 opcode = HCI_GET_OP_CODE(skb->data);
760 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" HCI Command: OGF:0x%X OCF:0x%X \r\n",
761 opcode >> 10, opcode & 0x3FF));
762 }
763 AR_DEBUG_PRINTBUF(skb->data,skb->len,"BT HCI SEND Packet Dump");
764 }
765
766 do {
767
768 txSkb = bt_skb_alloc(TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom +
769 pHcidevInfo->HCIProps.TailRoom + skb->len,
770 GFP_ATOMIC);
771
772 if (txSkb == NULL) {
773 status = A_NO_MEMORY;
774 break;
775 }
776
777 bt_cb(txSkb)->pkt_type = bt_cb(skb)->pkt_type;
778 txSkb->dev = (void *)pHcidevInfo->pBtStackHCIDev;
779 skb_reserve(txSkb, TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom);
780 memcpy(txSkb->data, skb->data, skb->len);
781 skb_put(txSkb,skb->len);
782
783 pPacket = AllocHTCStruct(pHcidevInfo);
784 if (NULL == pPacket) {
785 status = A_NO_MEMORY;
786 break;
787 }
788
789 /* HCI packet length here doesn't include the 1-byte transport header which
790 * will be handled by the HCI transport layer. Enough headroom has already
791 * been reserved above for the transport header
792 */
793 SET_HTC_PACKET_INFO_TX(pPacket,
794 txSkb,
795 txSkb->data,
796 txSkb->len,
797 type,
798 AR6K_CONTROL_PKT_TAG); /* HCI packets cannot be dropped */
799
800 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: bt_send_frame skb:0x%lX \n",(unsigned long)txSkb));
801 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: type:%d, Total Length:%d Bytes \n",
802 type, txSkb->len));
803
804 status = HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,false);
805 pPacket = NULL;
806 txSkb = NULL;
807
808 } while (false);
809
810 if (txSkb != NULL) {
811 kfree_skb(txSkb);
812 }
813
814 kfree_skb(skb);
815
816 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("-bt_send_frame \n"));
817 return 0;
818}
819
820/*
821 * bt_ioctl - ioctl processing
822*/
823static int bt_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
824{
825 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_ioctl - enter\n"));
826 return -ENOIOCTLCMD;
827}
828
829/*
830 * bt_flush - flush outstandingbpackets
831*/
832static int bt_flush(struct hci_dev *hdev)
833{
834 struct ar6k_hci_bridge_info *pHcidevInfo;
835
836 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_flush - enter\n"));
837
838 pHcidevInfo = (struct ar6k_hci_bridge_info *)hdev->driver_data;
839
840 /* TODO??? */
841
842 return 0;
843}
844
845
846/*
847 * bt_destruct -
848*/
849static void bt_destruct(struct hci_dev *hdev)
850{
851 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_destruct - enter\n"));
852 /* nothing to do here */
853}
854
855static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
856{
857 int status = 0;
858 struct hci_dev *pHciDev = NULL;
859 struct hif_device_os_device_info osDevInfo;
860
861 if (!setupbtdev) {
862 return 0;
863 }
864
865 do {
866
867 A_MEMZERO(&osDevInfo,sizeof(osDevInfo));
868 /* get the underlying OS device */
869#ifdef EXPORT_HCI_BRIDGE_INTERFACE
870 status = ar6000_get_hif_dev((struct hif_device *)(pHcidevInfo->HCITransHdl.hifDevice),
871 &osDevInfo);
872#else
873 status = HIFConfigureDevice(pHcidevInfo->ar->arHifDevice,
874 HIF_DEVICE_GET_OS_DEVICE,
875 &osDevInfo,
876 sizeof(osDevInfo));
877#endif
878
879 if (status) {
880 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to OS device info from HIF\n"));
881 break;
882 }
883
884 /* allocate a BT HCI struct for this device */
885 pHciDev = hci_alloc_dev();
886 if (NULL == pHciDev) {
887 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge - failed to allocate bt struct \n"));
888 status = A_NO_MEMORY;
889 break;
890 }
891 /* save the device, we'll register this later */
892 pHcidevInfo->pBtStackHCIDev = pHciDev;
893 SET_HCIDEV_DEV(pHciDev,osDevInfo.pOSDevice);
894 SET_HCI_BUS_TYPE(pHciDev, HCI_VIRTUAL, HCI_BREDR);
895 pHciDev->driver_data = pHcidevInfo;
896 pHciDev->open = bt_open;
897 pHciDev->close = bt_close;
898 pHciDev->send = bt_send_frame;
899 pHciDev->ioctl = bt_ioctl;
900 pHciDev->flush = bt_flush;
901 pHciDev->destruct = bt_destruct;
902 pHciDev->owner = THIS_MODULE;
903 /* driver is running in normal BT mode */
904 pHcidevInfo->HciNormalMode = true;
905
906 } while (false);
907
908 if (status) {
909 bt_cleanup_hci(pHcidevInfo);
910 }
911
912 return status;
913}
914
915static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
916{
917 int err;
918
919 if (pHcidevInfo->HciRegistered) {
920 pHcidevInfo->HciRegistered = false;
921 clear_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags);
922 clear_bit(HCI_UP, &pHcidevInfo->pBtStackHCIDev->flags);
923 clear_bit(HCI_INIT, &pHcidevInfo->pBtStackHCIDev->flags);
924 A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL);
925 /* unregister */
926 if ((err = hci_unregister_dev(pHcidevInfo->pBtStackHCIDev)) < 0) {
927 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to unregister with bluetooth %d\n",err));
928 }
929 }
930
931 kfree(pHcidevInfo->pBtStackHCIDev);
932 pHcidevInfo->pBtStackHCIDev = NULL;
933}
934
935static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
936{
937 int err;
938 int status = 0;
939
940 do {
941 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: registering HCI... \n"));
942 A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL);
943 /* mark that we are registered */
944 pHcidevInfo->HciRegistered = true;
945 if ((err = hci_register_dev(pHcidevInfo->pBtStackHCIDev)) < 0) {
946 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to register with bluetooth %d\n",err));
947 pHcidevInfo->HciRegistered = false;
948 status = A_ERROR;
949 break;
950 }
951
952 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: HCI registered \n"));
953
954 } while (false);
955
956 return status;
957}
958
959static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo,
960 HCI_TRANSPORT_PACKET_TYPE Type,
961 struct sk_buff *skb)
962{
963 u8 btType;
964 int len;
965 bool success = false;
966 BT_HCI_EVENT_HEADER *pEvent;
967
968 do {
969
970 if (!test_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags)) {
971 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_indicate_recv - not running\n"));
972 break;
973 }
974
975 switch (Type) {
976 case HCI_ACL_TYPE:
977 btType = HCI_ACLDATA_PKT;
978 break;
979 case HCI_EVENT_TYPE:
980 btType = HCI_EVENT_PKT;
981 break;
982 default:
983 btType = 0;
984 A_ASSERT(false);
985 break;
986 }
987
988 if (0 == btType) {
989 break;
990 }
991
992 /* set the final type */
993 bt_cb(skb)->pkt_type = btType;
994 /* set dev */
995 skb->dev = (void *)pHcidevInfo->pBtStackHCIDev;
996 len = skb->len;
997
998 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_RECV)) {
999 if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) {
1000 pEvent = (BT_HCI_EVENT_HEADER *)skb->data;
1001 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV, ("BT HCI EventCode: %d, len:%d \n",
1002 pEvent->EventCode, pEvent->ParamLength));
1003 }
1004 }
1005
1006 /* pass receive packet up the stack */
1007 if (hci_recv_frame(skb) != 0) {
1008 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: hci_recv_frame failed \n"));
1009 break;
1010 } else {
1011 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV,
1012 ("HCI Bridge: Indicated RCV of type:%d, Length:%d \n",btType,len));
1013 }
1014
1015 success = true;
1016
1017 } while (false);
1018
1019 return success;
1020}
1021
1022static struct sk_buff* bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length)
1023{
1024 struct sk_buff *skb;
1025 /* in normal HCI mode we need to alloc from the bt core APIs */
1026 skb = bt_skb_alloc(Length, GFP_ATOMIC);
1027 if (NULL == skb) {
1028 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc bt sk_buff \n"));
1029 }
1030 return skb;
1031}
1032
1033static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb)
1034{
1035 kfree_skb(skb);
1036}
1037
1038#else // { CONFIG_BLUEZ_HCI_BRIDGE
1039
1040 /* stubs when we only want to test the HCI bridging Interface without the HT stack */
1041static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
1042{
1043 return 0;
1044}
1045static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
1046{
1047
1048}
1049static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
1050{
1051 A_ASSERT(false);
1052 return A_ERROR;
1053}
1054
1055static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo,
1056 HCI_TRANSPORT_PACKET_TYPE Type,
1057 struct sk_buff *skb)
1058{
1059 A_ASSERT(false);
1060 return false;
1061}
1062
1063static struct sk_buff* bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length)
1064{
1065 A_ASSERT(false);
1066 return NULL;
1067}
1068static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb)
1069{
1070 A_ASSERT(false);
1071}
1072
1073#endif // } CONFIG_BLUEZ_HCI_BRIDGE
1074
1075#else // { ATH_AR6K_ENABLE_GMBOX
1076
1077 /* stubs when GMBOX support is not needed */
1078
1079#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1080int ar6000_setup_hci(void *ar)
1081#else
1082int ar6000_setup_hci(struct ar6_softc *ar)
1083#endif
1084{
1085 return 0;
1086}
1087
1088#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1089void ar6000_cleanup_hci(void *ar)
1090#else
1091void ar6000_cleanup_hci(struct ar6_softc *ar)
1092#endif
1093{
1094 return;
1095}
1096
1097#ifndef EXPORT_HCI_BRIDGE_INTERFACE
1098void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig)
1099{
1100 return;
1101}
1102#endif
1103
1104#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1105int hci_test_send(void *ar, struct sk_buff *skb)
1106#else
1107int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb)
1108#endif
1109{
1110 return -EOPNOTSUPP;
1111}
1112
1113#endif // } ATH_AR6K_ENABLE_GMBOX
1114
1115
1116#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1117static int __init
1118hcibridge_init_module(void)
1119{
1120 int status;
1121 struct hci_transport_callbacks hciTransCallbacks;
1122
1123 hciTransCallbacks.setupTransport = ar6000_setup_hci;
1124 hciTransCallbacks.cleanupTransport = ar6000_cleanup_hci;
1125
1126 status = ar6000_register_hci_transport(&hciTransCallbacks);
1127 if (status)
1128 return -ENODEV;
1129
1130 return 0;
1131}
1132
1133static void __exit
1134hcibridge_cleanup_module(void)
1135{
1136}
1137
1138module_init(hcibridge_init_module);
1139module_exit(hcibridge_cleanup_module);
1140MODULE_LICENSE("Dual BSD/GPL");
1141#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h
new file mode 100644
index 00000000000..80cef77738f
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h
@@ -0,0 +1,776 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _AR6000_H_
25#define _AR6000_H_
26
27#include <linux/init.h>
28#include <linux/sched.h>
29#include <linux/spinlock.h>
30#include <linux/if_ether.h>
31#include <linux/etherdevice.h>
32#include <net/iw_handler.h>
33#include <linux/if_arp.h>
34#include <linux/ip.h>
35#include <linux/wireless.h>
36#include <net/cfg80211.h>
37#include <linux/module.h>
38#include <asm/io.h>
39
40#include <a_config.h>
41#include <athdefs.h>
42#include "a_osapi.h"
43#include "htc_api.h"
44#include "wmi.h"
45#include "a_drv.h"
46#include "bmi.h"
47#include <ieee80211.h>
48#include <ieee80211_ioctl.h>
49#include <wlan_api.h>
50#include <wmi_api.h>
51#include "pkt_log.h"
52#include "aggr_recv_api.h"
53#include <host_version.h>
54#include <linux/rtnetlink.h>
55#include <linux/moduleparam.h>
56#include "ar6000_api.h"
57#ifdef CONFIG_HOST_TCMD_SUPPORT
58#include <testcmd.h>
59#endif
60#include <linux/firmware.h>
61
62#include "targaddrs.h"
63#include "dbglog_api.h"
64#include "ar6000_diag.h"
65#include "common_drv.h"
66#include "roaming.h"
67#include "hci_transport_api.h"
68#define ATH_MODULE_NAME driver
69#include "a_debug.h"
70#include "hw/apb_map.h"
71#include "hw/rtc_reg.h"
72#include "hw/mbox_reg.h"
73#include "gpio_reg.h"
74
75#define ATH_DEBUG_DBG_LOG ATH_DEBUG_MAKE_MODULE_MASK(0)
76#define ATH_DEBUG_WLAN_CONNECT ATH_DEBUG_MAKE_MODULE_MASK(1)
77#define ATH_DEBUG_WLAN_SCAN ATH_DEBUG_MAKE_MODULE_MASK(2)
78#define ATH_DEBUG_WLAN_TX ATH_DEBUG_MAKE_MODULE_MASK(3)
79#define ATH_DEBUG_WLAN_RX ATH_DEBUG_MAKE_MODULE_MASK(4)
80#define ATH_DEBUG_HTC_RAW ATH_DEBUG_MAKE_MODULE_MASK(5)
81#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
82#define ATH_DEBUG_HCI_RECV ATH_DEBUG_MAKE_MODULE_MASK(7)
83#define ATH_DEBUG_HCI_SEND ATH_DEBUG_MAKE_MODULE_MASK(8)
84#define ATH_DEBUG_HCI_DUMP ATH_DEBUG_MAKE_MODULE_MASK(9)
85
86#ifndef __dev_put
87#define __dev_put(dev) dev_put(dev)
88#endif
89
90
91#define USER_SAVEDKEYS_STAT_INIT 0
92#define USER_SAVEDKEYS_STAT_RUN 1
93
94// TODO this needs to move into the AR_SOFTC struct
95struct USER_SAVEDKEYS {
96 struct ieee80211req_key ucast_ik;
97 struct ieee80211req_key bcast_ik;
98 CRYPTO_TYPE keyType;
99 bool keyOk;
100};
101
102#define DBG_INFO 0x00000001
103#define DBG_ERROR 0x00000002
104#define DBG_WARNING 0x00000004
105#define DBG_SDIO 0x00000008
106#define DBG_HIF 0x00000010
107#define DBG_HTC 0x00000020
108#define DBG_WMI 0x00000040
109#define DBG_WMI2 0x00000080
110#define DBG_DRIVER 0x00000100
111
112#define DBG_DEFAULTS (DBG_ERROR|DBG_WARNING)
113
114
115int ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
116int ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
117
118#ifdef __cplusplus
119extern "C" {
120#endif
121
122#define MAX_AR6000 1
123#define AR6000_MAX_RX_BUFFERS 16
124#define AR6000_BUFFER_SIZE 1664
125#define AR6000_MAX_AMSDU_RX_BUFFERS 4
126#define AR6000_AMSDU_REFILL_THRESHOLD 3
127#define AR6000_AMSDU_BUFFER_SIZE (WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH + 128)
128#define AR6000_MAX_RX_MESSAGE_SIZE (max(WMI_MAX_NORMAL_RX_DATA_FRAME_LENGTH,WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH))
129
130#define AR6000_TX_TIMEOUT 10
131#define AR6000_ETH_ADDR_LEN 6
132#define AR6000_MAX_ENDPOINTS 4
133#define MAX_NODE_NUM 15
134/* MAX_HI_COOKIE_NUM are reserved for high priority traffic */
135#define MAX_DEF_COOKIE_NUM 180
136#define MAX_HI_COOKIE_NUM 18 /* 10% of MAX_COOKIE_NUM */
137#define MAX_COOKIE_NUM (MAX_DEF_COOKIE_NUM + MAX_HI_COOKIE_NUM)
138
139/* MAX_DEFAULT_SEND_QUEUE_DEPTH is used to set the default queue depth for the
140 * WMM send queues. If a queue exceeds this depth htc will query back to the
141 * OS specific layer by calling EpSendFull(). This gives the OS layer the
142 * opportunity to drop the packet if desired. Therefore changing
143 * MAX_DEFAULT_SEND_QUEUE_DEPTH does not affect resource utilization but
144 * does impact the threshold used to identify if a packet should be
145 * dropped. */
146#define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC)
147
148#define AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT 1
149#define AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT 1
150#define A_DISCONNECT_TIMER_INTERVAL 10 * 1000
151#define A_DEFAULT_LISTEN_INTERVAL 100
152#define A_MAX_WOW_LISTEN_INTERVAL 1000
153
154enum {
155 DRV_HB_CHALLENGE = 0,
156 APP_HB_CHALLENGE
157};
158
159enum {
160 WLAN_INIT_MODE_NONE = 0,
161 WLAN_INIT_MODE_USR,
162 WLAN_INIT_MODE_UDEV,
163 WLAN_INIT_MODE_DRV
164};
165
166/* Suspend - configuration */
167enum {
168 WLAN_SUSPEND_CUT_PWR = 0,
169 WLAN_SUSPEND_DEEP_SLEEP,
170 WLAN_SUSPEND_WOW,
171 WLAN_SUSPEND_CUT_PWR_IF_BT_OFF
172};
173
174/* WiFi OFF - configuration */
175enum {
176 WLAN_OFF_CUT_PWR = 0,
177 WLAN_OFF_DEEP_SLEEP,
178};
179
180/* WLAN low power state */
181enum {
182 WLAN_POWER_STATE_ON = 0,
183 WLAN_POWER_STATE_CUT_PWR = 1,
184 WLAN_POWER_STATE_DEEP_SLEEP,
185 WLAN_POWER_STATE_WOW
186};
187
188/* WLAN WoW State */
189enum {
190 WLAN_WOW_STATE_NONE = 0,
191 WLAN_WOW_STATE_SUSPENDED,
192 WLAN_WOW_STATE_SUSPENDING
193};
194
195
196typedef enum _AR6K_BIN_FILE {
197 AR6K_OTP_FILE,
198 AR6K_FIRMWARE_FILE,
199 AR6K_PATCH_FILE,
200 AR6K_BOARD_DATA_FILE,
201} AR6K_BIN_FILE;
202
203#ifdef SETUPHCI_ENABLED
204#define SETUPHCI_DEFAULT 1
205#else
206#define SETUPHCI_DEFAULT 0
207#endif /* SETUPHCI_ENABLED */
208
209#ifdef SETUPBTDEV_ENABLED
210#define SETUPBTDEV_DEFAULT 1
211#else
212#define SETUPBTDEV_DEFAULT 0
213#endif /* SETUPBTDEV_ENABLED */
214
215#ifdef ENABLEUARTPRINT_SET
216#define ENABLEUARTPRINT_DEFAULT 1
217#else
218#define ENABLEUARTPRINT_DEFAULT 0
219#endif /* ENABLEARTPRINT_SET */
220
221#ifdef ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER
222#define NOHIFSCATTERSUPPORT_DEFAULT 1
223#else /* ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER */
224#define NOHIFSCATTERSUPPORT_DEFAULT 0
225#endif /* ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER */
226
227
228#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE)
229
230#ifdef CONFIG_AR600x_BT_QCOM
231#define ATH6KL_BT_DEV 1
232#elif defined(CONFIG_AR600x_BT_CSR)
233#define ATH6KL_BT_DEV 2
234#else
235#define ATH6KL_BT_DEV 3
236#endif
237
238#ifdef CONFIG_AR600x_DUAL_ANTENNA
239#define ATH6KL_BT_ANTENNA 2
240#else
241#define ATH6KL_BT_ANTENNA 1
242#endif
243
244#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */
245
246#ifdef AR600x_BT_AR3001
247#define AR3KHCIBAUD_DEFAULT 3000000
248#define HCIUARTSCALE_DEFAULT 1
249#define HCIUARTSTEP_DEFAULT 8937
250#else
251#define AR3KHCIBAUD_DEFAULT 0
252#define HCIUARTSCALE_DEFAULT 0
253#define HCIUARTSTEP_DEFAULT 0
254#endif /* AR600x_BT_AR3001 */
255
256#define WLAN_INIT_MODE_DEFAULT WLAN_INIT_MODE_DRV
257
258#define AR6K_PATCH_DOWNLOAD_ADDRESS(_param, _ver) do { \
259 if ((_ver) == AR6003_REV1_VERSION) { \
260 (_param) = AR6003_REV1_PATCH_DOWNLOAD_ADDRESS; \
261 } else if ((_ver) == AR6003_REV2_VERSION) { \
262 (_param) = AR6003_REV2_PATCH_DOWNLOAD_ADDRESS; \
263 } else { \
264 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
265 A_ASSERT(0); \
266 } \
267} while (0)
268
269#define AR6K_DATA_DOWNLOAD_ADDRESS(_param, _ver) do { \
270 if ((_ver) == AR6003_REV1_VERSION) { \
271 (_param) = AR6003_REV1_DATA_DOWNLOAD_ADDRESS; \
272 } else if ((_ver) == AR6003_REV2_VERSION) { \
273 (_param) = AR6003_REV2_DATA_DOWNLOAD_ADDRESS; \
274 } else { \
275 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
276 A_ASSERT(0); \
277 } \
278} while (0)
279
280#define AR6K_DATASET_PATCH_ADDRESS(_param, _ver) do { \
281 if ((_ver) == AR6003_REV2_VERSION) { \
282 (_param) = AR6003_REV2_DATASET_PATCH_ADDRESS; \
283 } else if ((_ver) == AR6003_REV3_VERSION) { \
284 (_param) = AR6003_REV3_DATASET_PATCH_ADDRESS; \
285 } else { \
286 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
287 A_ASSERT(0); \
288 } \
289} while (0)
290
291#define AR6K_APP_LOAD_ADDRESS(_param, _ver) do { \
292 if ((_ver) == AR6003_REV2_VERSION) { \
293 (_param) = AR6003_REV2_APP_LOAD_ADDRESS; \
294 } else if ((_ver) == AR6003_REV3_VERSION) { \
295 (_param) = AR6003_REV3_APP_LOAD_ADDRESS; \
296 } else { \
297 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
298 A_ASSERT(0); \
299 } \
300} while (0)
301
302#define AR6K_APP_START_OVERRIDE_ADDRESS(_param, _ver) do { \
303 if ((_ver) == AR6003_REV2_VERSION) { \
304 (_param) = AR6003_REV2_APP_START_OVERRIDE; \
305 } else if ((_ver) == AR6003_REV3_VERSION) { \
306 (_param) = AR6003_REV3_APP_START_OVERRIDE; \
307 } else { \
308 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
309 A_ASSERT(0); \
310 } \
311} while (0)
312
313/* AR6003 1.0 definitions */
314#define AR6003_REV1_VERSION 0x300002ba
315#define AR6003_REV1_DATA_DOWNLOAD_ADDRESS AR6003_REV1_OTP_DATA_ADDRESS
316#define AR6003_REV1_PATCH_DOWNLOAD_ADDRESS 0x57ea6c
317#define AR6003_REV1_OTP_FILE "ath6k/AR6003/hw1.0/otp.bin.z77"
318#define AR6003_REV1_FIRMWARE_FILE "ath6k/AR6003/hw1.0/athwlan.bin.z77"
319#define AR6003_REV1_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw1.0/athtcmd_ram.bin"
320#define AR6003_REV1_ART_FIRMWARE_FILE "ath6k/AR6003/hw1.0/device.bin"
321#define AR6003_REV1_PATCH_FILE "ath6k/AR6003/hw1.0/data.patch.bin"
322#define AR6003_REV1_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw1.0/endpointping.bin"
323#ifdef CONFIG_AR600x_SD31_XXX
324#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD31.bin"
325#elif defined(CONFIG_AR600x_SD32_XXX)
326#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD32.bin"
327#elif defined(CONFIG_AR600x_WB31_XXX)
328#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.WB31.bin"
329#else
330#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.CUSTOM.bin"
331#endif /* Board Data File */
332
333/* AR6003 2.0 definitions */
334#define AR6003_REV2_VERSION 0x30000384
335#define AR6003_REV2_DATA_DOWNLOAD_ADDRESS AR6003_REV2_OTP_DATA_ADDRESS
336#define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS 0x57e910
337#define AR6003_REV2_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77"
338#define AR6003_REV2_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77"
339#define AR6003_REV2_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin"
340#define AR6003_REV2_ART_FIRMWARE_FILE "ath6k/AR6003/hw2.0/device.bin"
341#define AR6003_REV2_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin"
342#define AR6003_REV2_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw2.0/endpointping.bin"
343#ifdef CONFIG_AR600x_SD31_XXX
344#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin"
345#elif defined(CONFIG_AR600x_SD32_XXX)
346#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD32.bin"
347#elif defined(CONFIG_AR600x_WB31_XXX)
348#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.WB31.bin"
349#else
350#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.CUSTOM.bin"
351#endif /* Board Data File */
352
353/* AR6003 3.0 definitions */
354#define AR6003_REV3_VERSION 0x30000582
355#define AR6003_REV3_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin"
356#define AR6003_REV3_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin"
357#define AR6003_REV3_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin"
358#define AR6003_REV3_ART_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/device.bin"
359#define AR6003_REV3_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin"
360#define AR6003_REV3_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/endpointping.bin"
361#ifdef CONFIG_AR600x_SD31_XXX
362#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
363#elif defined(CONFIG_AR600x_SD32_XXX)
364#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.SD32.bin"
365#elif defined(CONFIG_AR600x_WB31_XXX)
366#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.WB31.bin"
367#else
368#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.CUSTOM.bin"
369#endif /* Board Data File */
370
371
372/* Power states */
373enum {
374 WLAN_PWR_CTRL_UP = 0,
375 WLAN_PWR_CTRL_CUT_PWR,
376 WLAN_PWR_CTRL_DEEP_SLEEP,
377 WLAN_PWR_CTRL_WOW,
378 WLAN_PWR_CTRL_DEEP_SLEEP_DISABLED
379};
380
381/* HTC RAW streams */
382typedef enum _HTC_RAW_STREAM_ID {
383 HTC_RAW_STREAM_NOT_MAPPED = -1,
384 HTC_RAW_STREAM_0 = 0,
385 HTC_RAW_STREAM_1 = 1,
386 HTC_RAW_STREAM_2 = 2,
387 HTC_RAW_STREAM_3 = 3,
388 HTC_RAW_STREAM_NUM_MAX
389} HTC_RAW_STREAM_ID;
390
391#define RAW_HTC_READ_BUFFERS_NUM 4
392#define RAW_HTC_WRITE_BUFFERS_NUM 4
393
394#define HTC_RAW_BUFFER_SIZE 1664
395
396typedef struct {
397 int currPtr;
398 int length;
399 unsigned char data[HTC_RAW_BUFFER_SIZE];
400 struct htc_packet HTCPacket;
401} raw_htc_buffer;
402
403#ifdef CONFIG_HOST_TCMD_SUPPORT
404/*
405 * add TCMD_MODE besides wmi and bypasswmi
406 * in TCMD_MODE, only few TCMD releated wmi commands
407 * counld be hanlder
408 */
409enum {
410 AR6000_WMI_MODE = 0,
411 AR6000_BYPASS_MODE,
412 AR6000_TCMD_MODE,
413 AR6000_WLAN_MODE
414};
415#endif /* CONFIG_HOST_TCMD_SUPPORT */
416
417struct ar_wep_key {
418 u8 arKeyIndex;
419 u8 arKeyLen;
420 u8 arKey[64];
421} ;
422
423struct ar_key {
424 u8 key[WLAN_MAX_KEY_LEN];
425 u8 key_len;
426 u8 seq[IW_ENCODE_SEQ_MAX_SIZE];
427 u8 seq_len;
428 u32 cipher;
429};
430
431enum {
432 SME_DISCONNECTED,
433 SME_CONNECTING,
434 SME_CONNECTED
435};
436
437struct ar_node_mapping {
438 u8 macAddress[6];
439 u8 epId;
440 u8 txPending;
441};
442
443struct ar_cookie {
444 unsigned long arc_bp[2]; /* Must be first field */
445 struct htc_packet HtcPkt; /* HTC packet wrapper */
446 struct ar_cookie *arc_list_next;
447};
448
449struct ar_hb_chlng_resp {
450 A_TIMER timer;
451 u32 frequency;
452 u32 seqNum;
453 bool outstanding;
454 u8 missCnt;
455 u8 missThres;
456};
457
458/* Per STA data, used in AP mode */
459/*TODO: All this should move to OS independent dir */
460
461#define STA_PWR_MGMT_MASK 0x1
462#define STA_PWR_MGMT_SHIFT 0x0
463#define STA_PWR_MGMT_AWAKE 0x0
464#define STA_PWR_MGMT_SLEEP 0x1
465
466#define STA_SET_PWR_SLEEP(sta) (sta->flags |= (STA_PWR_MGMT_MASK << STA_PWR_MGMT_SHIFT))
467#define STA_CLR_PWR_SLEEP(sta) (sta->flags &= ~(STA_PWR_MGMT_MASK << STA_PWR_MGMT_SHIFT))
468#define STA_IS_PWR_SLEEP(sta) ((sta->flags >> STA_PWR_MGMT_SHIFT) & STA_PWR_MGMT_MASK)
469
470#define STA_PS_POLLED_MASK 0x1
471#define STA_PS_POLLED_SHIFT 0x1
472#define STA_SET_PS_POLLED(sta) (sta->flags |= (STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
473#define STA_CLR_PS_POLLED(sta) (sta->flags &= ~(STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
474#define STA_IS_PS_POLLED(sta) (sta->flags & (STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
475
476typedef struct {
477 u16 flags;
478 u8 mac[ATH_MAC_LEN];
479 u8 aid;
480 u8 keymgmt;
481 u8 ucipher;
482 u8 auth;
483 u8 wpa_ie[IEEE80211_MAX_IE];
484 A_NETBUF_QUEUE_T psq; /* power save q */
485 A_MUTEX_T psqLock;
486} sta_t;
487
488typedef struct ar6_raw_htc {
489 HTC_ENDPOINT_ID arRaw2EpMapping[HTC_RAW_STREAM_NUM_MAX];
490 HTC_RAW_STREAM_ID arEp2RawMapping[ENDPOINT_MAX];
491 struct semaphore raw_htc_read_sem[HTC_RAW_STREAM_NUM_MAX];
492 struct semaphore raw_htc_write_sem[HTC_RAW_STREAM_NUM_MAX];
493 wait_queue_head_t raw_htc_read_queue[HTC_RAW_STREAM_NUM_MAX];
494 wait_queue_head_t raw_htc_write_queue[HTC_RAW_STREAM_NUM_MAX];
495 raw_htc_buffer raw_htc_read_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_READ_BUFFERS_NUM];
496 raw_htc_buffer raw_htc_write_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_WRITE_BUFFERS_NUM];
497 bool write_buffer_available[HTC_RAW_STREAM_NUM_MAX];
498 bool read_buffer_available[HTC_RAW_STREAM_NUM_MAX];
499} AR_RAW_HTC_T;
500
501struct ar6_softc {
502 struct net_device *arNetDev; /* net_device pointer */
503 void *arWmi;
504 int arTxPending[ENDPOINT_MAX];
505 int arTotalTxDataPending;
506 u8 arNumDataEndPts;
507 bool arWmiEnabled;
508 bool arWmiReady;
509 bool arConnected;
510 HTC_HANDLE arHtcTarget;
511 void *arHifDevice;
512 spinlock_t arLock;
513 struct semaphore arSem;
514 int arSsidLen;
515 u_char arSsid[32];
516 u8 arNextMode;
517 u8 arNetworkType;
518 u8 arDot11AuthMode;
519 u8 arAuthMode;
520 u8 arPairwiseCrypto;
521 u8 arPairwiseCryptoLen;
522 u8 arGroupCrypto;
523 u8 arGroupCryptoLen;
524 u8 arDefTxKeyIndex;
525 struct ar_wep_key arWepKeyList[WMI_MAX_KEY_INDEX + 1];
526 u8 arBssid[6];
527 u8 arReqBssid[6];
528 u16 arChannelHint;
529 u16 arBssChannel;
530 u16 arListenIntervalB;
531 u16 arListenIntervalT;
532 struct ar6000_version arVersion;
533 u32 arTargetType;
534 s8 arRssi;
535 u8 arTxPwr;
536 bool arTxPwrSet;
537 s32 arBitRate;
538 struct net_device_stats arNetStats;
539 struct iw_statistics arIwStats;
540 s8 arNumChannels;
541 u16 arChannelList[32];
542 u32 arRegCode;
543 bool statsUpdatePending;
544 TARGET_STATS arTargetStats;
545 s8 arMaxRetries;
546 u8 arPhyCapability;
547#ifdef CONFIG_HOST_TCMD_SUPPORT
548 u32 arTargetMode;
549 void *tcmd_rx_report;
550 int tcmd_rx_report_len;
551#endif
552 AR6000_WLAN_STATE arWlanState;
553 struct ar_node_mapping arNodeMap[MAX_NODE_NUM];
554 u8 arIbssPsEnable;
555 u8 arNodeNum;
556 u8 arNexEpId;
557 struct ar_cookie *arCookieList;
558 u32 arCookieCount;
559 u32 arRateMask;
560 u8 arSkipScan;
561 u16 arBeaconInterval;
562 bool arConnectPending;
563 bool arWmmEnabled;
564 struct ar_hb_chlng_resp arHBChallengeResp;
565 u8 arKeepaliveConfigured;
566 u32 arMgmtFilter;
567 HTC_ENDPOINT_ID arAc2EpMapping[WMM_NUM_AC];
568 bool arAcStreamActive[WMM_NUM_AC];
569 u8 arAcStreamPriMap[WMM_NUM_AC];
570 u8 arHiAcStreamActivePri;
571 u8 arEp2AcMapping[ENDPOINT_MAX];
572 HTC_ENDPOINT_ID arControlEp;
573#ifdef HTC_RAW_INTERFACE
574 AR_RAW_HTC_T *arRawHtc;
575#endif
576 bool arNetQueueStopped;
577 bool arRawIfInit;
578 int arDeviceIndex;
579 struct common_credit_state_info arCreditStateInfo;
580 bool arWMIControlEpFull;
581 bool dbgLogFetchInProgress;
582 u8 log_buffer[DBGLOG_HOST_LOG_BUFFER_SIZE];
583 u32 log_cnt;
584 u32 dbglog_init_done;
585 u32 arConnectCtrlFlags;
586 s32 user_savedkeys_stat;
587 u32 user_key_ctrl;
588 struct USER_SAVEDKEYS user_saved_keys;
589 USER_RSSI_THOLD rssi_map[12];
590 u8 arUserBssFilter;
591 u16 ap_profile_flag; /* AP mode */
592 WMI_AP_ACL g_acl; /* AP mode */
593 sta_t sta_list[AP_MAX_NUM_STA]; /* AP mode */
594 u8 sta_list_index; /* AP mode */
595 struct ieee80211req_key ap_mode_bkey; /* AP mode */
596 A_NETBUF_QUEUE_T mcastpsq; /* power save q for Mcast frames */
597 A_MUTEX_T mcastpsqLock;
598 bool DTIMExpired; /* flag to indicate DTIM expired */
599 u8 intra_bss; /* enable/disable intra bss data forward */
600 void *aggr_cntxt;
601#ifndef EXPORT_HCI_BRIDGE_INTERFACE
602 void *hcidev_info;
603#endif
604 WMI_AP_MODE_STAT arAPStats;
605 u8 ap_hidden_ssid;
606 u8 ap_country_code[3];
607 u8 ap_wmode;
608 u8 ap_dtim_period;
609 u16 ap_beacon_interval;
610 u16 arRTS;
611 u16 arACS; /* AP mode - Auto Channel Selection */
612 struct htc_packet_queue amsdu_rx_buffer_queue;
613 bool bIsDestroyProgress; /* flag to indicate ar6k destroy is in progress */
614 A_TIMER disconnect_timer;
615 u8 rxMetaVersion;
616#ifdef WAPI_ENABLE
617 u8 arWapiEnable;
618#endif
619 WMI_BTCOEX_CONFIG_EVENT arBtcoexConfig;
620 WMI_BTCOEX_STATS_EVENT arBtcoexStats;
621 s32 (*exitCallback)(void *config); /* generic callback at AR6K exit */
622 struct hif_device_os_device_info osDevInfo;
623 struct wireless_dev *wdev;
624 struct cfg80211_scan_request *scan_request;
625 struct ar_key keys[WMI_MAX_KEY_INDEX + 1];
626 u32 smeState;
627 u16 arWlanPowerState;
628 bool arWlanOff;
629#ifdef CONFIG_PM
630 u16 arWowState;
631 bool arBTOff;
632 bool arBTSharing;
633 u16 arSuspendConfig;
634 u16 arWlanOffConfig;
635 u16 arWow2Config;
636#endif
637 u8 scan_triggered;
638 WMI_SCAN_PARAMS_CMD scParams;
639#define AR_MCAST_FILTER_MAC_ADDR_SIZE 4
640 u8 mcast_filters[MAC_MAX_FILTERS_PER_LIST][AR_MCAST_FILTER_MAC_ADDR_SIZE];
641 u8 bdaddr[6];
642 bool scanSpecificSsid;
643#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
644 void *arApDev;
645#endif
646 u8 arAutoAuthStage;
647
648 u8 *fw_otp;
649 size_t fw_otp_len;
650 u8 *fw;
651 size_t fw_len;
652 u8 *fw_patch;
653 size_t fw_patch_len;
654 u8 *fw_data;
655 size_t fw_data_len;
656};
657
658#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
659struct ar_virtual_interface {
660 struct net_device *arNetDev; /* net_device pointer */
661 struct ar6_softc *arDev; /* ar device pointer */
662 struct net_device *arStaNetDev; /* net_device pointer */
663};
664#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
665
666static inline void *ar6k_priv(struct net_device *dev)
667{
668 return (wdev_priv(dev->ieee80211_ptr));
669}
670
671#define SET_HCI_BUS_TYPE(pHciDev, __bus, __type) do { \
672 (pHciDev)->bus = (__bus); \
673 (pHciDev)->dev_type = (__type); \
674} while(0)
675
676#define GET_INODE_FROM_FILEP(filp) \
677 (filp)->f_path.dentry->d_inode
678
679#define arAc2EndpointID(ar,ac) (ar)->arAc2EpMapping[(ac)]
680#define arSetAc2EndpointIDMap(ar,ac,ep) \
681{ (ar)->arAc2EpMapping[(ac)] = (ep); \
682 (ar)->arEp2AcMapping[(ep)] = (ac); }
683#define arEndpoint2Ac(ar,ep) (ar)->arEp2AcMapping[(ep)]
684
685#define arRawIfEnabled(ar) (ar)->arRawIfInit
686#define arRawStream2EndpointID(ar,raw) (ar)->arRawHtc->arRaw2EpMapping[(raw)]
687#define arSetRawStream2EndpointIDMap(ar,raw,ep) \
688{ (ar)->arRawHtc->arRaw2EpMapping[(raw)] = (ep); \
689 (ar)->arRawHtc->arEp2RawMapping[(ep)] = (raw); }
690#define arEndpoint2RawStreamID(ar,ep) (ar)->arRawHtc->arEp2RawMapping[(ep)]
691
692struct ar_giwscan_param {
693 char *current_ev;
694 char *end_buf;
695 u32 bytes_needed;
696 struct iw_request_info *info;
697};
698
699#define AR6000_STAT_INC(ar, stat) (ar->arNetStats.stat++)
700
701#define AR6000_SPIN_LOCK(lock, param) do { \
702 if (irqs_disabled()) { \
703 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("IRQs disabled:AR6000_LOCK\n")); \
704 } \
705 spin_lock_bh(lock); \
706} while (0)
707
708#define AR6000_SPIN_UNLOCK(lock, param) do { \
709 if (irqs_disabled()) { \
710 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("IRQs disabled: AR6000_UNLOCK\n")); \
711 } \
712 spin_unlock_bh(lock); \
713} while (0)
714
715void ar6000_init_profile_info(struct ar6_softc *ar);
716void ar6000_install_static_wep_keys(struct ar6_softc *ar);
717int ar6000_init(struct net_device *dev);
718int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar);
719void ar6000_TxDataCleanup(struct ar6_softc *ar);
720int ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev);
721void ar6000_restart_endpoint(struct net_device *dev);
722void ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs);
723
724#ifdef HTC_RAW_INTERFACE
725
726#ifndef __user
727#define __user
728#endif
729
730int ar6000_htc_raw_open(struct ar6_softc *ar);
731int ar6000_htc_raw_close(struct ar6_softc *ar);
732ssize_t ar6000_htc_raw_read(struct ar6_softc *ar,
733 HTC_RAW_STREAM_ID StreamID,
734 char __user *buffer, size_t count);
735ssize_t ar6000_htc_raw_write(struct ar6_softc *ar,
736 HTC_RAW_STREAM_ID StreamID,
737 char __user *buffer, size_t count);
738
739#endif /* HTC_RAW_INTERFACE */
740
741/* AP mode */
742/*TODO: These routines should be moved to a file that is common across OS */
743sta_t *
744ieee80211_find_conn(struct ar6_softc *ar, u8 *node_addr);
745
746sta_t *
747ieee80211_find_conn_for_aid(struct ar6_softc *ar, u8 aid);
748
749u8 remove_sta(struct ar6_softc *ar, u8 *mac, u16 reason);
750
751/* HCI support */
752
753#ifndef EXPORT_HCI_BRIDGE_INTERFACE
754int ar6000_setup_hci(struct ar6_softc *ar);
755void ar6000_cleanup_hci(struct ar6_softc *ar);
756void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig);
757
758/* HCI bridge testing */
759int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb);
760#endif
761
762ATH_DEBUG_DECLARE_EXTERN(htc);
763ATH_DEBUG_DECLARE_EXTERN(wmi);
764ATH_DEBUG_DECLARE_EXTERN(bmi);
765ATH_DEBUG_DECLARE_EXTERN(hif);
766ATH_DEBUG_DECLARE_EXTERN(wlan);
767ATH_DEBUG_DECLARE_EXTERN(misc);
768
769extern u8 bcast_mac[];
770extern u8 null_mac[];
771
772#ifdef __cplusplus
773}
774#endif
775
776#endif /* _AR6000_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h b/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h
new file mode 100644
index 00000000000..39e0873aff2
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h
@@ -0,0 +1,36 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4// The software source and binaries included in this development package are
5// licensed, not sold. You, or your company, received the package under one
6// or more license agreements. The rights granted to you are specifically
7// listed in these license agreement(s). All other rights remain with Atheros
8// Communications, Inc., its subsidiaries, or the respective owner including
9// those listed on the included copyright notices. Distribution of any
10// portion of this package must be in strict compliance with the license
11// agreement(s) terms.
12// </copyright>
13//
14// <summary>
15// PAL driver for AR6003
16// </summary>
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22#ifndef _AR6K_PAL_H_
23#define _AR6K_PAL_H_
24#define HCI_GET_OP_CODE(p) (((u16)((p)[1])) << 8) | ((u16)((p)[0]))
25
26/* transmit packet reserve offset */
27#define TX_PACKET_RSV_OFFSET 32
28/* pal specific config structure */
29typedef bool (*ar6k_pal_recv_pkt_t)(void *pHciPalInfo, void *skb);
30typedef struct ar6k_pal_config_s
31{
32 ar6k_pal_recv_pkt_t fpar6k_pal_recv_pkt;
33}ar6k_pal_config_t;
34
35void register_pal_cb(ar6k_pal_config_t *palConfig_p);
36#endif /* _AR6K_PAL_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h
new file mode 100644
index 00000000000..184dbdb5049
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h
@@ -0,0 +1,190 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _AR6XAPI_LINUX_H
25#define _AR6XAPI_LINUX_H
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30struct ar6_softc;
31
32void ar6000_ready_event(void *devt, u8 *datap, u8 phyCap,
33 u32 sw_ver, u32 abi_ver);
34int ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid);
35void ar6000_connect_event(struct ar6_softc *ar, u16 channel,
36 u8 *bssid, u16 listenInterval,
37 u16 beaconInterval, NETWORK_TYPE networkType,
38 u8 beaconIeLen, u8 assocReqLen,
39 u8 assocRespLen,u8 *assocInfo);
40void ar6000_disconnect_event(struct ar6_softc *ar, u8 reason,
41 u8 *bssid, u8 assocRespLen,
42 u8 *assocInfo, u16 protocolReasonStatus);
43void ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid,
44 bool ismcast);
45void ar6000_bitrate_rx(void *devt, s32 rateKbps);
46void ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList);
47void ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode);
48void ar6000_txPwr_rx(void *devt, u8 txPwr);
49void ar6000_keepalive_rx(void *devt, u8 configured);
50void ar6000_neighborReport_event(struct ar6_softc *ar, int numAps,
51 WMI_NEIGHBOR_INFO *info);
52void ar6000_set_numdataendpts(struct ar6_softc *ar, u32 num);
53void ar6000_scanComplete_event(struct ar6_softc *ar, int status);
54void ar6000_targetStats_event(struct ar6_softc *ar, u8 *ptr, u32 len);
55void ar6000_rssiThreshold_event(struct ar6_softc *ar,
56 WMI_RSSI_THRESHOLD_VAL newThreshold,
57 s16 rssi);
58void ar6000_reportError_event(struct ar6_softc *, WMI_TARGET_ERROR_VAL errorVal);
59void ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cac_indication,
60 u8 statusCode, u8 *tspecSuggestion);
61void ar6000_channel_change_event(struct ar6_softc *ar, u16 oldChannel, u16 newChannel);
62void ar6000_hbChallengeResp_event(struct ar6_softc *, u32 cookie, u32 source);
63void
64ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl);
65
66void
67ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p);
68
69void
70ar6000_wow_list_event(struct ar6_softc *ar, u8 num_filters,
71 WMI_GET_WOW_LIST_REPLY *wow_reply);
72
73void ar6000_pmkid_list_event(void *devt, u8 numPMKID,
74 WMI_PMKID *pmkidList, u8 *bssidList);
75
76void ar6000_gpio_intr_rx(u32 intr_mask, u32 input_values);
77void ar6000_gpio_data_rx(u32 reg_id, u32 value);
78void ar6000_gpio_ack_rx(void);
79
80s32 rssi_compensation_calc_tcmd(u32 freq, s32 rssi, u32 totalPkt);
81s16 rssi_compensation_calc(struct ar6_softc *ar, s16 rssi);
82s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above);
83
84void ar6000_dbglog_init_done(struct ar6_softc *ar);
85
86#ifdef CONFIG_HOST_TCMD_SUPPORT
87void ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len);
88#endif
89
90void ar6000_tx_retry_err_event(void *devt);
91
92void ar6000_snrThresholdEvent_rx(void *devt,
93 WMI_SNR_THRESHOLD_VAL newThreshold,
94 u8 snr);
95
96void ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL range, u8 lqVal);
97
98
99void ar6000_ratemask_rx(void *devt, u32 ratemask);
100
101int ar6000_get_driver_cfg(struct net_device *dev,
102 u16 cfgParam,
103 void *result);
104void ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *data, int len);
105
106void ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped,
107 s8 *buffer, u32 length);
108
109int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar);
110
111void ar6000_peer_event(void *devt, u8 eventCode, u8 *bssid);
112
113void ar6000_indicate_tx_activity(void *devt, u8 trafficClass, bool Active);
114HTC_ENDPOINT_ID ar6000_ac2_endpoint_id ( void * devt, u8 ac);
115u8 ar6000_endpoint_id2_ac (void * devt, HTC_ENDPOINT_ID ep );
116
117void ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, u32 len);
118
119void ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, u32 len) ;
120
121void ar6000_dset_open_req(void *devt,
122 u32 id,
123 u32 targ_handle,
124 u32 targ_reply_fn,
125 u32 targ_reply_arg);
126void ar6000_dset_close(void *devt, u32 access_cookie);
127void ar6000_dset_data_req(void *devt,
128 u32 access_cookie,
129 u32 offset,
130 u32 length,
131 u32 targ_buf,
132 u32 targ_reply_fn,
133 u32 targ_reply_arg);
134
135
136#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
137void prof_count_rx(unsigned int addr, unsigned int count);
138#endif
139
140u32 ar6000_getnodeAge (void);
141
142u32 ar6000_getclkfreq (void);
143
144int ar6000_ap_mode_profile_commit(struct ar6_softc *ar);
145
146struct ieee80211req_wpaie;
147int
148ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie);
149
150int is_iwioctl_allowed(u8 mode, u16 cmd);
151
152int is_xioctl_allowed(u8 mode, int cmd);
153
154void ar6000_pspoll_event(struct ar6_softc *ar,u8 aid);
155
156void ar6000_dtimexpiry_event(struct ar6_softc *ar);
157
158void ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *cmd);
159void ar6000_aggr_rcv_addba_resp_evt(struct ar6_softc *ar, WMI_ADDBA_RESP_EVENT *cmd);
160void ar6000_aggr_rcv_delba_req_evt(struct ar6_softc *ar, WMI_DELBA_EVENT *cmd);
161void ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd);
162
163#ifdef WAPI_ENABLE
164int ap_set_wapi_key(struct ar6_softc *ar, void *ik);
165void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac);
166#endif
167
168int ar6000_connect_to_ap(struct ar6_softc *ar);
169int ar6000_disconnect(struct ar6_softc *ar);
170int ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool suspending);
171int ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state);
172int ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 state);
173
174#ifdef CONFIG_PM
175int ar6000_suspend_ev(void *context);
176int ar6000_resume_ev(void *context);
177int ar6000_power_change_ev(void *context, u32 config);
178void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent);
179#endif
180
181#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
182int ar6000_add_ap_interface(struct ar6_softc *ar, char *ifname);
183int ar6000_remove_ap_interface(struct ar6_softc *ar);
184#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
185
186#ifdef __cplusplus
187}
188#endif
189
190#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h
new file mode 100644
index 00000000000..3d5f01da543
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h
@@ -0,0 +1,1217 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _ATHDRV_LINUX_H
25#define _ATHDRV_LINUX_H
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31
32/*
33 * There are two types of ioctl's here: Standard ioctls and
34 * eXtended ioctls. All extended ioctls (XIOCTL) are multiplexed
35 * off of the single ioctl command, AR6000_IOCTL_EXTENDED. The
36 * arguments for every XIOCTL starts with a 32-bit command word
37 * that is used to select which extended ioctl is in use. After
38 * the command word are command-specific arguments.
39 */
40
41/* Linux standard Wireless Extensions, private ioctl interfaces */
42#define IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0)
43#define IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+1)
44#define IEEE80211_IOCTL_DELKEY (SIOCIWFIRSTPRIV+2)
45#define IEEE80211_IOCTL_SETMLME (SIOCIWFIRSTPRIV+3)
46#define IEEE80211_IOCTL_ADDPMKID (SIOCIWFIRSTPRIV+4)
47#define IEEE80211_IOCTL_SETOPTIE (SIOCIWFIRSTPRIV+5)
48//#define IEEE80211_IOCTL_GETPARAM (SIOCIWFIRSTPRIV+6)
49//#define IEEE80211_IOCTL_SETWMMPARAMS (SIOCIWFIRSTPRIV+7)
50//#define IEEE80211_IOCTL_GETWMMPARAMS (SIOCIWFIRSTPRIV+8)
51//#define IEEE80211_IOCTL_GETOPTIE (SIOCIWFIRSTPRIV+9)
52//#define IEEE80211_IOCTL_SETAUTHALG (SIOCIWFIRSTPRIV+10)
53#define IEEE80211_IOCTL_LASTONE (SIOCIWFIRSTPRIV+10)
54
55
56
57/* ====WMI Ioctls==== */
58/*
59 *
60 * Many ioctls simply provide WMI services to application code:
61 * an application makes such an ioctl call with a set of arguments
62 * that are packaged into the corresponding WMI message, and sent
63 * to the Target.
64 */
65
66#define AR6000_IOCTL_WMI_GETREV (SIOCIWFIRSTPRIV+11)
67/*
68 * arguments:
69 * ar6000_version *revision
70 */
71
72#define AR6000_IOCTL_WMI_SETPWR (SIOCIWFIRSTPRIV+12)
73/*
74 * arguments:
75 * WMI_POWER_MODE_CMD pwrModeCmd (see include/wmi.h)
76 * uses: WMI_SET_POWER_MODE_CMDID
77 */
78
79#define AR6000_IOCTL_WMI_SETSCAN (SIOCIWFIRSTPRIV+13)
80/*
81 * arguments:
82 * WMI_SCAN_PARAMS_CMD scanParams (see include/wmi.h)
83 * uses: WMI_SET_SCAN_PARAMS_CMDID
84 */
85
86#define AR6000_IOCTL_WMI_SETLISTENINT (SIOCIWFIRSTPRIV+14)
87/*
88 * arguments:
89 * UINT32 listenInterval
90 * uses: WMI_SET_LISTEN_INT_CMDID
91 */
92
93#define AR6000_IOCTL_WMI_SETBSSFILTER (SIOCIWFIRSTPRIV+15)
94/*
95 * arguments:
96 * WMI_BSS_FILTER filter (see include/wmi.h)
97 * uses: WMI_SET_BSS_FILTER_CMDID
98 */
99
100#define AR6000_IOCTL_WMI_SET_CHANNELPARAMS (SIOCIWFIRSTPRIV+16)
101/*
102 * arguments:
103 * WMI_CHANNEL_PARAMS_CMD chParams
104 * uses: WMI_SET_CHANNEL_PARAMS_CMDID
105 */
106
107#define AR6000_IOCTL_WMI_SET_PROBEDSSID (SIOCIWFIRSTPRIV+17)
108/*
109 * arguments:
110 * WMI_PROBED_SSID_CMD probedSsids (see include/wmi.h)
111 * uses: WMI_SETPROBED_SSID_CMDID
112 */
113
114#define AR6000_IOCTL_WMI_SET_PMPARAMS (SIOCIWFIRSTPRIV+18)
115/*
116 * arguments:
117 * WMI_POWER_PARAMS_CMD powerParams (see include/wmi.h)
118 * uses: WMI_SET_POWER_PARAMS_CMDID
119 */
120
121#define AR6000_IOCTL_WMI_SET_BADAP (SIOCIWFIRSTPRIV+19)
122/*
123 * arguments:
124 * WMI_ADD_BAD_AP_CMD badAPs (see include/wmi.h)
125 * uses: WMI_ADD_BAD_AP_CMDID
126 */
127
128#define AR6000_IOCTL_WMI_GET_QOS_QUEUE (SIOCIWFIRSTPRIV+20)
129/*
130 * arguments:
131 * ar6000_queuereq queueRequest (see below)
132 */
133
134#define AR6000_IOCTL_WMI_CREATE_QOS (SIOCIWFIRSTPRIV+21)
135/*
136 * arguments:
137 * WMI_CREATE_PSTREAM createPstreamCmd (see include/wmi.h)
138 * uses: WMI_CREATE_PSTREAM_CMDID
139 */
140
141#define AR6000_IOCTL_WMI_DELETE_QOS (SIOCIWFIRSTPRIV+22)
142/*
143 * arguments:
144 * WMI_DELETE_PSTREAM_CMD deletePstreamCmd (see include/wmi.h)
145 * uses: WMI_DELETE_PSTREAM_CMDID
146 */
147
148#define AR6000_IOCTL_WMI_SET_SNRTHRESHOLD (SIOCIWFIRSTPRIV+23)
149/*
150 * arguments:
151 * WMI_SNR_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
152 * uses: WMI_SNR_THRESHOLD_PARAMS_CMDID
153 */
154
155#define AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK (SIOCIWFIRSTPRIV+24)
156/*
157 * arguments:
158 * WMI_TARGET_ERROR_REPORT_BITMASK errorReportBitMask (see include/wmi.h)
159 * uses: WMI_TARGET_ERROR_REPORT_BITMASK_CMDID
160 */
161
162#define AR6000_IOCTL_WMI_GET_TARGET_STATS (SIOCIWFIRSTPRIV+25)
163/*
164 * arguments:
165 * TARGET_STATS *targetStats (see below)
166 * uses: WMI_GET_STATISTICS_CMDID
167 */
168
169#define AR6000_IOCTL_WMI_SET_ASSOC_INFO (SIOCIWFIRSTPRIV+26)
170/*
171 * arguments:
172 * WMI_SET_ASSOC_INFO_CMD setAssocInfoCmd
173 * uses: WMI_SET_ASSOC_INFO_CMDID
174 */
175
176#define AR6000_IOCTL_WMI_SET_ACCESS_PARAMS (SIOCIWFIRSTPRIV+27)
177/*
178 * arguments:
179 * WMI_SET_ACCESS_PARAMS_CMD setAccessParams (see include/wmi.h)
180 * uses: WMI_SET_ACCESS_PARAMS_CMDID
181 */
182
183#define AR6000_IOCTL_WMI_SET_BMISS_TIME (SIOCIWFIRSTPRIV+28)
184/*
185 * arguments:
186 * UINT32 beaconMissTime
187 * uses: WMI_SET_BMISS_TIME_CMDID
188 */
189
190#define AR6000_IOCTL_WMI_SET_DISC_TIMEOUT (SIOCIWFIRSTPRIV+29)
191/*
192 * arguments:
193 * WMI_DISC_TIMEOUT_CMD disconnectTimeoutCmd (see include/wmi.h)
194 * uses: WMI_SET_DISC_TIMEOUT_CMDID
195 */
196
197#define AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS (SIOCIWFIRSTPRIV+30)
198/*
199 * arguments:
200 * WMI_IBSS_PM_CAPS_CMD ibssPowerMgmtCapsCmd
201 * uses: WMI_SET_IBSS_PM_CAPS_CMDID
202 */
203
204/*
205 * There is a very small space available for driver-private
206 * wireless ioctls. In order to circumvent this limitation,
207 * we multiplex a bunch of ioctls (XIOCTLs) on top of a
208 * single AR6000_IOCTL_EXTENDED ioctl.
209 */
210#define AR6000_IOCTL_EXTENDED (SIOCIWFIRSTPRIV+31)
211
212
213/* ====BMI Extended Ioctls==== */
214
215#define AR6000_XIOCTL_BMI_DONE 1
216/*
217 * arguments:
218 * UINT32 cmd (AR6000_XIOCTL_BMI_DONE)
219 * uses: BMI_DONE
220 */
221
222#define AR6000_XIOCTL_BMI_READ_MEMORY 2
223/*
224 * arguments:
225 * union {
226 * struct {
227 * UINT32 cmd (AR6000_XIOCTL_BMI_READ_MEMORY)
228 * UINT32 address
229 * UINT32 length
230 * }
231 * char results[length]
232 * }
233 * uses: BMI_READ_MEMORY
234 */
235
236#define AR6000_XIOCTL_BMI_WRITE_MEMORY 3
237/*
238 * arguments:
239 * UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_MEMORY)
240 * UINT32 address
241 * UINT32 length
242 * char data[length]
243 * uses: BMI_WRITE_MEMORY
244 */
245
246#define AR6000_XIOCTL_BMI_EXECUTE 4
247/*
248 * arguments:
249 * UINT32 cmd (AR6000_XIOCTL_BMI_EXECUTE)
250 * UINT32 TargetAddress
251 * UINT32 parameter
252 * uses: BMI_EXECUTE
253 */
254
255#define AR6000_XIOCTL_BMI_SET_APP_START 5
256/*
257 * arguments:
258 * UINT32 cmd (AR6000_XIOCTL_BMI_SET_APP_START)
259 * UINT32 TargetAddress
260 * uses: BMI_SET_APP_START
261 */
262
263#define AR6000_XIOCTL_BMI_READ_SOC_REGISTER 6
264/*
265 * arguments:
266 * union {
267 * struct {
268 * UINT32 cmd (AR6000_XIOCTL_BMI_READ_SOC_REGISTER)
269 * UINT32 TargetAddress, 32-bit aligned
270 * }
271 * UINT32 result
272 * }
273 * uses: BMI_READ_SOC_REGISTER
274 */
275
276#define AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER 7
277/*
278 * arguments:
279 * struct {
280 * UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER)
281 * UINT32 TargetAddress, 32-bit aligned
282 * UINT32 newValue
283 * }
284 * uses: BMI_WRITE_SOC_REGISTER
285 */
286
287#define AR6000_XIOCTL_BMI_TEST 8
288/*
289 * arguments:
290 * UINT32 cmd (AR6000_XIOCTL_BMI_TEST)
291 * UINT32 address
292 * UINT32 length
293 * UINT32 count
294 */
295
296
297
298/* Historical Host-side DataSet support */
299#define AR6000_XIOCTL_UNUSED9 9
300#define AR6000_XIOCTL_UNUSED10 10
301#define AR6000_XIOCTL_UNUSED11 11
302
303/* ====Misc Extended Ioctls==== */
304
305#define AR6000_XIOCTL_FORCE_TARGET_RESET 12
306/*
307 * arguments:
308 * UINT32 cmd (AR6000_XIOCTL_FORCE_TARGET_RESET)
309 */
310
311
312#ifdef HTC_RAW_INTERFACE
313/* HTC Raw Interface Ioctls */
314#define AR6000_XIOCTL_HTC_RAW_OPEN 13
315/*
316 * arguments:
317 * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_OPEN)
318 */
319
320#define AR6000_XIOCTL_HTC_RAW_CLOSE 14
321/*
322 * arguments:
323 * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_CLOSE)
324 */
325
326#define AR6000_XIOCTL_HTC_RAW_READ 15
327/*
328 * arguments:
329 * union {
330 * struct {
331 * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_READ)
332 * UINT32 mailboxID
333 * UINT32 length
334 * }
335 * results[length]
336 * }
337 */
338
339#define AR6000_XIOCTL_HTC_RAW_WRITE 16
340/*
341 * arguments:
342 * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_WRITE)
343 * UINT32 mailboxID
344 * UINT32 length
345 * char buffer[length]
346 */
347#endif /* HTC_RAW_INTERFACE */
348
349#define AR6000_XIOCTL_CHECK_TARGET_READY 17
350/*
351 * arguments:
352 * UINT32 cmd (AR6000_XIOCTL_CHECK_TARGET_READY)
353 */
354
355
356
357/* ====GPIO (General Purpose I/O) Extended Ioctls==== */
358
359#define AR6000_XIOCTL_GPIO_OUTPUT_SET 18
360/*
361 * arguments:
362 * UINT32 cmd (AR6000_XIOCTL_GPIO_OUTPUT_SET)
363 * ar6000_gpio_output_set_cmd_s (see below)
364 * uses: WMIX_GPIO_OUTPUT_SET_CMDID
365 */
366
367#define AR6000_XIOCTL_GPIO_INPUT_GET 19
368/*
369 * arguments:
370 * UINT32 cmd (AR6000_XIOCTL_GPIO_INPUT_GET)
371 * uses: WMIX_GPIO_INPUT_GET_CMDID
372 */
373
374#define AR6000_XIOCTL_GPIO_REGISTER_SET 20
375/*
376 * arguments:
377 * UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_SET)
378 * ar6000_gpio_register_cmd_s (see below)
379 * uses: WMIX_GPIO_REGISTER_SET_CMDID
380 */
381
382#define AR6000_XIOCTL_GPIO_REGISTER_GET 21
383/*
384 * arguments:
385 * UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_GET)
386 * ar6000_gpio_register_cmd_s (see below)
387 * uses: WMIX_GPIO_REGISTER_GET_CMDID
388 */
389
390#define AR6000_XIOCTL_GPIO_INTR_ACK 22
391/*
392 * arguments:
393 * UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_ACK)
394 * ar6000_cpio_intr_ack_cmd_s (see below)
395 * uses: WMIX_GPIO_INTR_ACK_CMDID
396 */
397
398#define AR6000_XIOCTL_GPIO_INTR_WAIT 23
399/*
400 * arguments:
401 * UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_WAIT)
402 */
403
404
405
406/* ====more wireless commands==== */
407
408#define AR6000_XIOCTL_SET_ADHOC_BSSID 24
409/*
410 * arguments:
411 * UINT32 cmd (AR6000_XIOCTL_SET_ADHOC_BSSID)
412 * WMI_SET_ADHOC_BSSID_CMD setAdHocBssidCmd (see include/wmi.h)
413 */
414
415#define AR6000_XIOCTL_SET_OPT_MODE 25
416/*
417 * arguments:
418 * UINT32 cmd (AR6000_XIOCTL_SET_OPT_MODE)
419 * WMI_SET_OPT_MODE_CMD setOptModeCmd (see include/wmi.h)
420 * uses: WMI_SET_OPT_MODE_CMDID
421 */
422
423#define AR6000_XIOCTL_OPT_SEND_FRAME 26
424/*
425 * arguments:
426 * UINT32 cmd (AR6000_XIOCTL_OPT_SEND_FRAME)
427 * WMI_OPT_TX_FRAME_CMD optTxFrameCmd (see include/wmi.h)
428 * uses: WMI_OPT_TX_FRAME_CMDID
429 */
430
431#define AR6000_XIOCTL_SET_BEACON_INTVAL 27
432/*
433 * arguments:
434 * UINT32 cmd (AR6000_XIOCTL_SET_BEACON_INTVAL)
435 * WMI_BEACON_INT_CMD beaconIntCmd (see include/wmi.h)
436 * uses: WMI_SET_BEACON_INT_CMDID
437 */
438
439
440#define IEEE80211_IOCTL_SETAUTHALG 28
441
442
443#define AR6000_XIOCTL_SET_VOICE_PKT_SIZE 29
444/*
445 * arguments:
446 * UINT32 cmd (AR6000_XIOCTL_SET_VOICE_PKT_SIZE)
447 * WMI_SET_VOICE_PKT_SIZE_CMD setVoicePktSizeCmd (see include/wmi.h)
448 * uses: WMI_SET_VOICE_PKT_SIZE_CMDID
449 */
450
451
452#define AR6000_XIOCTL_SET_MAX_SP 30
453/*
454 * arguments:
455 * UINT32 cmd (AR6000_XIOCTL_SET_MAX_SP)
456 * WMI_SET_MAX_SP_LEN_CMD maxSPLen(see include/wmi.h)
457 * uses: WMI_SET_MAX_SP_LEN_CMDID
458 */
459
460#define AR6000_XIOCTL_WMI_GET_ROAM_TBL 31
461
462#define AR6000_XIOCTL_WMI_SET_ROAM_CTRL 32
463
464#define AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS 33
465
466
467/*
468 * arguments:
469 * UINT32 cmd (AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS)
470 * WMI_SET_POWERSAVE_TIMERS_CMD powerSaveTimers(see include/wmi.h)
471 * WMI_SET_POWERSAVE_TIMERS_CMDID
472 */
473
474#define AR6000_XIOCTRL_WMI_GET_POWER_MODE 34
475/*
476 * arguments:
477 * UINT32 cmd (AR6000_XIOCTRL_WMI_GET_POWER_MODE)
478 */
479
480#define AR6000_XIOCTRL_WMI_SET_WLAN_STATE 35
481typedef enum {
482 WLAN_DISABLED,
483 WLAN_ENABLED
484} AR6000_WLAN_STATE;
485/*
486 * arguments:
487 * enable/disable
488 */
489
490#define AR6000_XIOCTL_WMI_GET_ROAM_DATA 36
491
492#define AR6000_XIOCTL_WMI_SETRETRYLIMITS 37
493/*
494 * arguments:
495 * WMI_SET_RETRY_LIMITS_CMD ibssSetRetryLimitsCmd
496 * uses: WMI_SET_RETRY_LIMITS_CMDID
497 */
498
499#ifdef CONFIG_HOST_TCMD_SUPPORT
500/* ====extended commands for radio test ==== */
501
502#define AR6000_XIOCTL_TCMD_CONT_TX 38
503/*
504 * arguments:
505 * UINT32 cmd (AR6000_XIOCTL_TCMD_CONT_TX)
506 * WMI_TCMD_CONT_TX_CMD contTxCmd (see include/wmi.h)
507 * uses: WMI_TCMD_CONT_TX_CMDID
508 */
509
510#define AR6000_XIOCTL_TCMD_CONT_RX 39
511/*
512 * arguments:
513 * UINT32 cmd (AR6000_XIOCTL_TCMD_CONT_RX)
514 * WMI_TCMD_CONT_RX_CMD rxCmd (see include/wmi.h)
515 * uses: WMI_TCMD_CONT_RX_CMDID
516 */
517
518#define AR6000_XIOCTL_TCMD_PM 40
519/*
520 * arguments:
521 * UINT32 cmd (AR6000_XIOCTL_TCMD_PM)
522 * WMI_TCMD_PM_CMD pmCmd (see include/wmi.h)
523 * uses: WMI_TCMD_PM_CMDID
524 */
525
526#endif /* CONFIG_HOST_TCMD_SUPPORT */
527
528#define AR6000_XIOCTL_WMI_STARTSCAN 41
529/*
530 * arguments:
531 * UINT32 cmd (AR6000_XIOCTL_WMI_STARTSCAN)
532 * UINT8 scanType
533 * UINT8 scanConnected
534 * u32 forceFgScan
535 * uses: WMI_START_SCAN_CMDID
536 */
537
538#define AR6000_XIOCTL_WMI_SETFIXRATES 42
539
540#define AR6000_XIOCTL_WMI_GETFIXRATES 43
541
542
543#define AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD 44
544/*
545 * arguments:
546 * WMI_RSSI_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
547 * uses: WMI_RSSI_THRESHOLD_PARAMS_CMDID
548 */
549
550#define AR6000_XIOCTL_WMI_CLR_RSSISNR 45
551/*
552 * arguments:
553 * WMI_CLR_RSSISNR_CMD thresholdParams (see include/wmi.h)
554 * uses: WMI_CLR_RSSISNR_CMDID
555 */
556
557#define AR6000_XIOCTL_WMI_SET_LQTHRESHOLD 46
558/*
559 * arguments:
560 * WMI_LQ_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
561 * uses: WMI_LQ_THRESHOLD_PARAMS_CMDID
562 */
563
564#define AR6000_XIOCTL_WMI_SET_RTS 47
565/*
566 * arguments:
567 * WMI_SET_RTS_MODE_CMD (see include/wmi.h)
568 * uses: WMI_SET_RTS_MODE_CMDID
569 */
570
571#define AR6000_XIOCTL_WMI_SET_LPREAMBLE 48
572
573#define AR6000_XIOCTL_WMI_SET_AUTHMODE 49
574/*
575 * arguments:
576 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_AUTHMODE)
577 * UINT8 mode
578 * uses: WMI_SET_RECONNECT_AUTH_MODE_CMDID
579 */
580
581#define AR6000_XIOCTL_WMI_SET_REASSOCMODE 50
582
583/*
584 * arguments:
585 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_WMM)
586 * UINT8 mode
587 * uses: WMI_SET_WMM_CMDID
588 */
589#define AR6000_XIOCTL_WMI_SET_WMM 51
590
591/*
592 * arguments:
593 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS)
594 * UINT32 frequency
595 * UINT8 threshold
596 */
597#define AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS 52
598
599/*
600 * arguments:
601 * UINT32 cmd (AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP)
602 * UINT32 cookie
603 */
604#define AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP 53
605
606/*
607 * arguments:
608 * UINT32 cmd (AR6000_XIOCTL_WMI_GET_RD)
609 * UINT32 regDomain
610 */
611#define AR6000_XIOCTL_WMI_GET_RD 54
612
613#define AR6000_XIOCTL_DIAG_READ 55
614
615#define AR6000_XIOCTL_DIAG_WRITE 56
616
617/*
618 * arguments cmd (AR6000_XIOCTL_SET_TXOP)
619 * WMI_TXOP_CFG txopEnable
620 */
621#define AR6000_XIOCTL_WMI_SET_TXOP 57
622
623/*
624 * arguments:
625 * UINT32 cmd (AR6000_XIOCTL_USER_SETKEYS)
626 * UINT32 keyOpCtrl
627 * uses struct ar6000_user_setkeys_info
628 */
629#define AR6000_XIOCTL_USER_SETKEYS 58
630
631#define AR6000_XIOCTL_WMI_SET_KEEPALIVE 59
632/*
633 * arguments:
634 * UINT8 cmd (AR6000_XIOCTL_WMI_SET_KEEPALIVE)
635 * UINT8 keepaliveInterval
636 * uses: WMI_SET_KEEPALIVE_CMDID
637 */
638
639#define AR6000_XIOCTL_WMI_GET_KEEPALIVE 60
640/*
641 * arguments:
642 * UINT8 cmd (AR6000_XIOCTL_WMI_GET_KEEPALIVE)
643 * UINT8 keepaliveInterval
644 * u32 configured
645 * uses: WMI_GET_KEEPALIVE_CMDID
646 */
647
648/* ====ROM Patching Extended Ioctls==== */
649
650#define AR6000_XIOCTL_BMI_ROMPATCH_INSTALL 61
651/*
652 * arguments:
653 * union {
654 * struct {
655 * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_INSTALL)
656 * UINT32 ROM Address
657 * UINT32 RAM Address
658 * UINT32 number of bytes
659 * UINT32 activate? (0 or 1)
660 * }
661 * u32 resulting rompatch ID
662 * }
663 * uses: BMI_ROMPATCH_INSTALL
664 */
665
666#define AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL 62
667/*
668 * arguments:
669 * struct {
670 * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL)
671 * UINT32 rompatch ID
672 * }
673 * uses: BMI_ROMPATCH_UNINSTALL
674 */
675
676#define AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE 63
677/*
678 * arguments:
679 * struct {
680 * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE)
681 * UINT32 rompatch count
682 * UINT32 rompatch IDs[rompatch count]
683 * }
684 * uses: BMI_ROMPATCH_ACTIVATE
685 */
686
687#define AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE 64
688/*
689 * arguments:
690 * struct {
691 * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE)
692 * UINT32 rompatch count
693 * UINT32 rompatch IDs[rompatch count]
694 * }
695 * uses: BMI_ROMPATCH_DEACTIVATE
696 */
697
698#define AR6000_XIOCTL_WMI_SET_APPIE 65
699/*
700 * arguments:
701 * struct {
702 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_APPIE)
703 * UINT32 app_frmtype;
704 * UINT32 app_buflen;
705 * UINT8 app_buf[];
706 * }
707 */
708#define AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER 66
709/*
710 * arguments:
711 * u32 filter_type;
712 */
713
714#define AR6000_XIOCTL_DBGLOG_CFG_MODULE 67
715
716#define AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS 68
717
718#define AR6000_XIOCTL_WMI_SET_WSC_STATUS 70
719/*
720 * arguments:
721 * u32 wsc_status;
722 * (WSC_REG_INACTIVE or WSC_REG_ACTIVE)
723 */
724
725/*
726 * arguments:
727 * struct {
728 * u8 streamType;
729 * u8 status;
730 * }
731 * uses: WMI_SET_BT_STATUS_CMDID
732 */
733#define AR6000_XIOCTL_WMI_SET_BT_STATUS 71
734
735/*
736 * arguments:
737 * struct {
738 * u8 paramType;
739 * union {
740 * u8 noSCOPkts;
741 * BT_PARAMS_A2DP a2dpParams;
742 * BT_COEX_REGS regs;
743 * };
744 * }
745 * uses: WMI_SET_BT_PARAM_CMDID
746 */
747#define AR6000_XIOCTL_WMI_SET_BT_PARAMS 72
748
749#define AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE 73
750#define AR6000_XIOCTL_WMI_SET_WOW_MODE 74
751#define AR6000_XIOCTL_WMI_GET_WOW_LIST 75
752#define AR6000_XIOCTL_WMI_ADD_WOW_PATTERN 76
753#define AR6000_XIOCTL_WMI_DEL_WOW_PATTERN 77
754
755
756
757#define AR6000_XIOCTL_TARGET_INFO 78
758/*
759 * arguments:
760 * UINT32 cmd (AR6000_XIOCTL_TARGET_INFO)
761 * u32 TargetVersion (returned)
762 * u32 TargetType (returned)
763 * (See also bmi_msg.h target_ver and target_type)
764 */
765
766#define AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE 79
767/*
768 * arguments:
769 * none
770 */
771
772#define AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE 80
773/*
774 * This ioctl is used to emulate traffic activity
775 * timeouts. Activity/inactivity will trigger the driver
776 * to re-balance credits.
777 *
778 * arguments:
779 * ar6000_traffic_activity_change
780 */
781
782#define AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS 81
783/*
784 * This ioctl is used to set the connect control flags
785 *
786 * arguments:
787 * u32 connectCtrlFlags
788 */
789
790#define AR6000_XIOCTL_WMI_SET_AKMP_PARAMS 82
791/*
792 * This IOCTL sets any Authentication,Key Management and Protection
793 * related parameters. This is used along with the information set in
794 * Connect Command.
795 * Currently this enables Multiple PMKIDs to an AP.
796 *
797 * arguments:
798 * struct {
799 * u32 akmpInfo;
800 * }
801 * uses: WMI_SET_AKMP_PARAMS_CMD
802 */
803
804#define AR6000_XIOCTL_WMI_GET_PMKID_LIST 83
805
806#define AR6000_XIOCTL_WMI_SET_PMKID_LIST 84
807/*
808 * This IOCTL is used to set a list of PMKIDs. This list of
809 * PMKIDs is used in the [Re]AssocReq Frame. This list is used
810 * only if the MultiPMKID option is enabled via the
811 * AR6000_XIOCTL_WMI_SET_AKMP_PARAMS IOCTL.
812 *
813 * arguments:
814 * struct {
815 * u32 numPMKID;
816 * WMI_PMKID pmkidList[WMI_MAX_PMKID_CACHE];
817 * }
818 * uses: WMI_SET_PMKIDLIST_CMD
819 */
820
821#define AR6000_XIOCTL_WMI_SET_PARAMS 85
822#define AR6000_XIOCTL_WMI_SET_MCAST_FILTER 86
823#define AR6000_XIOCTL_WMI_DEL_MCAST_FILTER 87
824
825
826/* Historical DSETPATCH support for INI patches */
827#define AR6000_XIOCTL_UNUSED90 90
828
829
830/* Support LZ-compressed firmware download */
831#define AR6000_XIOCTL_BMI_LZ_STREAM_START 91
832/*
833 * arguments:
834 * UINT32 cmd (AR6000_XIOCTL_BMI_LZ_STREAM_START)
835 * UINT32 address
836 * uses: BMI_LZ_STREAM_START
837 */
838
839#define AR6000_XIOCTL_BMI_LZ_DATA 92
840/*
841 * arguments:
842 * UINT32 cmd (AR6000_XIOCTL_BMI_LZ_DATA)
843 * UINT32 length
844 * char data[length]
845 * uses: BMI_LZ_DATA
846 */
847
848#define AR6000_XIOCTL_PROF_CFG 93
849/*
850 * arguments:
851 * u32 period
852 * u32 nbins
853 */
854
855#define AR6000_XIOCTL_PROF_ADDR_SET 94
856/*
857 * arguments:
858 * u32 Target address
859 */
860
861#define AR6000_XIOCTL_PROF_START 95
862
863#define AR6000_XIOCTL_PROF_STOP 96
864
865#define AR6000_XIOCTL_PROF_COUNT_GET 97
866
867#define AR6000_XIOCTL_WMI_ABORT_SCAN 98
868
869/*
870 * AP mode
871 */
872#define AR6000_XIOCTL_AP_GET_STA_LIST 99
873
874#define AR6000_XIOCTL_AP_HIDDEN_SSID 100
875
876#define AR6000_XIOCTL_AP_SET_NUM_STA 101
877
878#define AR6000_XIOCTL_AP_SET_ACL_MAC 102
879
880#define AR6000_XIOCTL_AP_GET_ACL_LIST 103
881
882#define AR6000_XIOCTL_AP_COMMIT_CONFIG 104
883
884#define IEEE80211_IOCTL_GETWPAIE 105
885
886#define AR6000_XIOCTL_AP_CONN_INACT_TIME 106
887
888#define AR6000_XIOCTL_AP_PROT_SCAN_TIME 107
889
890#define AR6000_XIOCTL_AP_SET_COUNTRY 108
891
892#define AR6000_XIOCTL_AP_SET_DTIM 109
893
894
895
896
897#define AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT 110
898
899#define AR6000_XIOCTL_SET_IP 111
900
901#define AR6000_XIOCTL_AP_SET_ACL_POLICY 112
902
903#define AR6000_XIOCTL_AP_INTRA_BSS_COMM 113
904
905#define AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO 114
906
907#define AR6000_XIOCTL_MODULE_DEBUG_SET_MASK 115
908
909#define AR6000_XIOCTL_MODULE_DEBUG_GET_MASK 116
910
911#define AR6000_XIOCTL_DUMP_RCV_AGGR_STATS 117
912
913#define AR6000_XIOCTL_SET_HT_CAP 118
914
915#define AR6000_XIOCTL_SET_HT_OP 119
916
917#define AR6000_XIOCTL_AP_GET_STAT 120
918
919#define AR6000_XIOCTL_SET_TX_SELECT_RATES 121
920
921#define AR6000_XIOCTL_SETUP_AGGR 122
922
923#define AR6000_XIOCTL_ALLOW_AGGR 123
924
925#define AR6000_XIOCTL_AP_GET_HIDDEN_SSID 124
926
927#define AR6000_XIOCTL_AP_GET_COUNTRY 125
928
929#define AR6000_XIOCTL_AP_GET_WMODE 126
930
931#define AR6000_XIOCTL_AP_GET_DTIM 127
932
933#define AR6000_XIOCTL_AP_GET_BINTVL 128
934
935#define AR6000_XIOCTL_AP_GET_RTS 129
936
937#define AR6000_XIOCTL_DELE_AGGR 130
938
939#define AR6000_XIOCTL_FETCH_TARGET_REGS 131
940
941#define AR6000_XIOCTL_HCI_CMD 132
942
943#define AR6000_XIOCTL_ACL_DATA 133 /* used to be used for PAL */
944
945#define AR6000_XIOCTL_WLAN_CONN_PRECEDENCE 134
946
947#define AR6000_XIOCTL_AP_SET_11BG_RATESET 135
948
949/*
950 * arguments:
951 * WMI_AP_PS_CMD apPsCmd
952 * uses: WMI_AP_PS_CMDID
953 */
954
955#define AR6000_XIOCTL_WMI_SET_AP_PS 136
956
957#define AR6000_XIOCTL_WMI_MCAST_FILTER 137
958
959#define AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT 138
960
961#define AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV 139
962
963#define AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG 140
964
965#define AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG 141
966
967#define AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG 142
968
969#define AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG 143
970
971#define AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG 144
972
973#define AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS 145
974
975#define AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG 146
976
977#define AR6000_XIOCTL_WMI_GET_BTCOEX_STATS 147
978/*
979 * arguments:
980 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_QOS_SUPP)
981 * UINT8 mode
982 * uses: WMI_SET_QOS_SUPP_CMDID
983 */
984#define AR6000_XIOCTL_WMI_SET_QOS_SUPP 148
985
986#define AR6000_XIOCTL_GET_WLAN_SLEEP_STATE 149
987
988#define AR6000_XIOCTL_SET_BT_HW_POWER_STATE 150
989
990#define AR6000_XIOCTL_GET_BT_HW_POWER_STATE 151
991
992#define AR6000_XIOCTL_ADD_AP_INTERFACE 152
993
994#define AR6000_XIOCTL_REMOVE_AP_INTERFACE 153
995
996#define AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM 154
997
998#define AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES 161
999
1000/* used by AR6000_IOCTL_WMI_GETREV */
1001struct ar6000_version {
1002 u32 host_ver;
1003 u32 target_ver;
1004 u32 wlan_ver;
1005 u32 abi_ver;
1006};
1007
1008/* used by AR6000_IOCTL_WMI_GET_QOS_QUEUE */
1009struct ar6000_queuereq {
1010 u8 trafficClass;
1011 u16 activeTsids;
1012};
1013
1014/* used by AR6000_IOCTL_WMI_GET_TARGET_STATS */
1015typedef struct targetStats_t {
1016 u64 tx_packets;
1017 u64 tx_bytes;
1018 u64 tx_unicast_pkts;
1019 u64 tx_unicast_bytes;
1020 u64 tx_multicast_pkts;
1021 u64 tx_multicast_bytes;
1022 u64 tx_broadcast_pkts;
1023 u64 tx_broadcast_bytes;
1024 u64 tx_rts_success_cnt;
1025 u64 tx_packet_per_ac[4];
1026
1027 u64 tx_errors;
1028 u64 tx_failed_cnt;
1029 u64 tx_retry_cnt;
1030 u64 tx_mult_retry_cnt;
1031 u64 tx_rts_fail_cnt;
1032
1033 u64 rx_packets;
1034 u64 rx_bytes;
1035 u64 rx_unicast_pkts;
1036 u64 rx_unicast_bytes;
1037 u64 rx_multicast_pkts;
1038 u64 rx_multicast_bytes;
1039 u64 rx_broadcast_pkts;
1040 u64 rx_broadcast_bytes;
1041 u64 rx_fragment_pkt;
1042
1043 u64 rx_errors;
1044 u64 rx_crcerr;
1045 u64 rx_key_cache_miss;
1046 u64 rx_decrypt_err;
1047 u64 rx_duplicate_frames;
1048
1049 u64 tkip_local_mic_failure;
1050 u64 tkip_counter_measures_invoked;
1051 u64 tkip_replays;
1052 u64 tkip_format_errors;
1053 u64 ccmp_format_errors;
1054 u64 ccmp_replays;
1055
1056 u64 power_save_failure_cnt;
1057
1058 u64 cs_bmiss_cnt;
1059 u64 cs_lowRssi_cnt;
1060 u64 cs_connect_cnt;
1061 u64 cs_disconnect_cnt;
1062
1063 s32 tx_unicast_rate;
1064 s32 rx_unicast_rate;
1065
1066 u32 lq_val;
1067
1068 u32 wow_num_pkts_dropped;
1069 u16 wow_num_events_discarded;
1070
1071 s16 noise_floor_calibation;
1072 s16 cs_rssi;
1073 s16 cs_aveBeacon_rssi;
1074 u8 cs_aveBeacon_snr;
1075 u8 cs_lastRoam_msec;
1076 u8 cs_snr;
1077
1078 u8 wow_num_host_pkt_wakeups;
1079 u8 wow_num_host_event_wakeups;
1080
1081 u32 arp_received;
1082 u32 arp_matched;
1083 u32 arp_replied;
1084}TARGET_STATS;
1085
1086typedef struct targetStats_cmd_t {
1087 TARGET_STATS targetStats;
1088 int clearStats;
1089} TARGET_STATS_CMD;
1090
1091/* used by AR6000_XIOCTL_USER_SETKEYS */
1092
1093/*
1094 * Setting this bit to 1 doesnot initialize the RSC on the firmware
1095 */
1096#define AR6000_XIOCTL_USER_SETKEYS_RSC_CTRL 1
1097#define AR6000_USER_SETKEYS_RSC_UNCHANGED 0x00000002
1098
1099struct ar6000_user_setkeys_info {
1100 u32 keyOpCtrl; /* Bit Map of Key Mgmt Ctrl Flags */
1101}; /* XXX: unused !? */
1102
1103/* used by AR6000_XIOCTL_GPIO_OUTPUT_SET */
1104struct ar6000_gpio_output_set_cmd_s {
1105 u32 set_mask;
1106 u32 clear_mask;
1107 u32 enable_mask;
1108 u32 disable_mask;
1109};
1110
1111/*
1112 * used by AR6000_XIOCTL_GPIO_REGISTER_GET and AR6000_XIOCTL_GPIO_REGISTER_SET
1113 */
1114struct ar6000_gpio_register_cmd_s {
1115 u32 gpioreg_id;
1116 u32 value;
1117};
1118
1119/* used by AR6000_XIOCTL_GPIO_INTR_ACK */
1120struct ar6000_gpio_intr_ack_cmd_s {
1121 u32 ack_mask;
1122};
1123
1124/* used by AR6000_XIOCTL_GPIO_INTR_WAIT */
1125struct ar6000_gpio_intr_wait_cmd_s {
1126 u32 intr_mask;
1127 u32 input_values;
1128};
1129
1130/* used by the AR6000_XIOCTL_DBGLOG_CFG_MODULE */
1131typedef struct ar6000_dbglog_module_config_s {
1132 u32 valid;
1133 u16 mmask;
1134 u16 tsr;
1135 u32 rep;
1136 u16 size;
1137} DBGLOG_MODULE_CONFIG;
1138
1139typedef struct user_rssi_thold_t {
1140 s16 tag;
1141 s16 rssi;
1142} USER_RSSI_THOLD;
1143
1144typedef struct user_rssi_params_t {
1145 u8 weight;
1146 u32 pollTime;
1147 USER_RSSI_THOLD tholds[12];
1148} USER_RSSI_PARAMS;
1149
1150typedef struct ar6000_get_btcoex_config_cmd_t{
1151 u32 btProfileType;
1152 u32 linkId;
1153 }AR6000_GET_BTCOEX_CONFIG_CMD;
1154
1155typedef struct ar6000_btcoex_config_t {
1156 AR6000_GET_BTCOEX_CONFIG_CMD configCmd;
1157 u32 *configEvent;
1158} AR6000_BTCOEX_CONFIG;
1159
1160typedef struct ar6000_btcoex_stats_t {
1161 u32 *statsEvent;
1162 }AR6000_BTCOEX_STATS;
1163/*
1164 * Host driver may have some config parameters. Typically, these
1165 * config params are one time config parameters. These could
1166 * correspond to any of the underlying modules. Host driver exposes
1167 * an api for the underlying modules to get this config.
1168 */
1169#define AR6000_DRIVER_CFG_BASE 0x8000
1170
1171/* Should driver perform wlan node caching? */
1172#define AR6000_DRIVER_CFG_GET_WLANNODECACHING 0x8001
1173/*Should we log raw WMI msgs */
1174#define AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS 0x8002
1175
1176/* used by AR6000_XIOCTL_DIAG_READ & AR6000_XIOCTL_DIAG_WRITE */
1177struct ar6000_diag_window_cmd_s {
1178 unsigned int addr;
1179 unsigned int value;
1180};
1181
1182
1183struct ar6000_traffic_activity_change {
1184 u32 StreamID; /* stream ID to indicate activity change */
1185 u32 Active; /* active (1) or inactive (0) */
1186};
1187
1188/* Used with AR6000_XIOCTL_PROF_COUNT_GET */
1189struct prof_count_s {
1190 u32 addr; /* bin start address */
1191 u32 count; /* hit count */
1192};
1193
1194
1195/* used by AR6000_XIOCTL_MODULE_DEBUG_SET_MASK */
1196/* AR6000_XIOCTL_MODULE_DEBUG_GET_MASK */
1197/* AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO */
1198struct drv_debug_module_s {
1199 char modulename[128]; /* name of module */
1200 u32 mask; /* new mask to set .. or .. current mask */
1201};
1202
1203
1204/* All HCI related rx events are sent up to the host app
1205 * via a wmi event id. It can contain ACL data or HCI event,
1206 * based on which it will be de-multiplexed.
1207 */
1208typedef enum {
1209 PAL_HCI_EVENT = 0,
1210 PAL_HCI_RX_DATA,
1211} WMI_PAL_EVENT_INFO;
1212
1213
1214#ifdef __cplusplus
1215}
1216#endif
1217#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/cfg80211.h b/drivers/staging/ath6kl/os/linux/include/cfg80211.h
new file mode 100644
index 00000000000..d5253207b19
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/cfg80211.h
@@ -0,0 +1,61 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _AR6K_CFG80211_H_
25#define _AR6K_CFG80211_H_
26
27struct wireless_dev *ar6k_cfg80211_init(struct device *dev);
28void ar6k_cfg80211_deinit(struct ar6_softc *ar);
29
30void ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status);
31
32void ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel,
33 u8 *bssid, u16 listenInterval,
34 u16 beaconInterval,NETWORK_TYPE networkType,
35 u8 beaconIeLen, u8 assocReqLen,
36 u8 assocRespLen, u8 *assocInfo);
37
38void ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason,
39 u8 *bssid, u8 assocRespLen,
40 u8 *assocInfo, u16 protocolReasonStatus);
41
42void ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast);
43
44#ifdef CONFIG_NL80211_TESTMODE
45void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf,
46 int buf_len);
47#else
48static inline void ar6000_testmode_rx_report_event(struct ar6_softc *ar,
49 void *buf, int buf_len)
50{
51}
52#endif
53
54
55#endif /* _AR6K_CFG80211_H_ */
56
57
58
59
60
61
diff --git a/drivers/staging/ath6kl/os/linux/include/config_linux.h b/drivers/staging/ath6kl/os/linux/include/config_linux.h
new file mode 100644
index 00000000000..dbbe1a00b92
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/config_linux.h
@@ -0,0 +1,51 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _CONFIG_LINUX_H_
25#define _CONFIG_LINUX_H_
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/*
32 * Host side Test Command support
33 */
34#define CONFIG_HOST_TCMD_SUPPORT
35
36#define USE_4BYTE_REGISTER_ACCESS
37
38/* Host-side support for Target-side profiling */
39#undef CONFIG_TARGET_PROFILE_SUPPORT
40
41/* IP/TCP checksum offload */
42/* Checksum offload is currently not supported for 64 bit platforms */
43#ifndef __LP64__
44#define CONFIG_CHECKSUM_OFFLOAD
45#endif /* __LP64__ */
46
47#ifdef __cplusplus
48}
49#endif
50
51#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/debug_linux.h b/drivers/staging/ath6kl/os/linux/include/debug_linux.h
new file mode 100644
index 00000000000..b8dba52badc
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/debug_linux.h
@@ -0,0 +1,50 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _DEBUG_LINUX_H_
25#define _DEBUG_LINUX_H_
26
27 /* macro to remove parens */
28#define ATH_PRINTX_ARG(arg...) arg
29
30#ifdef DEBUG
31 /* NOTE: the AR_DEBUG_PRINTF macro is defined here to handle special handling of variable arg macros
32 * which may be compiler dependent. */
33#define AR_DEBUG_PRINTF(mask, args) do { \
34 if (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (mask)) { \
35 A_LOGGER(mask, ATH_MODULE_NAME, ATH_PRINTX_ARG args); \
36 } \
37} while (0)
38#else
39 /* on non-debug builds, keep in error and warning messages in the driver, all other
40 * message tracing will get compiled out */
41#define AR_DEBUG_PRINTF(mask, args) \
42 if ((mask) & (ATH_DEBUG_ERR | ATH_DEBUG_WARN)) { A_PRINTF(ATH_PRINTX_ARG args); }
43
44#endif
45
46 /* compile specific macro to get the function name string */
47#define _A_FUNCNAME_ __func__
48
49
50#endif /* _DEBUG_LINUX_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h
new file mode 100644
index 00000000000..74f98618334
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h
@@ -0,0 +1,76 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// HCI bridge implementation
21//
22// Author(s): ="Atheros"
23//==============================================================================
24
25#include "hci_transport_api.h"
26#include "common_drv.h"
27
28extern HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo);
29extern void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans);
30extern int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue);
31extern int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous);
32extern void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans);
33extern int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans);
34extern int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
35extern int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans,
36 struct htc_packet *pPacket,
37 int MaxPollMS);
38extern int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud);
39extern int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
40
41
42#define HCI_TransportAttach(HTCHandle, pInfo) \
43 _HCI_TransportAttach((HTCHandle), (pInfo))
44#define HCI_TransportDetach(HciTrans) \
45 _HCI_TransportDetach(HciTrans)
46#define HCI_TransportAddReceivePkts(HciTrans, pQueue) \
47 _HCI_TransportAddReceivePkts((HciTrans), (pQueue))
48#define HCI_TransportSendPkt(HciTrans, pPacket, Synchronous) \
49 _HCI_TransportSendPkt((HciTrans), (pPacket), (Synchronous))
50#define HCI_TransportStop(HciTrans) \
51 _HCI_TransportStop((HciTrans))
52#define HCI_TransportStart(HciTrans) \
53 _HCI_TransportStart((HciTrans))
54#define HCI_TransportEnableDisableAsyncRecv(HciTrans, Enable) \
55 _HCI_TransportEnableDisableAsyncRecv((HciTrans), (Enable))
56#define HCI_TransportRecvHCIEventSync(HciTrans, pPacket, MaxPollMS) \
57 _HCI_TransportRecvHCIEventSync((HciTrans), (pPacket), (MaxPollMS))
58#define HCI_TransportSetBaudRate(HciTrans, Baud) \
59 _HCI_TransportSetBaudRate((HciTrans), (Baud))
60#define HCI_TransportEnablePowerMgmt(HciTrans, Enable) \
61 _HCI_TransportEnablePowerMgmt((HciTrans), (Enable))
62
63
64extern int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallbacks);
65
66extern int ar6000_get_hif_dev(struct hif_device *device, void *config);
67
68extern int ar6000_set_uart_config(struct hif_device *hifDevice, u32 scale, u32 step);
69
70/* get core clock register settings
71 * data: 0 - 40/44MHz
72 * 1 - 80/88MHz
73 * where (5G band/2.4G band)
74 * assume 2.4G band for now
75 */
76extern int ar6000_get_core_clock_config(struct hif_device *hifDevice, u32 *data);
diff --git a/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h b/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h
new file mode 100644
index 00000000000..e6e96de3fc6
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h
@@ -0,0 +1,177 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _IEEE80211_IOCTL_H_
25#define _IEEE80211_IOCTL_H_
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/*
32 * Extracted from the MADWIFI net80211/ieee80211_ioctl.h
33 */
34
35/*
36 * WPA/RSN get/set key request. Specify the key/cipher
37 * type and whether the key is to be used for sending and/or
38 * receiving. The key index should be set only when working
39 * with global keys (use IEEE80211_KEYIX_NONE for ``no index'').
40 * Otherwise a unicast/pairwise key is specified by the bssid
41 * (on a station) or mac address (on an ap). They key length
42 * must include any MIC key data; otherwise it should be no
43 more than IEEE80211_KEYBUF_SIZE.
44 */
45struct ieee80211req_key {
46 u_int8_t ik_type; /* key/cipher type */
47 u_int8_t ik_pad;
48 u_int16_t ik_keyix; /* key index */
49 u_int8_t ik_keylen; /* key length in bytes */
50 u_int8_t ik_flags;
51#define IEEE80211_KEY_XMIT 0x01
52#define IEEE80211_KEY_RECV 0x02
53#define IEEE80211_KEY_DEFAULT 0x80 /* default xmit key */
54 u_int8_t ik_macaddr[IEEE80211_ADDR_LEN];
55 u_int64_t ik_keyrsc; /* key receive sequence counter */
56 u_int64_t ik_keytsc; /* key transmit sequence counter */
57 u_int8_t ik_keydata[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE];
58};
59/*
60 * Delete a key either by index or address. Set the index
61 * to IEEE80211_KEYIX_NONE when deleting a unicast key.
62 */
63struct ieee80211req_del_key {
64 u_int8_t idk_keyix; /* key index */
65 u_int8_t idk_macaddr[IEEE80211_ADDR_LEN];
66};
67/*
68 * MLME state manipulation request. IEEE80211_MLME_ASSOC
69 * only makes sense when operating as a station. The other
70 * requests can be used when operating as a station or an
71 * ap (to effect a station).
72 */
73struct ieee80211req_mlme {
74 u_int8_t im_op; /* operation to perform */
75#define IEEE80211_MLME_ASSOC 1 /* associate station */
76#define IEEE80211_MLME_DISASSOC 2 /* disassociate station */
77#define IEEE80211_MLME_DEAUTH 3 /* deauthenticate station */
78#define IEEE80211_MLME_AUTHORIZE 4 /* authorize station */
79#define IEEE80211_MLME_UNAUTHORIZE 5 /* unauthorize station */
80 u_int16_t im_reason; /* 802.11 reason code */
81 u_int8_t im_macaddr[IEEE80211_ADDR_LEN];
82};
83
84struct ieee80211req_addpmkid {
85 u_int8_t pi_bssid[IEEE80211_ADDR_LEN];
86 u_int8_t pi_enable;
87 u_int8_t pi_pmkid[16];
88};
89
90#define AUTH_ALG_OPEN_SYSTEM 0x01
91#define AUTH_ALG_SHARED_KEY 0x02
92#define AUTH_ALG_LEAP 0x04
93
94struct ieee80211req_authalg {
95 u_int8_t auth_alg;
96};
97
98/*
99 * Request to add an IE to a Management Frame
100 */
101enum{
102 IEEE80211_APPIE_FRAME_BEACON = 0,
103 IEEE80211_APPIE_FRAME_PROBE_REQ = 1,
104 IEEE80211_APPIE_FRAME_PROBE_RESP = 2,
105 IEEE80211_APPIE_FRAME_ASSOC_REQ = 3,
106 IEEE80211_APPIE_FRAME_ASSOC_RESP = 4,
107 IEEE80211_APPIE_NUM_OF_FRAME = 5
108};
109
110/*
111 * The Maximum length of the IE that can be added to a Management frame
112 */
113#define IEEE80211_APPIE_FRAME_MAX_LEN 200
114
115struct ieee80211req_getset_appiebuf {
116 u_int32_t app_frmtype; /* management frame type for which buffer is added */
117 u_int32_t app_buflen; /*application supplied buffer length */
118 u_int8_t app_buf[];
119};
120
121/*
122 * The following definitions are used by an application to set filter
123 * for receiving management frames
124 */
125enum {
126 IEEE80211_FILTER_TYPE_BEACON = 0x1,
127 IEEE80211_FILTER_TYPE_PROBE_REQ = 0x2,
128 IEEE80211_FILTER_TYPE_PROBE_RESP = 0x4,
129 IEEE80211_FILTER_TYPE_ASSOC_REQ = 0x8,
130 IEEE80211_FILTER_TYPE_ASSOC_RESP = 0x10,
131 IEEE80211_FILTER_TYPE_AUTH = 0x20,
132 IEEE80211_FILTER_TYPE_DEAUTH = 0x40,
133 IEEE80211_FILTER_TYPE_DISASSOC = 0x80,
134 IEEE80211_FILTER_TYPE_ALL = 0xFF /* used to check the valid filter bits */
135};
136
137struct ieee80211req_set_filter {
138 u_int32_t app_filterype; /* management frame filter type */
139};
140
141enum {
142 IEEE80211_PARAM_AUTHMODE = 3, /* Authentication Mode */
143 IEEE80211_PARAM_MCASTCIPHER = 5,
144 IEEE80211_PARAM_MCASTKEYLEN = 6, /* multicast key length */
145 IEEE80211_PARAM_UCASTCIPHER = 8,
146 IEEE80211_PARAM_UCASTKEYLEN = 9, /* unicast key length */
147 IEEE80211_PARAM_WPA = 10, /* WPA mode (0,1,2) */
148 IEEE80211_PARAM_ROAMING = 12, /* roaming mode */
149 IEEE80211_PARAM_PRIVACY = 13, /* privacy invoked */
150 IEEE80211_PARAM_COUNTERMEASURES = 14, /* WPA/TKIP countermeasures */
151 IEEE80211_PARAM_DROPUNENCRYPTED = 15, /* discard unencrypted frames */
152 IEEE80211_PARAM_WAPI = 16, /* WAPI policy from wapid */
153};
154
155/*
156 * Values for IEEE80211_PARAM_WPA
157 */
158#define WPA_MODE_WPA1 1
159#define WPA_MODE_WPA2 2
160#define WPA_MODE_AUTO 3
161#define WPA_MODE_NONE 4
162
163struct ieee80211req_wpaie {
164 u_int8_t wpa_macaddr[IEEE80211_ADDR_LEN];
165 u_int8_t wpa_ie[IEEE80211_MAX_IE];
166 u_int8_t rsn_ie[IEEE80211_MAX_IE];
167};
168
169#ifndef IW_ENCODE_ALG_PMK
170#define IW_ENCODE_ALG_PMK 4
171#endif
172
173#ifdef __cplusplus
174}
175#endif
176
177#endif /* _IEEE80211_IOCTL_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h
new file mode 100644
index 00000000000..41f43730772
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h
@@ -0,0 +1,339 @@
1//------------------------------------------------------------------------------
2// This file contains the definitions of the basic atheros data types.
3// It is used to map the data types in atheros files to a platform specific
4// type.
5// Copyright (c) 2004-2010 Atheros Communications Inc.
6// All rights reserved.
7//
8//
9//
10// Permission to use, copy, modify, and/or distribute this software for any
11// purpose with or without fee is hereby granted, provided that the above
12// copyright notice and this permission notice appear in all copies.
13//
14// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21//
22//
23//
24// Author(s): ="Atheros"
25//------------------------------------------------------------------------------
26
27#ifndef _OSAPI_LINUX_H_
28#define _OSAPI_LINUX_H_
29
30#ifdef __KERNEL__
31
32#include <linux/types.h>
33#include <linux/kernel.h>
34#include <linux/string.h>
35#include <linux/skbuff.h>
36#include <linux/netdevice.h>
37#include <linux/jiffies.h>
38#include <linux/timer.h>
39#include <linux/delay.h>
40#include <linux/wait.h>
41#include <linux/semaphore.h>
42#include <linux/cache.h>
43
44#ifdef __GNUC__
45#define __ATTRIB_PACK __attribute__ ((packed))
46#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2)))
47#define __ATTRIB_NORETURN __attribute__ ((noreturn))
48#ifndef INLINE
49#define INLINE __inline__
50#endif
51#else /* Not GCC */
52#define __ATTRIB_PACK
53#define __ATTRIB_PRINTF
54#define __ATTRIB_NORETURN
55#ifndef INLINE
56#define INLINE __inline
57#endif
58#endif /* End __GNUC__ */
59
60#define PREPACK
61#define POSTPACK __ATTRIB_PACK
62
63/*
64 * Endianes macros
65 */
66#define A_BE2CPU8(x) ntohb(x)
67#define A_BE2CPU16(x) ntohs(x)
68#define A_BE2CPU32(x) ntohl(x)
69
70#define A_LE2CPU8(x) (x)
71#define A_LE2CPU16(x) (x)
72#define A_LE2CPU32(x) (x)
73
74#define A_CPU2BE8(x) htonb(x)
75#define A_CPU2BE16(x) htons(x)
76#define A_CPU2BE32(x) htonl(x)
77
78#define A_MEMZERO(addr, len) memset(addr, 0, len)
79#define A_MALLOC(size) kmalloc((size), GFP_KERNEL)
80#define A_MALLOC_NOWAIT(size) kmalloc((size), GFP_ATOMIC)
81
82#define A_LOGGER(mask, mod, args...) printk(KERN_ALERT args)
83#define A_PRINTF(args...) printk(KERN_ALERT args)
84
85#define A_PRINTF_LOG(args...) printk(args)
86#define A_SPRINTF(buf, args...) sprintf (buf, args)
87
88/* Mutual Exclusion */
89typedef spinlock_t A_MUTEX_T;
90#define A_MUTEX_INIT(mutex) spin_lock_init(mutex)
91#define A_MUTEX_LOCK(mutex) spin_lock_bh(mutex)
92#define A_MUTEX_UNLOCK(mutex) spin_unlock_bh(mutex)
93#define A_IS_MUTEX_VALID(mutex) true /* okay to return true, since A_MUTEX_DELETE does nothing */
94#define A_MUTEX_DELETE(mutex) /* spin locks are not kernel resources so nothing to free.. */
95
96/* Get current time in ms adding a constant offset (in ms) */
97#define A_GET_MS(offset) \
98 (((jiffies / HZ) * 1000) + (offset))
99
100/*
101 * Timer Functions
102 */
103#define A_MDELAY(msecs) mdelay(msecs)
104typedef struct timer_list A_TIMER;
105
106#define A_INIT_TIMER(pTimer, pFunction, pArg) do { \
107 init_timer(pTimer); \
108 (pTimer)->function = (pFunction); \
109 (pTimer)->data = (unsigned long)(pArg); \
110} while (0)
111
112/*
113 * Start a Timer that elapses after 'periodMSec' milli-seconds
114 * Support is provided for a one-shot timer. The 'repeatFlag' is
115 * ignored.
116 */
117#define A_TIMEOUT_MS(pTimer, periodMSec, repeatFlag) do { \
118 if (repeatFlag) { \
119 printk("\n" __FILE__ ":%d: Timer Repeat requested\n",__LINE__); \
120 panic("Timer Repeat"); \
121 } \
122 mod_timer((pTimer), jiffies + HZ * (periodMSec) / 1000); \
123} while (0)
124
125/*
126 * Cancel the Timer.
127 */
128#define A_UNTIMEOUT(pTimer) do { \
129 del_timer((pTimer)); \
130} while (0)
131
132#define A_DELETE_TIMER(pTimer) do { \
133} while (0)
134
135/*
136 * Wait Queue related functions
137 */
138typedef wait_queue_head_t A_WAITQUEUE_HEAD;
139#define A_INIT_WAITQUEUE_HEAD(head) init_waitqueue_head(head)
140#ifndef wait_event_interruptible_timeout
141#define __wait_event_interruptible_timeout(wq, condition, ret) \
142do { \
143 wait_queue_t __wait; \
144 init_waitqueue_entry(&__wait, current); \
145 \
146 add_wait_queue(&wq, &__wait); \
147 for (;;) { \
148 set_current_state(TASK_INTERRUPTIBLE); \
149 if (condition) \
150 break; \
151 if (!signal_pending(current)) { \
152 ret = schedule_timeout(ret); \
153 if (!ret) \
154 break; \
155 continue; \
156 } \
157 ret = -ERESTARTSYS; \
158 break; \
159 } \
160 current->state = TASK_RUNNING; \
161 remove_wait_queue(&wq, &__wait); \
162} while (0)
163
164#define wait_event_interruptible_timeout(wq, condition, timeout) \
165({ \
166 long __ret = timeout; \
167 if (!(condition)) \
168 __wait_event_interruptible_timeout(wq, condition, __ret); \
169 __ret; \
170})
171#endif /* wait_event_interruptible_timeout */
172
173#define A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(head, condition, timeout) do { \
174 wait_event_interruptible_timeout(head, condition, timeout); \
175} while (0)
176
177#define A_WAKE_UP(head) wake_up(head)
178
179#ifdef DEBUG
180extern unsigned int panic_on_assert;
181#define A_ASSERT(expr) \
182 if (!(expr)) { \
183 printk(KERN_ALERT"Debug Assert Caught, File %s, Line: %d, Test:%s \n",__FILE__, __LINE__,#expr); \
184 if (panic_on_assert) panic(#expr); \
185 }
186#else
187#define A_ASSERT(expr)
188#endif /* DEBUG */
189
190#define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) request_firmware(_ppf, _pfile, _dev)
191#define A_RELEASE_FIRMWARE(_pf) release_firmware(_pf)
192
193/*
194 * Initialization of the network buffer subsystem
195 */
196#define A_NETBUF_INIT()
197
198/*
199 * Network buffer queue support
200 */
201typedef struct sk_buff_head A_NETBUF_QUEUE_T;
202
203#define A_NETBUF_QUEUE_INIT(q) \
204 a_netbuf_queue_init(q)
205
206#define A_NETBUF_ENQUEUE(q, pkt) \
207 a_netbuf_enqueue((q), (pkt))
208#define A_NETBUF_PREQUEUE(q, pkt) \
209 a_netbuf_prequeue((q), (pkt))
210#define A_NETBUF_DEQUEUE(q) \
211 (a_netbuf_dequeue(q))
212#define A_NETBUF_QUEUE_SIZE(q) \
213 a_netbuf_queue_size(q)
214#define A_NETBUF_QUEUE_EMPTY(q) \
215 (a_netbuf_queue_empty(q) ? true : false)
216
217/*
218 * Network buffer support
219 */
220#define A_NETBUF_ALLOC(size) \
221 a_netbuf_alloc(size)
222#define A_NETBUF_ALLOC_RAW(size) \
223 a_netbuf_alloc_raw(size)
224#define A_NETBUF_FREE(bufPtr) \
225 a_netbuf_free(bufPtr)
226#define A_NETBUF_DATA(bufPtr) \
227 a_netbuf_to_data(bufPtr)
228#define A_NETBUF_LEN(bufPtr) \
229 a_netbuf_to_len(bufPtr)
230#define A_NETBUF_PUSH(bufPtr, len) \
231 a_netbuf_push(bufPtr, len)
232#define A_NETBUF_PUT(bufPtr, len) \
233 a_netbuf_put(bufPtr, len)
234#define A_NETBUF_TRIM(bufPtr,len) \
235 a_netbuf_trim(bufPtr, len)
236#define A_NETBUF_PULL(bufPtr, len) \
237 a_netbuf_pull(bufPtr, len)
238#define A_NETBUF_HEADROOM(bufPtr)\
239 a_netbuf_headroom(bufPtr)
240#define A_NETBUF_SETLEN(bufPtr,len) \
241 a_netbuf_setlen(bufPtr, len)
242
243/* Add data to end of a buffer */
244#define A_NETBUF_PUT_DATA(bufPtr, srcPtr, len) \
245 a_netbuf_put_data(bufPtr, srcPtr, len)
246
247/* Add data to start of the buffer */
248#define A_NETBUF_PUSH_DATA(bufPtr, srcPtr, len) \
249 a_netbuf_push_data(bufPtr, srcPtr, len)
250
251/* Remove data at start of the buffer */
252#define A_NETBUF_PULL_DATA(bufPtr, dstPtr, len) \
253 a_netbuf_pull_data(bufPtr, dstPtr, len)
254
255/* Remove data from the end of the buffer */
256#define A_NETBUF_TRIM_DATA(bufPtr, dstPtr, len) \
257 a_netbuf_trim_data(bufPtr, dstPtr, len)
258
259/* View data as "size" contiguous bytes of type "t" */
260#define A_NETBUF_VIEW_DATA(bufPtr, t, size) \
261 (t )( ((struct skbuf *)(bufPtr))->data)
262
263/* return the beginning of the headroom for the buffer */
264#define A_NETBUF_HEAD(bufPtr) \
265 ((((struct sk_buff *)(bufPtr))->head))
266
267/*
268 * OS specific network buffer access routines
269 */
270void *a_netbuf_alloc(int size);
271void *a_netbuf_alloc_raw(int size);
272void a_netbuf_free(void *bufPtr);
273void *a_netbuf_to_data(void *bufPtr);
274u32 a_netbuf_to_len(void *bufPtr);
275int a_netbuf_push(void *bufPtr, s32 len);
276int a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len);
277int a_netbuf_put(void *bufPtr, s32 len);
278int a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len);
279int a_netbuf_pull(void *bufPtr, s32 len);
280int a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len);
281int a_netbuf_trim(void *bufPtr, s32 len);
282int a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len);
283int a_netbuf_setlen(void *bufPtr, s32 len);
284s32 a_netbuf_headroom(void *bufPtr);
285void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt);
286void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt);
287void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q);
288int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q);
289int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q);
290int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q);
291void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q);
292
293/*
294 * Kernel v.s User space functions
295 */
296u32 a_copy_to_user(void *to, const void *from, u32 n);
297u32 a_copy_from_user(void *to, const void *from, u32 n);
298
299/* In linux, WLAN Rx and Tx run in different contexts, so no need to check
300 * for any commands/data queued for WLAN */
301#define A_CHECK_DRV_TX()
302
303#define A_GET_CACHE_LINE_BYTES() L1_CACHE_BYTES
304
305#define A_CACHE_LINE_PAD 128
306
307static inline void *A_ALIGN_TO_CACHE_LINE(void *ptr) {
308 return (void *)L1_CACHE_ALIGN((unsigned long)ptr);
309}
310
311#else /* __KERNEL__ */
312
313#ifdef __GNUC__
314#define __ATTRIB_PACK __attribute__ ((packed))
315#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2)))
316#define __ATTRIB_NORETURN __attribute__ ((noreturn))
317#ifndef INLINE
318#define INLINE __inline__
319#endif
320#else /* Not GCC */
321#define __ATTRIB_PACK
322#define __ATTRIB_PRINTF
323#define __ATTRIB_NORETURN
324#ifndef INLINE
325#define INLINE __inline
326#endif
327#endif /* End __GNUC__ */
328
329#define PREPACK
330#define POSTPACK __ATTRIB_PACK
331
332#define A_MEMZERO(addr, len) memset((addr), 0, (len))
333#define A_MALLOC(size) malloc(size)
334
335#include <err.h>
336
337#endif /* __KERNEL__ */
338
339#endif /* _OSAPI_LINUX_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/wlan_config.h b/drivers/staging/ath6kl/os/linux/include/wlan_config.h
new file mode 100644
index 00000000000..c1fe0c6e4fa
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/wlan_config.h
@@ -0,0 +1,108 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// This file contains the tunable configuration items for the WLAN module
21//
22// Author(s): ="Atheros"
23//==============================================================================
24#ifndef _HOST_WLAN_CONFIG_H_
25#define _HOST_WLAN_CONFIG_H_
26
27/* Include definitions here that can be used to tune the WLAN module behavior.
28 * Different customers can tune the behavior as per their needs, here.
29 */
30
31/* This configuration item when defined will consider the barker preamble
32 * mentioned in the ERP IE of the beacons from the AP to determine the short
33 * preamble support sent in the (Re)Assoc request frames.
34 */
35#define WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP 0
36
37/* This config item when defined will not send the power module state transition
38 * failure events that happen during scan, to the host.
39 */
40#define WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN 0
41
42/*
43 * This configuration item enable/disable keepalive support.
44 * Keepalive support: In the absence of any data traffic to AP, null
45 * frames will be sent to the AP at periodic interval, to keep the association
46 * active. This configuration item defines the periodic interval.
47 * Use value of zero to disable keepalive support
48 * Default: 60 seconds
49 */
50#define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60
51
52/*
53 * This configuration item sets the value of disconnect timeout
54 * Firmware delays sending the disconnec event to the host for this
55 * timeout after is gets disconnected from the current AP.
56 * If the firmware successly roams within the disconnect timeout
57 * it sends a new connect event
58 */
59#define WLAN_CONFIG_DISCONNECT_TIMEOUT 10
60
61/*
62 * This configuration item disables 11n support.
63 * 0 - Enable
64 * 1 - Disable
65 */
66#define WLAN_CONFIG_DISABLE_11N 0
67
68/*
69 * This configuration item enable BT clock sharing support
70 * 1 - Enable
71 * 0 - Disable (Default)
72 */
73#define WLAN_CONFIG_BT_SHARING 0
74
75/*
76 * This configuration item sets WIFI OFF policy
77 * 0 - CUT_POWER
78 * 1 - DEEP_SLEEP (Default)
79 */
80#define WLAN_CONFIG_WLAN_OFF 1
81
82/*
83 * This configuration item sets suspend policy
84 * 0 - CUT_POWER (Default)
85 * 1 - DEEP_SLEEP
86 * 2 - WoW
87 * 3 - CUT_POWER if BT OFF (clock sharing designs only)
88 */
89#define WLAN_CONFIG_PM_SUSPEND 0
90
91/*
92 * This configuration item sets suspend policy to use if PM_SUSPEND is
93 * set to WoW and device is not connected at the time of suspend
94 * 0 - CUT_POWER (Default)
95 * 1 - DEEP_SLEEP
96 * 2 - WoW
97 * 3 - CUT_POWER if BT OFF (clock sharing designs only)
98 */
99#define WLAN_CONFIG_PM_WOW2 0
100
101/*
102 * This configuration item enables/disables transmit bursting
103 * 0 - Enable tx Bursting (default)
104 * 1 - Disable tx bursting
105 */
106#define WLAN_CONFIG_DISABLE_TX_BURSTING 0
107
108#endif /* _HOST_WLAN_CONFIG_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h
new file mode 100644
index 00000000000..1eb6f822d64
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h
@@ -0,0 +1,300 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _WMI_FILTER_LINUX_H_
25#define _WMI_FILTER_LINUX_H_
26
27/*
28 * sioctl_filter - Standard ioctl
29 * pioctl_filter - Priv ioctl
30 * xioctl_filter - eXtended ioctl
31 *
32 * ---- Possible values for the WMI filter ---------------
33 * (0) - Block this cmd always (or) not implemented
34 * (INFRA_NETWORK) - Allow this cmd only in STA mode
35 * (ADHOC_NETWORK) - Allow this cmd only in IBSS mode
36 * (AP_NETWORK) - Allow this cmd only in AP mode
37 * (INFRA_NETWORK | ADHOC_NETWORK) - Block this cmd in AP mode
38 * (ADHOC_NETWORK | AP_NETWORK) - Block this cmd in STA mode
39 * (INFRA_NETWORK | AP_NETWORK) - Block this cmd in IBSS mode
40 * (INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK)- allow only when mode is set
41 * (0xFF) - Allow this cmd always irrespective of mode
42 */
43
44u8 sioctl_filter[] = {
45(AP_NETWORK), /* SIOCSIWCOMMIT 0x8B00 */
46(0xFF), /* SIOCGIWNAME 0x8B01 */
47(0), /* SIOCSIWNWID 0x8B02 */
48(0), /* SIOCGIWNWID 0x8B03 */
49(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWFREQ 0x8B04 */
50(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWFREQ 0x8B05 */
51(0xFF), /* SIOCSIWMODE 0x8B06 */
52(0xFF), /* SIOCGIWMODE 0x8B07 */
53(0), /* SIOCSIWSENS 0x8B08 */
54(0), /* SIOCGIWSENS 0x8B09 */
55(0), /* SIOCSIWRANGE 0x8B0A */
56(0xFF), /* SIOCGIWRANGE 0x8B0B */
57(0), /* SIOCSIWPRIV 0x8B0C */
58(0), /* SIOCGIWPRIV 0x8B0D */
59(0), /* SIOCSIWSTATS 0x8B0E */
60(0), /* SIOCGIWSTATS 0x8B0F */
61(0), /* SIOCSIWSPY 0x8B10 */
62(0), /* SIOCGIWSPY 0x8B11 */
63(0), /* SIOCSIWTHRSPY 0x8B12 */
64(0), /* SIOCGIWTHRSPY 0x8B13 */
65(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWAP 0x8B14 */
66(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWAP 0x8B15 */
67#if (WIRELESS_EXT >= 18)
68(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWMLME 0X8B16 */
69#else
70(0), /* Dummy 0 */
71#endif /* WIRELESS_EXT */
72(0), /* SIOCGIWAPLIST 0x8B17 */
73(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWSCAN 0x8B18 */
74(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCGIWSCAN 0x8B19 */
75(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWESSID 0x8B1A */
76(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWESSID 0x8B1B */
77(0), /* SIOCSIWNICKN 0x8B1C */
78(0), /* SIOCGIWNICKN 0x8B1D */
79(0), /* Dummy 0 */
80(0), /* Dummy 0 */
81(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWRATE 0x8B20 */
82(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWRATE 0x8B21 */
83(0), /* SIOCSIWRTS 0x8B22 */
84(0), /* SIOCGIWRTS 0x8B23 */
85(0), /* SIOCSIWFRAG 0x8B24 */
86(0), /* SIOCGIWFRAG 0x8B25 */
87(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWTXPOW 0x8B26 */
88(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWTXPOW 0x8B27 */
89(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWRETRY 0x8B28 */
90(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCGIWRETRY 0x8B29 */
91(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWENCODE 0x8B2A */
92(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWENCODE 0x8B2B */
93(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWPOWER 0x8B2C */
94(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWPOWER 0x8B2D */
95};
96
97
98
99u8 pioctl_filter[] = {
100(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0) */
101(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+1) */
102(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_DELKEY (SIOCIWFIRSTPRIV+2) */
103(AP_NETWORK), /* IEEE80211_IOCTL_SETMLME (SIOCIWFIRSTPRIV+3) */
104(INFRA_NETWORK), /* IEEE80211_IOCTL_ADDPMKID (SIOCIWFIRSTPRIV+4) */
105(0), /* IEEE80211_IOCTL_SETOPTIE (SIOCIWFIRSTPRIV+5) */
106(0), /* (SIOCIWFIRSTPRIV+6) */
107(0), /* (SIOCIWFIRSTPRIV+7) */
108(0), /* (SIOCIWFIRSTPRIV+8) */
109(0), /* (SIOCIWFIRSTPRIV+9) */
110(0), /* IEEE80211_IOCTL_LASTONE (SIOCIWFIRSTPRIV+10) */
111(0xFF), /* AR6000_IOCTL_WMI_GETREV (SIOCIWFIRSTPRIV+11) */
112(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_IOCTL_WMI_SETPWR (SIOCIWFIRSTPRIV+12) */
113(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETSCAN (SIOCIWFIRSTPRIV+13) */
114(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETLISTENINT (SIOCIWFIRSTPRIV+14) */
115(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETBSSFILTER (SIOCIWFIRSTPRIV+15) */
116(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_IOCTL_WMI_SET_CHANNELPARAMS (SIOCIWFIRSTPRIV+16) */
117(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_PROBEDSSID (SIOCIWFIRSTPRIV+17) */
118(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_PMPARAMS (SIOCIWFIRSTPRIV+18) */
119(INFRA_NETWORK), /* AR6000_IOCTL_WMI_SET_BADAP (SIOCIWFIRSTPRIV+19) */
120(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_GET_QOS_QUEUE (SIOCIWFIRSTPRIV+20) */
121(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_CREATE_QOS (SIOCIWFIRSTPRIV+21) */
122(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_DELETE_QOS (SIOCIWFIRSTPRIV+22) */
123(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_SNRTHRESHOLD (SIOCIWFIRSTPRIV+23) */
124(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK (SIOCIWFIRSTPRIV+24)*/
125(0xFF), /* AR6000_IOCTL_WMI_GET_TARGET_STATS (SIOCIWFIRSTPRIV+25) */
126(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ASSOC_INFO (SIOCIWFIRSTPRIV+26) */
127(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ACCESS_PARAMS (SIOCIWFIRSTPRIV+27) */
128(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_BMISS_TIME (SIOCIWFIRSTPRIV+28) */
129(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_DISC_TIMEOUT (SIOCIWFIRSTPRIV+29) */
130(ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS (SIOCIWFIRSTPRIV+30) */
131};
132
133
134
135u8 xioctl_filter[] = {
136(0xFF), /* Dummy 0 */
137(0xFF), /* AR6000_XIOCTL_BMI_DONE 1 */
138(0xFF), /* AR6000_XIOCTL_BMI_READ_MEMORY 2 */
139(0xFF), /* AR6000_XIOCTL_BMI_WRITE_MEMORY 3 */
140(0xFF), /* AR6000_XIOCTL_BMI_EXECUTE 4 */
141(0xFF), /* AR6000_XIOCTL_BMI_SET_APP_START 5 */
142(0xFF), /* AR6000_XIOCTL_BMI_READ_SOC_REGISTER 6 */
143(0xFF), /* AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER 7 */
144(0xFF), /* AR6000_XIOCTL_BMI_TEST 8 */
145(0xFF), /* AR6000_XIOCTL_UNUSED9 9 */
146(0xFF), /* AR6000_XIOCTL_UNUSED10 10 */
147(0xFF), /* AR6000_XIOCTL_UNUSED11 11 */
148(0xFF), /* AR6000_XIOCTL_FORCE_TARGET_RESET 12 */
149(0xFF), /* AR6000_XIOCTL_HTC_RAW_OPEN 13 */
150(0xFF), /* AR6000_XIOCTL_HTC_RAW_CLOSE 14 */
151(0xFF), /* AR6000_XIOCTL_HTC_RAW_READ 15 */
152(0xFF), /* AR6000_XIOCTL_HTC_RAW_WRITE 16 */
153(0xFF), /* AR6000_XIOCTL_CHECK_TARGET_READY 17 */
154(0xFF), /* AR6000_XIOCTL_GPIO_OUTPUT_SET 18 */
155(0xFF), /* AR6000_XIOCTL_GPIO_INPUT_GET 19 */
156(0xFF), /* AR6000_XIOCTL_GPIO_REGISTER_SET 20 */
157(0xFF), /* AR6000_XIOCTL_GPIO_REGISTER_GET 21 */
158(0xFF), /* AR6000_XIOCTL_GPIO_INTR_ACK 22 */
159(0xFF), /* AR6000_XIOCTL_GPIO_INTR_WAIT 23 */
160(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_ADHOC_BSSID 24 */
161(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_OPT_MODE 25 */
162(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_OPT_SEND_FRAME 26 */
163(ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_SET_BEACON_INTVAL 27 */
164(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETAUTHALG 28 */
165(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_VOICE_PKT_SIZE 29 */
166(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_MAX_SP 30 */
167(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_ROAM_TBL 31 */
168(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_ROAM_CTRL 32 */
169(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS 33 */
170(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTRL_WMI_GET_POWER_MODE 34 */
171(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTRL_WMI_SET_WLAN_STATE 35 */
172(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_ROAM_DATA 36 */
173(0xFF), /* AR6000_XIOCTL_WMI_SETRETRYLIMITS 37 */
174(0xFF), /* AR6000_XIOCTL_TCMD_CONT_TX 38 */
175(0xFF), /* AR6000_XIOCTL_TCMD_CONT_RX 39 */
176(0xFF), /* AR6000_XIOCTL_TCMD_PM 40 */
177(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_STARTSCAN 41 */
178(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SETFIXRATES 42 */
179(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_GETFIXRATES 43 */
180(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD 44 */
181(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_CLR_RSSISNR 45 */
182(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_LQTHRESHOLD 46 */
183(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_RTS 47 */
184(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_LPREAMBLE 48 */
185(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_AUTHMODE 49 */
186(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_REASSOCMODE 50 */
187(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WMM 51 */
188(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS 52 */
189(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP 53 */
190(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_GET_RD 54 */
191(0xFF), /* AR6000_XIOCTL_DIAG_READ 55 */
192(0xFF), /* AR6000_XIOCTL_DIAG_WRITE 56 */
193(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_TXOP 57 */
194(INFRA_NETWORK), /* AR6000_XIOCTL_USER_SETKEYS 58 */
195(INFRA_NETWORK), /* AR6000_XIOCTL_WMI_SET_KEEPALIVE 59 */
196(INFRA_NETWORK), /* AR6000_XIOCTL_WMI_GET_KEEPALIVE 60 */
197(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_INSTALL 61 */
198(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL 62 */
199(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE 63 */
200(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE 64 */
201(0xFF), /* AR6000_XIOCTL_WMI_SET_APPIE 65 */
202(0xFF), /* AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER 66 */
203(0xFF), /* AR6000_XIOCTL_DBGLOG_CFG_MODULE 67 */
204(0xFF), /* AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS 68 */
205(0xFF), /* Dummy 69 */
206(0xFF), /* AR6000_XIOCTL_WMI_SET_WSC_STATUS 70 */
207(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_STATUS 71 */
208(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_PARAMS 72 */
209(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE 73 */
210(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WOW_MODE 74 */
211(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_WOW_LIST 75 */
212(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_ADD_WOW_PATTERN 76 */
213(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_DEL_WOW_PATTERN 77 */
214(0xFF), /* AR6000_XIOCTL_TARGET_INFO 78 */
215(0xFF), /* AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE 79 */
216(0xFF), /* AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE 80 */
217(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS 81 */
218(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_AKMP_PARAMS 82 */
219(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_PMKID_LIST 83 */
220(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_PMKID_LIST 84 */
221(0xFF), /* Dummy 85 */
222(0xFF), /* Dummy 86 */
223(0xFF), /* Dummy 87 */
224(0xFF), /* Dummy 88 */
225(0xFF), /* Dummy 89 */
226(0xFF), /* AR6000_XIOCTL_UNUSED90 90 */
227(0xFF), /* AR6000_XIOCTL_BMI_LZ_STREAM_START 91 */
228(0xFF), /* AR6000_XIOCTL_BMI_LZ_DATA 92 */
229(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_CFG 93 */
230(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_ADDR_SET 94 */
231(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_START 95 */
232(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_STOP 96 */
233(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_COUNT_GET 97 */
234(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_ABORT_SCAN 98 */
235(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_STA_LIST 99 */
236(AP_NETWORK), /* AR6000_XIOCTL_AP_HIDDEN_SSID 100 */
237(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_NUM_STA 101 */
238(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_ACL_MAC 102 */
239(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_ACL_LIST 103 */
240(AP_NETWORK), /* AR6000_XIOCTL_AP_COMMIT_CONFIG 104 */
241(AP_NETWORK), /* IEEE80211_IOCTL_GETWPAIE 105 */
242(AP_NETWORK), /* AR6000_XIOCTL_AP_CONN_INACT_TIME 106 */
243(AP_NETWORK), /* AR6000_XIOCTL_AP_PROT_SCAN_TIME 107 */
244(AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_COUNTRY 108 */
245(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_DTIM 109 */
246(0xFF), /* AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT 110 */
247(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_IP 111 */
248(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_ACL_POLICY 112 */
249(AP_NETWORK), /* AR6000_XIOCTL_AP_INTRA_BSS_COMM 113 */
250(0xFF), /* AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO 114 */
251(0xFF), /* AR6000_XIOCTL_MODULE_DEBUG_SET_MASK 115 */
252(0xFF), /* AR6000_XIOCTL_MODULE_DEBUG_GET_MASK 116 */
253(0xFF), /* AR6000_XIOCTL_DUMP_RCV_AGGR_STATS 117 */
254(0xFF), /* AR6000_XIOCTL_SET_HT_CAP 118 */
255(0xFF), /* AR6000_XIOCTL_SET_HT_OP 119 */
256(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_STAT 120 */
257(0xFF), /* AR6000_XIOCTL_SET_TX_SELECT_RATES 121 */
258(0xFF), /* AR6000_XIOCTL_SETUP_AGGR 122 */
259(0xFF), /* AR6000_XIOCTL_ALLOW_AGGR 123 */
260(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_HIDDEN_SSID 124 */
261(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_COUNTRY 125 */
262(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_WMODE 126 */
263(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_DTIM 127 */
264(AP_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_AP_GET_BINTVL 128 */
265(0xFF), /* AR6000_XIOCTL_AP_GET_RTS 129 */
266(0xFF), /* AR6000_XIOCTL_DELE_AGGR 130 */
267(0xFF), /* AR6000_XIOCTL_FETCH_TARGET_REGS 131 */
268(0xFF), /* AR6000_XIOCTL_HCI_CMD 132 */
269(0xFF), /* AR6000_XIOCTL_ACL_DATA(used to be used for PAL) 133 */
270(0xFF), /* AR6000_XIOCTL_WLAN_CONN_PRECEDENCE 134 */
271(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_11BG_RATESET 135 */
272(0xFF),
273(0xFF),
274(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT 138 */
275(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV 139 */
276(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG 140 */
277(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG 141 */
278(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG 142 */
279(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG 143 */
280(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG 144 */
281(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS 145 */
282(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG 146 */
283(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_BTCOEX_GET_STATS 147 */
284(0xFF), /* AR6000_XIOCTL_WMI_SET_QOS_SUPP 148 */
285(0xFF), /* AR6000_XIOCTL_GET_WLAN_SLEEP_STATE 149 */
286(0xFF), /* AR6000_XIOCTL_SET_BT_HW_POWER_STATE 150 */
287(0xFF), /* AR6000_XIOCTL_GET_BT_HW_POWER_STATE 151 */
288(0xFF), /* AR6000_XIOCTL_ADD_AP_INTERFACE 152 */
289(0xFF), /* AR6000_XIOCTL_REMOVE_AP_INTERFACE 153 */
290(0xFF), /* AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM 154 */
291(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WPA_OFFLOAD_STATE 155 */
292(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_PASSPHRASE 156 */
293(0xFF),
294(0xFF),
295(0xFF),
296(0xFF),
297(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES 161 */
298};
299
300#endif /*_WMI_FILTER_LINUX_H_*/
diff --git a/drivers/staging/ath6kl/os/linux/netbuf.c b/drivers/staging/ath6kl/os/linux/netbuf.c
new file mode 100644
index 00000000000..963a2fb76a9
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/netbuf.c
@@ -0,0 +1,231 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23#include <a_config.h>
24#include "athdefs.h"
25#include "a_osapi.h"
26#include "htc_packet.h"
27
28#define AR6000_DATA_OFFSET 64
29
30void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt)
31{
32 skb_queue_tail((struct sk_buff_head *) q, (struct sk_buff *) pkt);
33}
34
35void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt)
36{
37 skb_queue_head((struct sk_buff_head *) q, (struct sk_buff *) pkt);
38}
39
40void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q)
41{
42 return((void *) skb_dequeue((struct sk_buff_head *) q));
43}
44
45int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q)
46{
47 return(skb_queue_len((struct sk_buff_head *) q));
48}
49
50int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q)
51{
52 return(skb_queue_empty((struct sk_buff_head *) q));
53}
54
55void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q)
56{
57 skb_queue_head_init((struct sk_buff_head *) q);
58}
59
60void *
61a_netbuf_alloc(int size)
62{
63 struct sk_buff *skb;
64 size += 2 * (A_GET_CACHE_LINE_BYTES()); /* add some cacheline space at front and back of buffer */
65 skb = dev_alloc_skb(AR6000_DATA_OFFSET + sizeof(struct htc_packet) + size);
66 skb_reserve(skb, AR6000_DATA_OFFSET + sizeof(struct htc_packet) + A_GET_CACHE_LINE_BYTES());
67 return ((void *)skb);
68}
69
70/*
71 * Allocate an SKB w.o. any encapsulation requirement.
72 */
73void *
74a_netbuf_alloc_raw(int size)
75{
76 struct sk_buff *skb;
77
78 skb = dev_alloc_skb(size);
79
80 return ((void *)skb);
81}
82
83void
84a_netbuf_free(void *bufPtr)
85{
86 struct sk_buff *skb = (struct sk_buff *)bufPtr;
87
88 dev_kfree_skb(skb);
89}
90
91u32 a_netbuf_to_len(void *bufPtr)
92{
93 return (((struct sk_buff *)bufPtr)->len);
94}
95
96void *
97a_netbuf_to_data(void *bufPtr)
98{
99 return (((struct sk_buff *)bufPtr)->data);
100}
101
102/*
103 * Add len # of bytes to the beginning of the network buffer
104 * pointed to by bufPtr
105 */
106int
107a_netbuf_push(void *bufPtr, s32 len)
108{
109 skb_push((struct sk_buff *)bufPtr, len);
110
111 return 0;
112}
113
114/*
115 * Add len # of bytes to the beginning of the network buffer
116 * pointed to by bufPtr and also fill with data
117 */
118int
119a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len)
120{
121 skb_push((struct sk_buff *) bufPtr, len);
122 memcpy(((struct sk_buff *)bufPtr)->data, srcPtr, len);
123
124 return 0;
125}
126
127/*
128 * Add len # of bytes to the end of the network buffer
129 * pointed to by bufPtr
130 */
131int
132a_netbuf_put(void *bufPtr, s32 len)
133{
134 skb_put((struct sk_buff *)bufPtr, len);
135
136 return 0;
137}
138
139/*
140 * Add len # of bytes to the end of the network buffer
141 * pointed to by bufPtr and also fill with data
142 */
143int
144a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len)
145{
146 char *start = (char*)(((struct sk_buff *)bufPtr)->data +
147 ((struct sk_buff *)bufPtr)->len);
148 skb_put((struct sk_buff *)bufPtr, len);
149 memcpy(start, srcPtr, len);
150
151 return 0;
152}
153
154
155/*
156 * Trim the network buffer pointed to by bufPtr to len # of bytes
157 */
158int
159a_netbuf_setlen(void *bufPtr, s32 len)
160{
161 skb_trim((struct sk_buff *)bufPtr, len);
162
163 return 0;
164}
165
166/*
167 * Chop of len # of bytes from the end of the buffer.
168 */
169int
170a_netbuf_trim(void *bufPtr, s32 len)
171{
172 skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len);
173
174 return 0;
175}
176
177/*
178 * Chop of len # of bytes from the end of the buffer and return the data.
179 */
180int
181a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len)
182{
183 char *start = (char*)(((struct sk_buff *)bufPtr)->data +
184 (((struct sk_buff *)bufPtr)->len - len));
185
186 memcpy(dstPtr, start, len);
187 skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len);
188
189 return 0;
190}
191
192
193/*
194 * Returns the number of bytes available to a a_netbuf_push()
195 */
196s32 a_netbuf_headroom(void *bufPtr)
197{
198 return (skb_headroom((struct sk_buff *)bufPtr));
199}
200
201/*
202 * Removes specified number of bytes from the beginning of the buffer
203 */
204int
205a_netbuf_pull(void *bufPtr, s32 len)
206{
207 skb_pull((struct sk_buff *)bufPtr, len);
208
209 return 0;
210}
211
212/*
213 * Removes specified number of bytes from the beginning of the buffer
214 * and return the data
215 */
216int
217a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len)
218{
219 memcpy(dstPtr, ((struct sk_buff *)bufPtr)->data, len);
220 skb_pull((struct sk_buff *)bufPtr, len);
221
222 return 0;
223}
224
225#ifdef EXPORT_HCI_BRIDGE_INTERFACE
226EXPORT_SYMBOL(a_netbuf_to_data);
227EXPORT_SYMBOL(a_netbuf_put);
228EXPORT_SYMBOL(a_netbuf_pull);
229EXPORT_SYMBOL(a_netbuf_alloc);
230EXPORT_SYMBOL(a_netbuf_free);
231#endif