aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-10-03 14:59:35 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-10-03 14:59:35 -0400
commita5abbcb2206953eb1bf86281626363f2fd7a8ceb (patch)
treebcf338e32ce63fe65eb12a44989a6008f8a34f63
parent49a59543eb5a5d268b3d11747f9c3c557ae271a0 (diff)
parent62c83ac4d6bcfa6a116c8f1c8ace05cb3933a4f1 (diff)
Merge branch 'for-linville' of git://github.com/kvalo/ath6kl
-rw-r--r--drivers/net/wireless/ath/ath6kl/Makefile4
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.c23
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.h4
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c894
-rw-r--r--drivers/net/wireless/ath/ath6kl/common.h83
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h145
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.c784
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.h49
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif-ops.h5
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.h1
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc.c271
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c794
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c448
-rw-r--r--drivers/net/wireless/ath/ath6kl/node.c234
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c79
-rw-r--r--drivers/net/wireless/ath/ath6kl/target.h41
-rw-r--r--drivers/net/wireless/ath/ath6kl/testmode.c167
-rw-r--r--drivers/net/wireless/ath/ath6kl/testmode.h36
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c61
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c1126
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h350
21 files changed, 4050 insertions, 1549 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile
index e1bb07ea8e80..8f7a0d1c290c 100644
--- a/drivers/net/wireless/ath/ath6kl/Makefile
+++ b/drivers/net/wireless/ath/ath6kl/Makefile
@@ -31,5 +31,7 @@ ath6kl-y += init.o
31ath6kl-y += main.o 31ath6kl-y += main.o
32ath6kl-y += txrx.o 32ath6kl-y += txrx.o
33ath6kl-y += wmi.o 33ath6kl-y += wmi.o
34ath6kl-y += node.o
35ath6kl-y += sdio.o 34ath6kl-y += sdio.o
35ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o
36
37ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c
index 84676697d7eb..c5d11cc536e0 100644
--- a/drivers/net/wireless/ath/ath6kl/bmi.c
+++ b/drivers/net/wireless/ath/ath6kl/bmi.c
@@ -62,14 +62,14 @@ static int ath6kl_get_bmi_cmd_credits(struct ath6kl *ar)
62 return 0; 62 return 0;
63} 63}
64 64
65static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar, bool need_timeout) 65static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar)
66{ 66{
67 unsigned long timeout; 67 unsigned long timeout;
68 u32 rx_word = 0; 68 u32 rx_word = 0;
69 int ret = 0; 69 int ret = 0;
70 70
71 timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT); 71 timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
72 while ((!need_timeout || time_before(jiffies, timeout)) && !rx_word) { 72 while (time_before(jiffies, timeout) && !rx_word) {
73 ret = hif_read_write_sync(ar, RX_LOOKAHEAD_VALID_ADDRESS, 73 ret = hif_read_write_sync(ar, RX_LOOKAHEAD_VALID_ADDRESS,
74 (u8 *)&rx_word, sizeof(rx_word), 74 (u8 *)&rx_word, sizeof(rx_word),
75 HIF_RD_SYNC_BYTE_INC); 75 HIF_RD_SYNC_BYTE_INC);
@@ -109,8 +109,7 @@ static int ath6kl_bmi_send_buf(struct ath6kl *ar, u8 *buf, u32 len)
109 return ret; 109 return ret;
110} 110}
111 111
112static int ath6kl_bmi_recv_buf(struct ath6kl *ar, 112static int ath6kl_bmi_recv_buf(struct ath6kl *ar, u8 *buf, u32 len)
113 u8 *buf, u32 len, bool want_timeout)
114{ 113{
115 int ret; 114 int ret;
116 u32 addr; 115 u32 addr;
@@ -162,7 +161,7 @@ static int ath6kl_bmi_recv_buf(struct ath6kl *ar,
162 * a function of Host processor speed. 161 * a function of Host processor speed.
163 */ 162 */
164 if (len >= 4) { /* NB: Currently, always true */ 163 if (len >= 4) { /* NB: Currently, always true */
165 ret = ath6kl_bmi_get_rx_lkahd(ar, want_timeout); 164 ret = ath6kl_bmi_get_rx_lkahd(ar);
166 if (ret) 165 if (ret)
167 return ret; 166 return ret;
168 } 167 }
@@ -220,7 +219,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
220 } 219 }
221 220
222 ret = ath6kl_bmi_recv_buf(ar, (u8 *)&targ_info->version, 221 ret = ath6kl_bmi_recv_buf(ar, (u8 *)&targ_info->version,
223 sizeof(targ_info->version), true); 222 sizeof(targ_info->version));
224 if (ret) { 223 if (ret) {
225 ath6kl_err("Unable to recv target info: %d\n", ret); 224 ath6kl_err("Unable to recv target info: %d\n", ret);
226 return ret; 225 return ret;
@@ -230,8 +229,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
230 /* Determine how many bytes are in the Target's targ_info */ 229 /* Determine how many bytes are in the Target's targ_info */
231 ret = ath6kl_bmi_recv_buf(ar, 230 ret = ath6kl_bmi_recv_buf(ar,
232 (u8 *)&targ_info->byte_count, 231 (u8 *)&targ_info->byte_count,
233 sizeof(targ_info->byte_count), 232 sizeof(targ_info->byte_count));
234 true);
235 if (ret) { 233 if (ret) {
236 ath6kl_err("unable to read target info byte count: %d\n", 234 ath6kl_err("unable to read target info byte count: %d\n",
237 ret); 235 ret);
@@ -252,8 +250,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
252 ((u8 *)targ_info) + 250 ((u8 *)targ_info) +
253 sizeof(targ_info->byte_count), 251 sizeof(targ_info->byte_count),
254 sizeof(*targ_info) - 252 sizeof(*targ_info) -
255 sizeof(targ_info->byte_count), 253 sizeof(targ_info->byte_count));
256 true);
257 254
258 if (ret) { 255 if (ret) {
259 ath6kl_err("Unable to read target info (%d bytes): %d\n", 256 ath6kl_err("Unable to read target info (%d bytes): %d\n",
@@ -311,7 +308,7 @@ int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
311 ret); 308 ret);
312 return ret; 309 return ret;
313 } 310 }
314 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len, true); 311 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len);
315 if (ret) { 312 if (ret) {
316 ath6kl_err("Unable to read from the device: %d\n", 313 ath6kl_err("Unable to read from the device: %d\n",
317 ret); 314 ret);
@@ -424,7 +421,7 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param)
424 return ret; 421 return ret;
425 } 422 }
426 423
427 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), false); 424 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param));
428 if (ret) { 425 if (ret) {
429 ath6kl_err("Unable to read from the device: %d\n", ret); 426 ath6kl_err("Unable to read from the device: %d\n", ret);
430 return ret; 427 return ret;
@@ -504,7 +501,7 @@ int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param)
504 return ret; 501 return ret;
505 } 502 }
506 503
507 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), true); 504 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param));
508 if (ret) { 505 if (ret) {
509 ath6kl_err("Unable to read from the device: %d\n", ret); 506 ath6kl_err("Unable to read from the device: %d\n", ret);
510 return ret; 507 return ret;
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h
index 83546d76d979..96851d5df24b 100644
--- a/drivers/net/wireless/ath/ath6kl/bmi.h
+++ b/drivers/net/wireless/ath/ath6kl/bmi.h
@@ -139,8 +139,8 @@
139 */ 139 */
140 140
141#define TARGET_VERSION_SENTINAL 0xffffffff 141#define TARGET_VERSION_SENTINAL 0xffffffff
142#define TARGET_TYPE_AR6003 3 142#define TARGET_TYPE_AR6003 3
143 143#define TARGET_TYPE_AR6004 5
144#define BMI_ROMPATCH_INSTALL 9 144#define BMI_ROMPATCH_INSTALL 9
145/* 145/*
146 * Semantics: Install a ROM Patch. 146 * Semantics: Install a ROM Patch.
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 14559ffb1453..8d9fbd4a62b7 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -17,6 +17,12 @@
17#include "core.h" 17#include "core.h"
18#include "cfg80211.h" 18#include "cfg80211.h"
19#include "debug.h" 19#include "debug.h"
20#include "hif-ops.h"
21#include "testmode.h"
22
23static unsigned int ath6kl_p2p;
24
25module_param(ath6kl_p2p, uint, 0644);
20 26
21#define RATETAB_ENT(_rate, _rateid, _flags) { \ 27#define RATETAB_ENT(_rate, _rateid, _flags) { \
22 .bitrate = (_rate), \ 28 .bitrate = (_rate), \
@@ -152,8 +158,7 @@ static int ath6kl_set_auth_type(struct ath6kl *ar,
152 break; 158 break;
153 159
154 case NL80211_AUTHTYPE_AUTOMATIC: 160 case NL80211_AUTHTYPE_AUTOMATIC:
155 ar->dot11_auth_mode = OPEN_AUTH; 161 ar->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
156 ar->auto_auth_stage = AUTH_OPEN_IN_PROGRESS;
157 break; 162 break;
158 163
159 default: 164 default:
@@ -167,7 +172,8 @@ static int ath6kl_set_auth_type(struct ath6kl *ar,
167static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast) 172static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast)
168{ 173{
169 u8 *ar_cipher = ucast ? &ar->prwise_crypto : &ar->grp_crypto; 174 u8 *ar_cipher = ucast ? &ar->prwise_crypto : &ar->grp_crypto;
170 u8 *ar_cipher_len = ucast ? &ar->prwise_crypto_len : &ar->grp_crpto_len; 175 u8 *ar_cipher_len = ucast ? &ar->prwise_crypto_len :
176 &ar->grp_crypto_len;
171 177
172 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n", 178 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
173 __func__, cipher, ucast); 179 __func__, cipher, ucast);
@@ -354,6 +360,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
354 } 360 }
355 361
356 if (!ar->usr_bss_filter) { 362 if (!ar->usr_bss_filter) {
363 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
357 if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) { 364 if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) {
358 ath6kl_err("couldn't set bss filtering\n"); 365 ath6kl_err("couldn't set bss filtering\n");
359 up(&ar->sem); 366 up(&ar->sem);
@@ -370,14 +377,14 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
370 __func__, 377 __func__,
371 ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto, 378 ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
372 ar->prwise_crypto_len, ar->grp_crypto, 379 ar->prwise_crypto_len, ar->grp_crypto,
373 ar->grp_crpto_len, ar->ch_hint); 380 ar->grp_crypto_len, ar->ch_hint);
374 381
375 ar->reconnect_flag = 0; 382 ar->reconnect_flag = 0;
376 status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type, 383 status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
377 ar->dot11_auth_mode, ar->auth_mode, 384 ar->dot11_auth_mode, ar->auth_mode,
378 ar->prwise_crypto, 385 ar->prwise_crypto,
379 ar->prwise_crypto_len, 386 ar->prwise_crypto_len,
380 ar->grp_crypto, ar->grp_crpto_len, 387 ar->grp_crypto, ar->grp_crypto_len,
381 ar->ssid_len, ar->ssid, 388 ar->ssid_len, ar->ssid,
382 ar->req_bssid, ar->ch_hint, 389 ar->req_bssid, ar->ch_hint,
383 ar->connect_ctrl_flags); 390 ar->connect_ctrl_flags);
@@ -407,6 +414,53 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
407 return 0; 414 return 0;
408} 415}
409 416
417static int ath6kl_add_bss_if_needed(struct ath6kl *ar, const u8 *bssid,
418 struct ieee80211_channel *chan,
419 const u8 *beacon_ie, size_t beacon_ie_len)
420{
421 struct cfg80211_bss *bss;
422 u8 *ie;
423
424 bss = cfg80211_get_bss(ar->wdev->wiphy, chan, bssid,
425 ar->ssid, ar->ssid_len, WLAN_CAPABILITY_ESS,
426 WLAN_CAPABILITY_ESS);
427 if (bss == NULL) {
428 /*
429 * Since cfg80211 may not yet know about the BSS,
430 * generate a partial entry until the first BSS info
431 * event becomes available.
432 *
433 * Prepend SSID element since it is not included in the Beacon
434 * IEs from the target.
435 */
436 ie = kmalloc(2 + ar->ssid_len + beacon_ie_len, GFP_KERNEL);
437 if (ie == NULL)
438 return -ENOMEM;
439 ie[0] = WLAN_EID_SSID;
440 ie[1] = ar->ssid_len;
441 memcpy(ie + 2, ar->ssid, ar->ssid_len);
442 memcpy(ie + 2 + ar->ssid_len, beacon_ie, beacon_ie_len);
443 bss = cfg80211_inform_bss(ar->wdev->wiphy, chan,
444 bssid, 0, WLAN_CAPABILITY_ESS, 100,
445 ie, 2 + ar->ssid_len + beacon_ie_len,
446 0, GFP_KERNEL);
447 if (bss)
448 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added dummy bss for "
449 "%pM prior to indicating connect/roamed "
450 "event\n", bssid);
451 kfree(ie);
452 } else
453 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss "
454 "entry\n");
455
456 if (bss == NULL)
457 return -ENOMEM;
458
459 cfg80211_put_bss(bss);
460
461 return 0;
462}
463
410void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel, 464void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
411 u8 *bssid, u16 listen_intvl, 465 u8 *bssid, u16 listen_intvl,
412 u16 beacon_intvl, 466 u16 beacon_intvl,
@@ -414,19 +468,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
414 u8 beacon_ie_len, u8 assoc_req_len, 468 u8 beacon_ie_len, u8 assoc_req_len,
415 u8 assoc_resp_len, u8 *assoc_info) 469 u8 assoc_resp_len, u8 *assoc_info)
416{ 470{
417 u16 size = 0; 471 struct ieee80211_channel *chan;
418 u16 capability = 0;
419 struct cfg80211_bss *bss = NULL;
420 struct ieee80211_mgmt *mgmt = NULL;
421 struct ieee80211_channel *ibss_ch = NULL;
422 s32 signal = 50 * 100;
423 u8 ie_buf_len = 0;
424 unsigned char ie_buf[256];
425 unsigned char *ptr_ie_buf = ie_buf;
426 unsigned char *ieeemgmtbuf = NULL;
427 u8 source_mac[ETH_ALEN];
428 u16 capa_mask;
429 u16 capa_val;
430 472
431 /* capinfo + listen interval */ 473 /* capinfo + listen interval */
432 u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16); 474 u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
@@ -441,7 +483,12 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
441 assoc_req_len -= assoc_req_ie_offset; 483 assoc_req_len -= assoc_req_ie_offset;
442 assoc_resp_len -= assoc_resp_ie_offset; 484 assoc_resp_len -= assoc_resp_ie_offset;
443 485
444 ar->auto_auth_stage = AUTH_IDLE; 486 /*
487 * Store Beacon interval here; DTIM period will be available only once
488 * a Beacon frame from the AP is seen.
489 */
490 ar->assoc_bss_beacon_int = beacon_intvl;
491 clear_bit(DTIM_PERIOD_AVAIL, &ar->flag);
445 492
446 if (nw_type & ADHOC_NETWORK) { 493 if (nw_type & ADHOC_NETWORK) {
447 if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) { 494 if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
@@ -452,110 +499,26 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
452 } 499 }
453 500
454 if (nw_type & INFRA_NETWORK) { 501 if (nw_type & INFRA_NETWORK) {
455 if (ar->wdev->iftype != NL80211_IFTYPE_STATION) { 502 if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
503 ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
456 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, 504 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
457 "%s: ath6k not in station mode\n", __func__); 505 "%s: ath6k not in station mode\n", __func__);
458 return; 506 return;
459 } 507 }
460 } 508 }
461 509
462 if (nw_type & ADHOC_NETWORK) { 510 chan = ieee80211_get_channel(ar->wdev->wiphy, (int) channel);
463 capa_mask = WLAN_CAPABILITY_IBSS;
464 capa_val = WLAN_CAPABILITY_IBSS;
465 } else {
466 capa_mask = WLAN_CAPABILITY_ESS;
467 capa_val = WLAN_CAPABILITY_ESS;
468 }
469 511
470 /* Before informing the join/connect event, make sure that
471 * bss entry is present in scan list, if it not present
472 * construct and insert into scan list, otherwise that
473 * event will be dropped on the way by cfg80211, due to
474 * this keys will not be plumbed in case of WEP and
475 * application will not be aware of join/connect status. */
476 bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid,
477 ar->wdev->ssid, ar->wdev->ssid_len,
478 capa_mask, capa_val);
479
480 /*
481 * Earlier we were updating the cfg about bss by making a beacon frame
482 * only if the entry for bss is not there. This can have some issue if
483 * ROAM event is generated and a heavy traffic is ongoing. The ROAM
484 * event is handled through a work queue and by the time it really gets
485 * handled, BSS would have been aged out. So it is better to update the
486 * cfg about BSS irrespective of its entry being present right now or
487 * not.
488 */
489 512
490 if (nw_type & ADHOC_NETWORK) { 513 if (nw_type & ADHOC_NETWORK) {
491 /* construct 802.11 mgmt beacon */ 514 cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
492 if (ptr_ie_buf) {
493 *ptr_ie_buf++ = WLAN_EID_SSID;
494 *ptr_ie_buf++ = ar->ssid_len;
495 memcpy(ptr_ie_buf, ar->ssid, ar->ssid_len);
496 ptr_ie_buf += ar->ssid_len;
497
498 *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
499 *ptr_ie_buf++ = 2; /* length */
500 *ptr_ie_buf++ = 0; /* ATIM window */
501 *ptr_ie_buf++ = 0; /* ATIM window */
502
503 /* TODO: update ibss params and include supported rates,
504 * DS param set, extened support rates, wmm. */
505
506 ie_buf_len = ptr_ie_buf - ie_buf;
507 }
508
509 capability |= WLAN_CAPABILITY_IBSS;
510
511 if (ar->prwise_crypto == WEP_CRYPT)
512 capability |= WLAN_CAPABILITY_PRIVACY;
513
514 memcpy(source_mac, ar->net_dev->dev_addr, ETH_ALEN);
515 ptr_ie_buf = ie_buf;
516 } else {
517 capability = *(u16 *) (&assoc_info[beacon_ie_len]);
518 memcpy(source_mac, bssid, ETH_ALEN);
519 ptr_ie_buf = assoc_req_ie;
520 ie_buf_len = assoc_req_len;
521 }
522
523 size = offsetof(struct ieee80211_mgmt, u)
524 + sizeof(mgmt->u.beacon)
525 + ie_buf_len;
526
527 ieeemgmtbuf = kzalloc(size, GFP_ATOMIC);
528 if (!ieeemgmtbuf) {
529 ath6kl_err("ieee mgmt buf alloc error\n");
530 cfg80211_put_bss(bss);
531 return; 515 return;
532 } 516 }
533 517
534 mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf; 518 if (ath6kl_add_bss_if_needed(ar, bssid, chan, assoc_info,
535 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 519 beacon_ie_len) < 0) {
536 IEEE80211_STYPE_BEACON); 520 ath6kl_err("could not add cfg80211 bss entry for "
537 memset(mgmt->da, 0xff, ETH_ALEN); /* broadcast addr */ 521 "connect/roamed notification\n");
538 memcpy(mgmt->sa, source_mac, ETH_ALEN);
539 memcpy(mgmt->bssid, bssid, ETH_ALEN);
540 mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_intvl);
541 mgmt->u.beacon.capab_info = cpu_to_le16(capability);
542 memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
543
544 ibss_ch = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
545
546 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
547 "%s: inform bss with bssid %pM channel %d beacon_intvl %d capability 0x%x\n",
548 __func__, mgmt->bssid, ibss_ch->hw_value,
549 beacon_intvl, capability);
550
551 bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
552 ibss_ch, mgmt,
553 size, signal, GFP_KERNEL);
554 kfree(ieeemgmtbuf);
555 cfg80211_put_bss(bss);
556
557 if (nw_type & ADHOC_NETWORK) {
558 cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
559 return; 522 return;
560 } 523 }
561 524
@@ -568,7 +531,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
568 WLAN_STATUS_SUCCESS, GFP_KERNEL); 531 WLAN_STATUS_SUCCESS, GFP_KERNEL);
569 } else if (ar->sme_state == SME_CONNECTED) { 532 } else if (ar->sme_state == SME_CONNECTED) {
570 /* inform roam event to cfg80211 */ 533 /* inform roam event to cfg80211 */
571 cfg80211_roamed(ar->net_dev, ibss_ch, bssid, 534 cfg80211_roamed(ar->net_dev, chan, bssid,
572 assoc_req_ie, assoc_req_len, 535 assoc_req_ie, assoc_req_len,
573 assoc_resp_ie, assoc_resp_len, GFP_KERNEL); 536 assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
574 } 537 }
@@ -605,6 +568,8 @@ static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
605 568
606 up(&ar->sem); 569 up(&ar->sem);
607 570
571 ar->sme_state = SME_DISCONNECTED;
572
608 return 0; 573 return 0;
609} 574}
610 575
@@ -612,9 +577,6 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
612 u8 *bssid, u8 assoc_resp_len, 577 u8 *bssid, u8 assoc_resp_len,
613 u8 *assoc_info, u16 proto_reason) 578 u8 *assoc_info, u16 proto_reason)
614{ 579{
615 struct ath6kl_key *key = NULL;
616 u16 status;
617
618 if (ar->scan_req) { 580 if (ar->scan_req) {
619 cfg80211_scan_done(ar->scan_req, true); 581 cfg80211_scan_done(ar->scan_req, true);
620 ar->scan_req = NULL; 582 ar->scan_req = NULL;
@@ -632,164 +594,64 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
632 } 594 }
633 595
634 if (ar->nw_type & INFRA_NETWORK) { 596 if (ar->nw_type & INFRA_NETWORK) {
635 if (ar->wdev->iftype != NL80211_IFTYPE_STATION) { 597 if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
598 ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
636 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, 599 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
637 "%s: ath6k not in station mode\n", __func__); 600 "%s: ath6k not in station mode\n", __func__);
638 return; 601 return;
639 } 602 }
640 } 603 }
641 604
642 if (!test_bit(CONNECT_PEND, &ar->flag)) {
643 if (reason != DISCONNECT_CMD)
644 ath6kl_wmi_disconnect_cmd(ar->wmi);
645
646 return;
647 }
648
649 if (reason == NO_NETWORK_AVAIL) {
650 /* connect cmd failed */
651 ath6kl_wmi_disconnect_cmd(ar->wmi);
652 return;
653 }
654
655 if (reason != DISCONNECT_CMD)
656 return;
657
658 if (!ar->auto_auth_stage) {
659 clear_bit(CONNECT_PEND, &ar->flag);
660
661 if (ar->sme_state == SME_CONNECTING) {
662 cfg80211_connect_result(ar->net_dev,
663 bssid, NULL, 0,
664 NULL, 0,
665 WLAN_STATUS_UNSPECIFIED_FAILURE,
666 GFP_KERNEL);
667 } else {
668 cfg80211_disconnected(ar->net_dev, reason,
669 NULL, 0, GFP_KERNEL);
670 }
671
672 ar->sme_state = SME_DISCONNECTED;
673 return;
674 }
675
676 if (ar->dot11_auth_mode != OPEN_AUTH)
677 return;
678
679 /* 605 /*
680 * If the current auth algorithm is open, try shared and 606 * Send a disconnect command to target when a disconnect event is
681 * make autoAuthStage idle. We do not make it leap for now 607 * received with reason code other than 3 (DISCONNECT_CMD - disconnect
682 * being. 608 * request from host) to make the firmware stop trying to connect even
609 * after giving disconnect event. There will be one more disconnect
610 * event for this disconnect command with reason code DISCONNECT_CMD
611 * which will be notified to cfg80211.
683 */ 612 */
684 key = &ar->keys[ar->def_txkey_index];
685 if (down_interruptible(&ar->sem)) {
686 ath6kl_err("busy, couldn't get access\n");
687 return;
688 }
689
690 ar->dot11_auth_mode = SHARED_AUTH;
691 ar->auto_auth_stage = AUTH_IDLE;
692 613
693 ath6kl_wmi_addkey_cmd(ar->wmi, 614 if (reason != DISCONNECT_CMD) {
694 ar->def_txkey_index, 615 ath6kl_wmi_disconnect_cmd(ar->wmi);
695 ar->prwise_crypto,
696 GROUP_USAGE | TX_USAGE,
697 key->key_len, NULL,
698 key->key,
699 KEY_OP_INIT_VAL, NULL,
700 NO_SYNC_WMIFLAG);
701
702 status = ath6kl_wmi_connect_cmd(ar->wmi,
703 ar->nw_type,
704 ar->dot11_auth_mode,
705 ar->auth_mode,
706 ar->prwise_crypto,
707 ar->prwise_crypto_len,
708 ar->grp_crypto,
709 ar->grp_crpto_len,
710 ar->ssid_len,
711 ar->ssid,
712 ar->req_bssid,
713 ar->ch_hint,
714 ar->connect_ctrl_flags);
715 up(&ar->sem);
716}
717
718static inline bool is_ch_11a(u16 ch)
719{
720 return (!((ch >= 2412) && (ch <= 2484)));
721}
722
723/* struct ath6kl_node_table::nt_nodelock is locked when calling this */
724void ath6kl_cfg80211_scan_node(struct wiphy *wiphy, struct bss *ni)
725{
726 u16 size;
727 unsigned char *ieeemgmtbuf = NULL;
728 struct ieee80211_mgmt *mgmt;
729 struct ieee80211_channel *channel;
730 struct ieee80211_supported_band *band;
731 struct ath6kl_common_ie *cie;
732 s32 signal;
733 int freq;
734
735 cie = &ni->ni_cie;
736
737 if (is_ch_11a(cie->ie_chan))
738 band = wiphy->bands[IEEE80211_BAND_5GHZ]; /* 11a */
739 else if ((cie->ie_erp) || (cie->ie_xrates))
740 band = wiphy->bands[IEEE80211_BAND_2GHZ]; /* 11g */
741 else
742 band = wiphy->bands[IEEE80211_BAND_2GHZ]; /* 11b */
743
744 size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
745 ieeemgmtbuf = kmalloc(size, GFP_ATOMIC);
746 if (!ieeemgmtbuf) {
747 ath6kl_err("ieee mgmt buf alloc error\n");
748 return; 616 return;
749 } 617 }
750 618
751 /* 619 clear_bit(CONNECT_PEND, &ar->flag);
752 * TODO: Update target to include 802.11 mac header while sending
753 * bss info. Target removes 802.11 mac header while sending the bss
754 * info to host, cfg80211 needs it, for time being just filling the
755 * da, sa and bssid fields alone.
756 */
757 mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
758 memset(mgmt->da, 0xff, ETH_ALEN); /*broadcast addr */
759 memcpy(mgmt->sa, ni->ni_macaddr, ETH_ALEN);
760 memcpy(mgmt->bssid, ni->ni_macaddr, ETH_ALEN);
761 memcpy(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
762 ni->ni_buf, ni->ni_framelen);
763
764 freq = cie->ie_chan;
765 channel = ieee80211_get_channel(wiphy, freq);
766 signal = ni->ni_snr * 100;
767 620
768 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, 621 if (ar->sme_state == SME_CONNECTING) {
769 "%s: bssid %pM ch %d freq %d size %d\n", __func__, 622 cfg80211_connect_result(ar->net_dev,
770 mgmt->bssid, channel->hw_value, freq, size); 623 bssid, NULL, 0,
771 cfg80211_inform_bss_frame(wiphy, channel, mgmt, 624 NULL, 0,
772 size, signal, GFP_ATOMIC); 625 WLAN_STATUS_UNSPECIFIED_FAILURE,
626 GFP_KERNEL);
627 } else if (ar->sme_state == SME_CONNECTED) {
628 cfg80211_disconnected(ar->net_dev, reason,
629 NULL, 0, GFP_KERNEL);
630 }
773 631
774 kfree(ieeemgmtbuf); 632 ar->sme_state = SME_DISCONNECTED;
775} 633}
776 634
777static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, 635static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
778 struct cfg80211_scan_request *request) 636 struct cfg80211_scan_request *request)
779{ 637{
780 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev); 638 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
639 s8 n_channels = 0;
640 u16 *channels = NULL;
781 int ret = 0; 641 int ret = 0;
782 642
783 if (!ath6kl_cfg80211_ready(ar)) 643 if (!ath6kl_cfg80211_ready(ar))
784 return -EIO; 644 return -EIO;
785 645
786 if (!ar->usr_bss_filter) { 646 if (!ar->usr_bss_filter) {
787 if (ath6kl_wmi_bssfilter_cmd(ar->wmi, 647 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
788 (test_bit(CONNECTED, &ar->flag) ? 648 ret = ath6kl_wmi_bssfilter_cmd(
789 ALL_BUT_BSS_FILTER : 649 ar->wmi,
790 ALL_BSS_FILTER), 0) != 0) { 650 (test_bit(CONNECTED, &ar->flag) ?
651 ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
652 if (ret) {
791 ath6kl_err("couldn't set bss filtering\n"); 653 ath6kl_err("couldn't set bss filtering\n");
792 return -EIO; 654 return ret;
793 } 655 }
794 } 656 }
795 657
@@ -806,13 +668,46 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
806 request->ssids[i].ssid); 668 request->ssids[i].ssid);
807 } 669 }
808 670
809 if (ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, 0, 671 if (request->ie) {
810 false, 0, 0, 0, NULL) != 0) { 672 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_REQ,
811 ath6kl_err("wmi_startscan_cmd failed\n"); 673 request->ie, request->ie_len);
812 ret = -EIO; 674 if (ret) {
675 ath6kl_err("failed to set Probe Request appie for "
676 "scan");
677 return ret;
678 }
813 } 679 }
814 680
815 ar->scan_req = request; 681 /*
682 * Scan only the requested channels if the request specifies a set of
683 * channels. If the list is longer than the target supports, do not
684 * configure the list and instead, scan all available channels.
685 */
686 if (request->n_channels > 0 &&
687 request->n_channels <= WMI_MAX_CHANNELS) {
688 u8 i;
689
690 n_channels = request->n_channels;
691
692 channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
693 if (channels == NULL) {
694 ath6kl_warn("failed to set scan channels, "
695 "scan all channels");
696 n_channels = 0;
697 }
698
699 for (i = 0; i < n_channels; i++)
700 channels[i] = request->channels[i]->center_freq;
701 }
702
703 ret = ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, 0,
704 false, 0, 0, n_channels, channels);
705 if (ret)
706 ath6kl_err("wmi_startscan_cmd failed\n");
707 else
708 ar->scan_req = request;
709
710 kfree(channels);
816 711
817 return ret; 712 return ret;
818} 713}
@@ -831,9 +726,6 @@ void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)
831 goto out; 726 goto out;
832 } 727 }
833 728
834 /* Translate data to cfg80211 mgmt format */
835 wlan_iterate_nodes(&ar->scan_table, ar->wdev->wiphy);
836
837 cfg80211_scan_done(ar->scan_req, false); 729 cfg80211_scan_done(ar->scan_req, false);
838 730
839 if (ar->scan_req->n_ssids && ar->scan_req->ssids[0].ssid_len) { 731 if (ar->scan_req->n_ssids && ar->scan_req->ssids[0].ssid_len) {
@@ -918,6 +810,40 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
918 key_usage, key->seq_len); 810 key_usage, key->seq_len);
919 811
920 ar->def_txkey_index = key_index; 812 ar->def_txkey_index = key_index;
813
814 if (ar->nw_type == AP_NETWORK && !pairwise &&
815 (key_type == TKIP_CRYPT || key_type == AES_CRYPT) && params) {
816 ar->ap_mode_bkey.valid = true;
817 ar->ap_mode_bkey.key_index = key_index;
818 ar->ap_mode_bkey.key_type = key_type;
819 ar->ap_mode_bkey.key_len = key->key_len;
820 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
821 if (!test_bit(CONNECTED, &ar->flag)) {
822 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
823 "key configuration until AP mode has been "
824 "started\n");
825 /*
826 * The key will be set in ath6kl_connect_ap_mode() once
827 * the connected event is received from the target.
828 */
829 return 0;
830 }
831 }
832
833 if (ar->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
834 !test_bit(CONNECTED, &ar->flag)) {
835 /*
836 * Store the key locally so that it can be re-configured after
837 * the AP mode has properly started
838 * (ath6kl_install_statioc_wep_keys).
839 */
840 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration "
841 "until AP mode has been started\n");
842 ar->wep_key_list[key_index].key_len = key->key_len;
843 memcpy(ar->wep_key_list[key_index].key, key->key, key->key_len);
844 return 0;
845 }
846
921 status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index, 847 status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
922 key_type, key_usage, key->key_len, 848 key_type, key_usage, key->key_len,
923 key->seq, key->key, KEY_OP_INIT_VAL, 849 key->seq, key->key, KEY_OP_INIT_VAL,
@@ -1002,6 +928,7 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1002 struct ath6kl_key *key = NULL; 928 struct ath6kl_key *key = NULL;
1003 int status = 0; 929 int status = 0;
1004 u8 key_usage; 930 u8 key_usage;
931 enum crypto_type key_type = NONE_CRYPT;
1005 932
1006 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index); 933 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1007 934
@@ -1026,9 +953,16 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1026 key_usage = GROUP_USAGE; 953 key_usage = GROUP_USAGE;
1027 if (ar->prwise_crypto == WEP_CRYPT) 954 if (ar->prwise_crypto == WEP_CRYPT)
1028 key_usage |= TX_USAGE; 955 key_usage |= TX_USAGE;
956 if (unicast)
957 key_type = ar->prwise_crypto;
958 if (multicast)
959 key_type = ar->grp_crypto;
960
961 if (ar->next_mode == AP_NETWORK && !test_bit(CONNECTED, &ar->flag))
962 return 0; /* Delay until AP mode has been started */
1029 963
1030 status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index, 964 status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
1031 ar->prwise_crypto, key_usage, 965 key_type, key_usage,
1032 key->key_len, key->seq, key->key, 966 key->key_len, key->seq, key->key,
1033 KEY_OP_INIT_VAL, NULL, 967 KEY_OP_INIT_VAL, NULL,
1034 SYNC_BOTH_WMIFLAG); 968 SYNC_BOTH_WMIFLAG);
@@ -1183,6 +1117,15 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1183 case NL80211_IFTYPE_ADHOC: 1117 case NL80211_IFTYPE_ADHOC:
1184 ar->next_mode = ADHOC_NETWORK; 1118 ar->next_mode = ADHOC_NETWORK;
1185 break; 1119 break;
1120 case NL80211_IFTYPE_AP:
1121 ar->next_mode = AP_NETWORK;
1122 break;
1123 case NL80211_IFTYPE_P2P_CLIENT:
1124 ar->next_mode = INFRA_NETWORK;
1125 break;
1126 case NL80211_IFTYPE_P2P_GO:
1127 ar->next_mode = AP_NETWORK;
1128 break;
1186 default: 1129 default:
1187 ath6kl_err("invalid interface type %u\n", type); 1130 ath6kl_err("invalid interface type %u\n", type);
1188 return -EOPNOTSUPP; 1131 return -EOPNOTSUPP;
@@ -1246,13 +1189,13 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1246 __func__, 1189 __func__,
1247 ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto, 1190 ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
1248 ar->prwise_crypto_len, ar->grp_crypto, 1191 ar->prwise_crypto_len, ar->grp_crypto,
1249 ar->grp_crpto_len, ar->ch_hint); 1192 ar->grp_crypto_len, ar->ch_hint);
1250 1193
1251 status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type, 1194 status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
1252 ar->dot11_auth_mode, ar->auth_mode, 1195 ar->dot11_auth_mode, ar->auth_mode,
1253 ar->prwise_crypto, 1196 ar->prwise_crypto,
1254 ar->prwise_crypto_len, 1197 ar->prwise_crypto_len,
1255 ar->grp_crypto, ar->grp_crpto_len, 1198 ar->grp_crypto, ar->grp_crypto_len,
1256 ar->ssid_len, ar->ssid, 1199 ar->ssid_len, ar->ssid,
1257 ar->req_bssid, ar->ch_hint, 1200 ar->req_bssid, ar->ch_hint,
1258 ar->connect_ctrl_flags); 1201 ar->connect_ctrl_flags);
@@ -1422,12 +1365,23 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1422 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 1365 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1423 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; 1366 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1424 } else { 1367 } else {
1425 ath6kl_warn("invalid rate: %d\n", rate); 1368 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1369 "invalid rate from stats: %d\n", rate);
1370 ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1426 return 0; 1371 return 0;
1427 } 1372 }
1428 1373
1429 sinfo->filled |= STATION_INFO_TX_BITRATE; 1374 sinfo->filled |= STATION_INFO_TX_BITRATE;
1430 1375
1376 if (test_bit(CONNECTED, &ar->flag) &&
1377 test_bit(DTIM_PERIOD_AVAIL, &ar->flag) &&
1378 ar->nw_type == INFRA_NETWORK) {
1379 sinfo->filled |= STATION_INFO_BSS_PARAM;
1380 sinfo->bss_param.flags = 0;
1381 sinfo->bss_param.dtim_period = ar->assoc_bss_dtim_period;
1382 sinfo->bss_param.beacon_interval = ar->assoc_bss_beacon_int;
1383 }
1384
1431 return 0; 1385 return 0;
1432} 1386}
1433 1387
@@ -1455,6 +1409,402 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1455 return 0; 1409 return 0;
1456} 1410}
1457 1411
1412#ifdef CONFIG_PM
1413static int ar6k_cfg80211_suspend(struct wiphy *wiphy,
1414 struct cfg80211_wowlan *wow)
1415{
1416 struct ath6kl *ar = wiphy_priv(wiphy);
1417
1418 return ath6kl_hif_suspend(ar);
1419}
1420#endif
1421
1422static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
1423 struct ieee80211_channel *chan,
1424 enum nl80211_channel_type channel_type)
1425{
1426 struct ath6kl *ar = ath6kl_priv(dev);
1427
1428 if (!ath6kl_cfg80211_ready(ar))
1429 return -EIO;
1430
1431 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
1432 __func__, chan->center_freq, chan->hw_value);
1433 ar->next_chan = chan->center_freq;
1434
1435 return 0;
1436}
1437
1438static bool ath6kl_is_p2p_ie(const u8 *pos)
1439{
1440 return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1441 pos[2] == 0x50 && pos[3] == 0x6f &&
1442 pos[4] == 0x9a && pos[5] == 0x09;
1443}
1444
1445static int ath6kl_set_ap_probe_resp_ies(struct ath6kl *ar, const u8 *ies,
1446 size_t ies_len)
1447{
1448 const u8 *pos;
1449 u8 *buf = NULL;
1450 size_t len = 0;
1451 int ret;
1452
1453 /*
1454 * Filter out P2P IE(s) since they will be included depending on
1455 * the Probe Request frame in ath6kl_send_go_probe_resp().
1456 */
1457
1458 if (ies && ies_len) {
1459 buf = kmalloc(ies_len, GFP_KERNEL);
1460 if (buf == NULL)
1461 return -ENOMEM;
1462 pos = ies;
1463 while (pos + 1 < ies + ies_len) {
1464 if (pos + 2 + pos[1] > ies + ies_len)
1465 break;
1466 if (!ath6kl_is_p2p_ie(pos)) {
1467 memcpy(buf + len, pos, 2 + pos[1]);
1468 len += 2 + pos[1];
1469 }
1470 pos += 2 + pos[1];
1471 }
1472 }
1473
1474 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_RESP,
1475 buf, len);
1476 kfree(buf);
1477 return ret;
1478}
1479
1480static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
1481 struct beacon_parameters *info, bool add)
1482{
1483 struct ath6kl *ar = ath6kl_priv(dev);
1484 struct ieee80211_mgmt *mgmt;
1485 u8 *ies;
1486 int ies_len;
1487 struct wmi_connect_cmd p;
1488 int res;
1489 int i;
1490
1491 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add);
1492
1493 if (!ath6kl_cfg80211_ready(ar))
1494 return -EIO;
1495
1496 if (ar->next_mode != AP_NETWORK)
1497 return -EOPNOTSUPP;
1498
1499 if (info->beacon_ies) {
1500 res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_BEACON,
1501 info->beacon_ies,
1502 info->beacon_ies_len);
1503 if (res)
1504 return res;
1505 }
1506 if (info->proberesp_ies) {
1507 res = ath6kl_set_ap_probe_resp_ies(ar, info->proberesp_ies,
1508 info->proberesp_ies_len);
1509 if (res)
1510 return res;
1511 }
1512 if (info->assocresp_ies) {
1513 res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_ASSOC_RESP,
1514 info->assocresp_ies,
1515 info->assocresp_ies_len);
1516 if (res)
1517 return res;
1518 }
1519
1520 if (!add)
1521 return 0;
1522
1523 ar->ap_mode_bkey.valid = false;
1524
1525 /* TODO:
1526 * info->interval
1527 * info->dtim_period
1528 */
1529
1530 if (info->head == NULL)
1531 return -EINVAL;
1532 mgmt = (struct ieee80211_mgmt *) info->head;
1533 ies = mgmt->u.beacon.variable;
1534 if (ies > info->head + info->head_len)
1535 return -EINVAL;
1536 ies_len = info->head + info->head_len - ies;
1537
1538 if (info->ssid == NULL)
1539 return -EINVAL;
1540 memcpy(ar->ssid, info->ssid, info->ssid_len);
1541 ar->ssid_len = info->ssid_len;
1542 if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1543 return -EOPNOTSUPP; /* TODO */
1544
1545 ar->dot11_auth_mode = OPEN_AUTH;
1546
1547 memset(&p, 0, sizeof(p));
1548
1549 for (i = 0; i < info->crypto.n_akm_suites; i++) {
1550 switch (info->crypto.akm_suites[i]) {
1551 case WLAN_AKM_SUITE_8021X:
1552 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1553 p.auth_mode |= WPA_AUTH;
1554 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1555 p.auth_mode |= WPA2_AUTH;
1556 break;
1557 case WLAN_AKM_SUITE_PSK:
1558 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1559 p.auth_mode |= WPA_PSK_AUTH;
1560 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1561 p.auth_mode |= WPA2_PSK_AUTH;
1562 break;
1563 }
1564 }
1565 if (p.auth_mode == 0)
1566 p.auth_mode = NONE_AUTH;
1567 ar->auth_mode = p.auth_mode;
1568
1569 for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
1570 switch (info->crypto.ciphers_pairwise[i]) {
1571 case WLAN_CIPHER_SUITE_WEP40:
1572 case WLAN_CIPHER_SUITE_WEP104:
1573 p.prwise_crypto_type |= WEP_CRYPT;
1574 break;
1575 case WLAN_CIPHER_SUITE_TKIP:
1576 p.prwise_crypto_type |= TKIP_CRYPT;
1577 break;
1578 case WLAN_CIPHER_SUITE_CCMP:
1579 p.prwise_crypto_type |= AES_CRYPT;
1580 break;
1581 }
1582 }
1583 if (p.prwise_crypto_type == 0) {
1584 p.prwise_crypto_type = NONE_CRYPT;
1585 ath6kl_set_cipher(ar, 0, true);
1586 } else if (info->crypto.n_ciphers_pairwise == 1)
1587 ath6kl_set_cipher(ar, info->crypto.ciphers_pairwise[0], true);
1588
1589 switch (info->crypto.cipher_group) {
1590 case WLAN_CIPHER_SUITE_WEP40:
1591 case WLAN_CIPHER_SUITE_WEP104:
1592 p.grp_crypto_type = WEP_CRYPT;
1593 break;
1594 case WLAN_CIPHER_SUITE_TKIP:
1595 p.grp_crypto_type = TKIP_CRYPT;
1596 break;
1597 case WLAN_CIPHER_SUITE_CCMP:
1598 p.grp_crypto_type = AES_CRYPT;
1599 break;
1600 default:
1601 p.grp_crypto_type = NONE_CRYPT;
1602 break;
1603 }
1604 ath6kl_set_cipher(ar, info->crypto.cipher_group, false);
1605
1606 p.nw_type = AP_NETWORK;
1607 ar->nw_type = ar->next_mode;
1608
1609 p.ssid_len = ar->ssid_len;
1610 memcpy(p.ssid, ar->ssid, ar->ssid_len);
1611 p.dot11_auth_mode = ar->dot11_auth_mode;
1612 p.ch = cpu_to_le16(ar->next_chan);
1613
1614 res = ath6kl_wmi_ap_profile_commit(ar->wmi, &p);
1615 if (res < 0)
1616 return res;
1617
1618 return 0;
1619}
1620
1621static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev,
1622 struct beacon_parameters *info)
1623{
1624 return ath6kl_ap_beacon(wiphy, dev, info, true);
1625}
1626
1627static int ath6kl_set_beacon(struct wiphy *wiphy, struct net_device *dev,
1628 struct beacon_parameters *info)
1629{
1630 return ath6kl_ap_beacon(wiphy, dev, info, false);
1631}
1632
1633static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
1634{
1635 struct ath6kl *ar = ath6kl_priv(dev);
1636
1637 if (ar->nw_type != AP_NETWORK)
1638 return -EOPNOTSUPP;
1639 if (!test_bit(CONNECTED, &ar->flag))
1640 return -ENOTCONN;
1641
1642 ath6kl_wmi_disconnect_cmd(ar->wmi);
1643 clear_bit(CONNECTED, &ar->flag);
1644
1645 return 0;
1646}
1647
1648static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
1649 u8 *mac, struct station_parameters *params)
1650{
1651 struct ath6kl *ar = ath6kl_priv(dev);
1652
1653 if (ar->nw_type != AP_NETWORK)
1654 return -EOPNOTSUPP;
1655
1656 /* Use this only for authorizing/unauthorizing a station */
1657 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
1658 return -EOPNOTSUPP;
1659
1660 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
1661 return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_AUTHORIZE,
1662 mac, 0);
1663 return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_UNAUTHORIZE, mac,
1664 0);
1665}
1666
1667static int ath6kl_remain_on_channel(struct wiphy *wiphy,
1668 struct net_device *dev,
1669 struct ieee80211_channel *chan,
1670 enum nl80211_channel_type channel_type,
1671 unsigned int duration,
1672 u64 *cookie)
1673{
1674 struct ath6kl *ar = ath6kl_priv(dev);
1675
1676 /* TODO: if already pending or ongoing remain-on-channel,
1677 * return -EBUSY */
1678 *cookie = 1; /* only a single pending request is supported */
1679
1680 return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, chan->center_freq,
1681 duration);
1682}
1683
1684static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
1685 struct net_device *dev,
1686 u64 cookie)
1687{
1688 struct ath6kl *ar = ath6kl_priv(dev);
1689
1690 if (cookie != 1)
1691 return -ENOENT;
1692
1693 return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi);
1694}
1695
1696static int ath6kl_send_go_probe_resp(struct ath6kl *ar, const u8 *buf,
1697 size_t len, unsigned int freq)
1698{
1699 const u8 *pos;
1700 u8 *p2p;
1701 int p2p_len;
1702 int ret;
1703 const struct ieee80211_mgmt *mgmt;
1704
1705 mgmt = (const struct ieee80211_mgmt *) buf;
1706
1707 /* Include P2P IE(s) from the frame generated in user space. */
1708
1709 p2p = kmalloc(len, GFP_KERNEL);
1710 if (p2p == NULL)
1711 return -ENOMEM;
1712 p2p_len = 0;
1713
1714 pos = mgmt->u.probe_resp.variable;
1715 while (pos + 1 < buf + len) {
1716 if (pos + 2 + pos[1] > buf + len)
1717 break;
1718 if (ath6kl_is_p2p_ie(pos)) {
1719 memcpy(p2p + p2p_len, pos, 2 + pos[1]);
1720 p2p_len += 2 + pos[1];
1721 }
1722 pos += 2 + pos[1];
1723 }
1724
1725 ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, freq, mgmt->da,
1726 p2p, p2p_len);
1727 kfree(p2p);
1728 return ret;
1729}
1730
1731static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1732 struct ieee80211_channel *chan, bool offchan,
1733 enum nl80211_channel_type channel_type,
1734 bool channel_type_valid, unsigned int wait,
1735 const u8 *buf, size_t len, u64 *cookie)
1736{
1737 struct ath6kl *ar = ath6kl_priv(dev);
1738 u32 id;
1739 const struct ieee80211_mgmt *mgmt;
1740
1741 mgmt = (const struct ieee80211_mgmt *) buf;
1742 if (buf + len >= mgmt->u.probe_resp.variable &&
1743 ar->nw_type == AP_NETWORK && test_bit(CONNECTED, &ar->flag) &&
1744 ieee80211_is_probe_resp(mgmt->frame_control)) {
1745 /*
1746 * Send Probe Response frame in AP mode using a separate WMI
1747 * command to allow the target to fill in the generic IEs.
1748 */
1749 *cookie = 0; /* TX status not supported */
1750 return ath6kl_send_go_probe_resp(ar, buf, len,
1751 chan->center_freq);
1752 }
1753
1754 id = ar->send_action_id++;
1755 if (id == 0) {
1756 /*
1757 * 0 is a reserved value in the WMI command and shall not be
1758 * used for the command.
1759 */
1760 id = ar->send_action_id++;
1761 }
1762
1763 *cookie = id;
1764 return ath6kl_wmi_send_action_cmd(ar->wmi, id, chan->center_freq, wait,
1765 buf, len);
1766}
1767
1768static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
1769 struct net_device *dev,
1770 u16 frame_type, bool reg)
1771{
1772 struct ath6kl *ar = ath6kl_priv(dev);
1773
1774 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
1775 __func__, frame_type, reg);
1776 if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
1777 /*
1778 * Note: This notification callback is not allowed to sleep, so
1779 * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
1780 * hardcode target to report Probe Request frames all the time.
1781 */
1782 ar->probe_req_report = reg;
1783 }
1784}
1785
1786static const struct ieee80211_txrx_stypes
1787ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
1788 [NL80211_IFTYPE_STATION] = {
1789 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1790 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1791 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1792 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1793 },
1794 [NL80211_IFTYPE_P2P_CLIENT] = {
1795 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1796 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1797 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1798 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1799 },
1800 [NL80211_IFTYPE_P2P_GO] = {
1801 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1802 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1803 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1804 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1805 },
1806};
1807
1458static struct cfg80211_ops ath6kl_cfg80211_ops = { 1808static struct cfg80211_ops ath6kl_cfg80211_ops = {
1459 .change_virtual_intf = ath6kl_cfg80211_change_iface, 1809 .change_virtual_intf = ath6kl_cfg80211_change_iface,
1460 .scan = ath6kl_cfg80211_scan, 1810 .scan = ath6kl_cfg80211_scan,
@@ -1474,12 +1824,26 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
1474 .set_pmksa = ath6kl_set_pmksa, 1824 .set_pmksa = ath6kl_set_pmksa,
1475 .del_pmksa = ath6kl_del_pmksa, 1825 .del_pmksa = ath6kl_del_pmksa,
1476 .flush_pmksa = ath6kl_flush_pmksa, 1826 .flush_pmksa = ath6kl_flush_pmksa,
1827 CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
1828#ifdef CONFIG_PM
1829 .suspend = ar6k_cfg80211_suspend,
1830#endif
1831 .set_channel = ath6kl_set_channel,
1832 .add_beacon = ath6kl_add_beacon,
1833 .set_beacon = ath6kl_set_beacon,
1834 .del_beacon = ath6kl_del_beacon,
1835 .change_station = ath6kl_change_station,
1836 .remain_on_channel = ath6kl_remain_on_channel,
1837 .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
1838 .mgmt_tx = ath6kl_mgmt_tx,
1839 .mgmt_frame_register = ath6kl_mgmt_frame_register,
1477}; 1840};
1478 1841
1479struct wireless_dev *ath6kl_cfg80211_init(struct device *dev) 1842struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
1480{ 1843{
1481 int ret = 0; 1844 int ret = 0;
1482 struct wireless_dev *wdev; 1845 struct wireless_dev *wdev;
1846 struct ath6kl *ar;
1483 1847
1484 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 1848 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1485 if (!wdev) { 1849 if (!wdev) {
@@ -1495,13 +1859,25 @@ struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
1495 return NULL; 1859 return NULL;
1496 } 1860 }
1497 1861
1862 ar = wiphy_priv(wdev->wiphy);
1863 ar->p2p = !!ath6kl_p2p;
1864
1865 wdev->wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
1866
1867 wdev->wiphy->max_remain_on_channel_duration = 5000;
1868
1498 /* set device pointer for wiphy */ 1869 /* set device pointer for wiphy */
1499 set_wiphy_dev(wdev->wiphy, dev); 1870 set_wiphy_dev(wdev->wiphy, dev);
1500 1871
1501 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 1872 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1502 BIT(NL80211_IFTYPE_ADHOC); 1873 BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
1874 if (ar->p2p) {
1875 wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
1876 BIT(NL80211_IFTYPE_P2P_CLIENT);
1877 }
1503 /* max num of ssids that can be probed during scanning */ 1878 /* max num of ssids that can be probed during scanning */
1504 wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; 1879 wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
1880 wdev->wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
1505 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; 1881 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
1506 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz; 1882 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
1507 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 1883 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
index 6b0d45642fe3..b92f0e5d2336 100644
--- a/drivers/net/wireless/ath/ath6kl/common.h
+++ b/drivers/net/wireless/ath/ath6kl/common.h
@@ -75,94 +75,11 @@ enum crypto_type {
75 AES_CRYPT = 0x08, 75 AES_CRYPT = 0x08,
76}; 76};
77 77
78#define ATH6KL_NODE_HASHSIZE 32
79/* simple hash is enough for variation of macaddr */
80#define ATH6KL_NODE_HASH(addr) \
81 (((const u8 *)(addr))[ETH_ALEN - 1] % \
82 ATH6KL_NODE_HASHSIZE)
83
84/*
85 * Table of ath6kl_node instances. Each ieee80211com
86 * has at least one for holding the scan candidates.
87 * When operating as an access point or in ibss mode there
88 * is a second table for associated stations or neighbors.
89 */
90struct ath6kl_node_table {
91 spinlock_t nt_nodelock; /* on node table */
92 struct bss *nt_node_first; /* information of all nodes */
93 struct bss *nt_node_last; /* information of all nodes */
94 struct bss *nt_hash[ATH6KL_NODE_HASHSIZE];
95 const char *nt_name; /* for debugging */
96 u32 nt_node_age; /* node aging time */
97};
98
99#define WLAN_NODE_INACT_TIMEOUT_MSEC 120000
100#define WLAN_NODE_INACT_CNT 4
101
102struct ath6kl_common_ie {
103 u16 ie_chan;
104 u8 *ie_tstamp;
105 u8 *ie_ssid;
106 u8 *ie_rates;
107 u8 *ie_xrates;
108 u8 *ie_country;
109 u8 *ie_wpa;
110 u8 *ie_rsn;
111 u8 *ie_wmm;
112 u8 *ie_ath;
113 u16 ie_capInfo;
114 u16 ie_beaconInt;
115 u8 *ie_tim;
116 u8 *ie_chswitch;
117 u8 ie_erp;
118 u8 *ie_wsc;
119 u8 *ie_htcap;
120 u8 *ie_htop;
121};
122
123struct bss {
124 u8 ni_macaddr[ETH_ALEN];
125 u8 ni_snr;
126 s16 ni_rssi;
127 struct bss *ni_list_next;
128 struct bss *ni_list_prev;
129 struct bss *ni_hash_next;
130 struct bss *ni_hash_prev;
131 struct ath6kl_common_ie ni_cie;
132 u8 *ni_buf;
133 u16 ni_framelen;
134 struct ath6kl_node_table *ni_table;
135 u32 ni_refcnt;
136
137 u32 ni_tstamp;
138 u32 ni_actcnt;
139};
140
141struct htc_endpoint_credit_dist; 78struct htc_endpoint_credit_dist;
142struct ath6kl; 79struct ath6kl;
143enum htc_credit_dist_reason; 80enum htc_credit_dist_reason;
144struct htc_credit_state_info; 81struct htc_credit_state_info;
145 82
146struct bss *wlan_node_alloc(int wh_size);
147void wlan_node_free(struct bss *ni);
148void wlan_setup_node(struct ath6kl_node_table *nt, struct bss *ni,
149 const u8 *mac_addr);
150struct bss *wlan_find_node(struct ath6kl_node_table *nt,
151 const u8 *mac_addr);
152void wlan_node_reclaim(struct ath6kl_node_table *nt, struct bss *ni);
153void wlan_free_allnodes(struct ath6kl_node_table *nt);
154void wlan_iterate_nodes(struct ath6kl_node_table *nt, void *arg);
155
156void wlan_node_table_init(struct ath6kl_node_table *nt);
157void wlan_node_table_cleanup(struct ath6kl_node_table *nt);
158
159void wlan_refresh_inactive_nodes(struct ath6kl *ar);
160
161struct bss *wlan_find_ssid_node(struct ath6kl_node_table *nt, u8 *ssid,
162 u32 ssid_len, bool is_wpa2, bool match_ssid);
163
164void wlan_node_return(struct ath6kl_node_table *nt, struct bss *ni);
165
166int ath6k_setup_credit_dist(void *htc_handle, 83int ath6k_setup_credit_dist(void *htc_handle,
167 struct htc_credit_state_info *cred_info); 84 struct htc_credit_state_info *cred_info);
168void ath6k_credit_distribute(struct htc_credit_state_info *cred_inf, 85void ath6k_credit_distribute(struct htc_credit_state_info *cred_inf,
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 74170229523f..6d8a4845baaf 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -21,10 +21,12 @@
21#include <linux/rtnetlink.h> 21#include <linux/rtnetlink.h>
22#include <linux/firmware.h> 22#include <linux/firmware.h>
23#include <linux/sched.h> 23#include <linux/sched.h>
24#include <linux/circ_buf.h>
24#include <net/cfg80211.h> 25#include <net/cfg80211.h>
25#include "htc.h" 26#include "htc.h"
26#include "wmi.h" 27#include "wmi.h"
27#include "bmi.h" 28#include "bmi.h"
29#include "target.h"
28 30
29#define MAX_ATH6KL 1 31#define MAX_ATH6KL 1
30#define ATH6KL_MAX_RX_BUFFERS 16 32#define ATH6KL_MAX_RX_BUFFERS 16
@@ -42,6 +44,9 @@
42#define ATH6KL_MAX_ENDPOINTS 4 44#define ATH6KL_MAX_ENDPOINTS 4
43#define MAX_NODE_NUM 15 45#define MAX_NODE_NUM 15
44 46
47/* Extra bytes for htc header alignment */
48#define ATH6KL_HTC_ALIGN_BYTES 3
49
45/* MAX_HI_COOKIE_NUM are reserved for high priority traffic */ 50/* MAX_HI_COOKIE_NUM are reserved for high priority traffic */
46#define MAX_DEF_COOKIE_NUM 180 51#define MAX_DEF_COOKIE_NUM 180
47#define MAX_HI_COOKIE_NUM 18 /* 10% of MAX_COOKIE_NUM */ 52#define MAX_HI_COOKIE_NUM 18 /* 10% of MAX_COOKIE_NUM */
@@ -53,6 +58,35 @@
53#define A_DEFAULT_LISTEN_INTERVAL 100 58#define A_DEFAULT_LISTEN_INTERVAL 100
54#define A_MAX_WOW_LISTEN_INTERVAL 1000 59#define A_MAX_WOW_LISTEN_INTERVAL 1000
55 60
61/* includes also the null byte */
62#define ATH6KL_FIRMWARE_MAGIC "QCA-ATH6KL"
63
64enum ath6kl_fw_ie_type {
65 ATH6KL_FW_IE_FW_VERSION = 0,
66 ATH6KL_FW_IE_TIMESTAMP = 1,
67 ATH6KL_FW_IE_OTP_IMAGE = 2,
68 ATH6KL_FW_IE_FW_IMAGE = 3,
69 ATH6KL_FW_IE_PATCH_IMAGE = 4,
70 ATH6KL_FW_IE_RESERVED_RAM_SIZE = 5,
71 ATH6KL_FW_IE_CAPABILITIES = 6,
72 ATH6KL_FW_IE_PATCH_ADDR = 7,
73};
74
75enum ath6kl_fw_capability {
76 ATH6KL_FW_CAPABILITY_HOST_P2P = 0,
77
78 /* this needs to be last */
79 ATH6KL_FW_CAPABILITY_MAX,
80};
81
82#define ATH6KL_CAPABILITY_LEN (ALIGN(ATH6KL_FW_CAPABILITY_MAX, 32) / 32)
83
84struct ath6kl_fw_ie {
85 __le32 id;
86 __le32 len;
87 u8 data[0];
88};
89
56/* AR6003 1.0 definitions */ 90/* AR6003 1.0 definitions */
57#define AR6003_REV1_VERSION 0x300002ba 91#define AR6003_REV1_VERSION 0x300002ba
58 92
@@ -61,7 +95,9 @@
61#define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS 0x57e910 95#define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS 0x57e910
62#define AR6003_REV2_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77" 96#define AR6003_REV2_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77"
63#define AR6003_REV2_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77" 97#define AR6003_REV2_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77"
98#define AR6003_REV2_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin"
64#define AR6003_REV2_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin" 99#define AR6003_REV2_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin"
100#define AR6003_REV2_FIRMWARE_2_FILE "ath6k/AR6003/hw2.0/fw-2.bin"
65#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin" 101#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin"
66#define AR6003_REV2_DEFAULT_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin" 102#define AR6003_REV2_DEFAULT_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin"
67 103
@@ -69,11 +105,21 @@
69#define AR6003_REV3_VERSION 0x30000582 105#define AR6003_REV3_VERSION 0x30000582
70#define AR6003_REV3_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin" 106#define AR6003_REV3_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin"
71#define AR6003_REV3_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin" 107#define AR6003_REV3_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin"
108#define AR6003_REV3_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin"
72#define AR6003_REV3_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin" 109#define AR6003_REV3_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin"
110#define AR6003_REV3_FIRMWARE_2_FILE "ath6k/AR6003/hw2.1.1/fw-2.bin"
73#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin" 111#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin"
74#define AR6003_REV3_DEFAULT_BOARD_DATA_FILE \ 112#define AR6003_REV3_DEFAULT_BOARD_DATA_FILE \
75 "ath6k/AR6003/hw2.1.1/bdata.SD31.bin" 113 "ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
76 114
115/* AR6004 1.0 definitions */
116#define AR6004_REV1_VERSION 0x30000623
117#define AR6004_REV1_FIRMWARE_FILE "ath6k/AR6004/hw6.1/fw.ram.bin"
118#define AR6004_REV1_FIRMWARE_2_FILE "ath6k/AR6004/hw6.1/fw-2.bin"
119#define AR6004_REV1_BOARD_DATA_FILE "ath6k/AR6004/hw6.1/bdata.bin"
120#define AR6004_REV1_DEFAULT_BOARD_DATA_FILE "ath6k/AR6004/hw6.1/bdata.DB132.bin"
121#define AR6004_REV1_EPPING_FIRMWARE_FILE "ath6k/AR6004/hw6.1/endpointping.bin"
122
77/* Per STA data, used in AP mode */ 123/* Per STA data, used in AP mode */
78#define STA_PS_AWAKE BIT(0) 124#define STA_PS_AWAKE BIT(0)
79#define STA_PS_SLEEP BIT(1) 125#define STA_PS_SLEEP BIT(1)
@@ -325,26 +371,13 @@ struct ath6kl_mbox_info {
325#define ATH6KL_KEY_RECV 0x02 371#define ATH6KL_KEY_RECV 0x02
326#define ATH6KL_KEY_DEFAULT 0x80 /* default xmit key */ 372#define ATH6KL_KEY_DEFAULT 0x80 /* default xmit key */
327 373
328/* 374/* Initial group key for AP mode */
329 * WPA/RSN get/set key request. Specify the key/cipher
330 * type and whether the key is to be used for sending and/or
331 * receiving. The key index should be set only when working
332 * with global keys (use IEEE80211_KEYIX_NONE for ``no index'').
333 * Otherwise a unicast/pairwise key is specified by the bssid
334 * (on a station) or mac address (on an ap). They key length
335 * must include any MIC key data; otherwise it should be no
336 * more than ATH6KL_KEYBUF_SIZE.
337 */
338struct ath6kl_req_key { 375struct ath6kl_req_key {
339 u8 ik_type; /* key/cipher type */ 376 bool valid;
340 u8 ik_pad; 377 u8 key_index;
341 u16 ik_keyix; /* key index */ 378 int key_type;
342 u8 ik_keylen; /* key length in bytes */ 379 u8 key[WLAN_MAX_KEY_LEN];
343 u8 ik_flags; 380 u8 key_len;
344 u8 ik_macaddr[ETH_ALEN];
345 u64 ik_keyrsc; /* key receive sequence counter */
346 u64 ik_keytsc; /* key transmit sequence counter */
347 u8 ik_keydata[ATH6KL_KEYBUF_SIZE + ATH6KL_MICBUF_SIZE];
348}; 381};
349 382
350/* Flag info */ 383/* Flag info */
@@ -361,6 +394,9 @@ struct ath6kl_req_key {
361#define NETDEV_REGISTERED 10 394#define NETDEV_REGISTERED 10
362#define SKIP_SCAN 11 395#define SKIP_SCAN 11
363#define WLAN_ENABLED 12 396#define WLAN_ENABLED 12
397#define TESTMODE 13
398#define CLEAR_BSSFILTER_ON_BEACON 14
399#define DTIM_PERIOD_AVAIL 15
364 400
365struct ath6kl { 401struct ath6kl {
366 struct device *dev; 402 struct device *dev;
@@ -383,7 +419,7 @@ struct ath6kl {
383 u8 prwise_crypto; 419 u8 prwise_crypto;
384 u8 prwise_crypto_len; 420 u8 prwise_crypto_len;
385 u8 grp_crypto; 421 u8 grp_crypto;
386 u8 grp_crpto_len; 422 u8 grp_crypto_len;
387 u8 def_txkey_index; 423 u8 def_txkey_index;
388 struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1]; 424 struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
389 u8 bssid[ETH_ALEN]; 425 u8 bssid[ETH_ALEN];
@@ -392,6 +428,7 @@ struct ath6kl {
392 u16 bss_ch; 428 u16 bss_ch;
393 u16 listen_intvl_b; 429 u16 listen_intvl_b;
394 u16 listen_intvl_t; 430 u16 listen_intvl_t;
431 u8 lrssi_roam_threshold;
395 struct ath6kl_version version; 432 struct ath6kl_version version;
396 u32 target_type; 433 u32 target_type;
397 u8 tx_pwr; 434 u8 tx_pwr;
@@ -432,7 +469,18 @@ struct ath6kl {
432 enum wlan_low_pwr_state wlan_pwr_state; 469 enum wlan_low_pwr_state wlan_pwr_state;
433 struct wmi_scan_params_cmd sc_params; 470 struct wmi_scan_params_cmd sc_params;
434#define AR_MCAST_FILTER_MAC_ADDR_SIZE 4 471#define AR_MCAST_FILTER_MAC_ADDR_SIZE 4
435 u8 auto_auth_stage; 472 struct {
473 void *rx_report;
474 size_t rx_report_len;
475 } tm;
476
477 struct {
478 u32 dataset_patch_addr;
479 u32 app_load_addr;
480 u32 app_start_override_addr;
481 u32 board_ext_data_addr;
482 u32 reserved_ram_size;
483 } hw;
436 484
437 u16 conf_flags; 485 u16 conf_flags;
438 wait_queue_head_t event_wq; 486 wait_queue_head_t event_wq;
@@ -454,9 +502,35 @@ struct ath6kl {
454 u8 *fw_patch; 502 u8 *fw_patch;
455 size_t fw_patch_len; 503 size_t fw_patch_len;
456 504
505 unsigned long fw_capabilities[ATH6KL_CAPABILITY_LEN];
506
457 struct workqueue_struct *ath6kl_wq; 507 struct workqueue_struct *ath6kl_wq;
458 508
459 struct ath6kl_node_table scan_table; 509 struct dentry *debugfs_phy;
510
511 u32 send_action_id;
512 bool probe_req_report;
513 u16 next_chan;
514
515 bool p2p;
516 u16 assoc_bss_beacon_int;
517 u8 assoc_bss_dtim_period;
518
519#ifdef CONFIG_ATH6KL_DEBUG
520 struct {
521 struct circ_buf fwlog_buf;
522 spinlock_t fwlog_lock;
523 void *fwlog_tmp;
524 u32 fwlog_mask;
525 unsigned int dbgfs_diag_reg;
526 u32 diag_reg_addr_wr;
527 u32 diag_reg_val_wr;
528
529 struct {
530 unsigned int invalid_rate;
531 } war_stats;
532 } debug;
533#endif /* CONFIG_ATH6KL_DEBUG */
460}; 534};
461 535
462static inline void *ath6kl_priv(struct net_device *dev) 536static inline void *ath6kl_priv(struct net_device *dev)
@@ -474,6 +548,19 @@ static inline void ath6kl_deposit_credit_to_ep(struct htc_credit_state_info
474 cred_info->cur_free_credits -= credits; 548 cred_info->cur_free_credits -= credits;
475} 549}
476 550
551static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
552 u32 item_offset)
553{
554 u32 addr = 0;
555
556 if (ar->target_type == TARGET_TYPE_AR6003)
557 addr = ATH6KL_AR6003_HI_START_ADDR + item_offset;
558 else if (ar->target_type == TARGET_TYPE_AR6004)
559 addr = ATH6KL_AR6004_HI_START_ADDR + item_offset;
560
561 return addr;
562}
563
477void ath6kl_destroy(struct net_device *dev, unsigned int unregister); 564void ath6kl_destroy(struct net_device *dev, unsigned int unregister);
478int ath6kl_configure_target(struct ath6kl *ar); 565int ath6kl_configure_target(struct ath6kl *ar);
479void ath6kl_detect_error(unsigned long ptr); 566void ath6kl_detect_error(unsigned long ptr);
@@ -487,9 +574,11 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
487 struct htc_packet *packet); 574 struct htc_packet *packet);
488void ath6kl_stop_txrx(struct ath6kl *ar); 575void ath6kl_stop_txrx(struct ath6kl *ar);
489void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar); 576void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar);
490int ath6kl_access_datadiag(struct ath6kl *ar, u32 address, 577int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value);
491 u8 *data, u32 length, bool read); 578int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length);
492int ath6kl_read_reg_diag(struct ath6kl *ar, u32 *address, u32 *data); 579int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value);
580int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length);
581int ath6kl_read_fwlogs(struct ath6kl *ar);
493void ath6kl_init_profile_info(struct ath6kl *ar); 582void ath6kl_init_profile_info(struct ath6kl *ar);
494void ath6kl_tx_data_cleanup(struct ath6kl *ar); 583void ath6kl_tx_data_cleanup(struct ath6kl *ar);
495void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile, 584void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
@@ -520,6 +609,10 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel,
520 u16 beacon_int, enum network_type net_type, 609 u16 beacon_int, enum network_type net_type,
521 u8 beacon_ie_len, u8 assoc_req_len, 610 u8 beacon_ie_len, u8 assoc_req_len,
522 u8 assoc_resp_len, u8 *assoc_info); 611 u8 assoc_resp_len, u8 *assoc_info);
612void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel);
613void ath6kl_connect_ap_mode_sta(struct ath6kl *ar, u16 aid, u8 *mac_addr,
614 u8 keymgmt, u8 ucipher, u8 auth,
615 u8 assoc_req_len, u8 *assoc_info);
523void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, 616void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason,
524 u8 *bssid, u8 assoc_resp_len, 617 u8 *bssid, u8 assoc_resp_len,
525 u8 *assoc_info, u16 prot_reason_status); 618 u8 *assoc_info, u16 prot_reason_status);
@@ -534,11 +627,11 @@ void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid);
534 627
535void ath6kl_dtimexpiry_event(struct ath6kl *ar); 628void ath6kl_dtimexpiry_event(struct ath6kl *ar);
536void ath6kl_disconnect(struct ath6kl *ar); 629void ath6kl_disconnect(struct ath6kl *ar);
630void ath6kl_deep_sleep_enable(struct ath6kl *ar);
537void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid); 631void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid);
538void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no, 632void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no,
539 u8 win_sz); 633 u8 win_sz);
540void ath6kl_wakeup_event(void *dev); 634void ath6kl_wakeup_event(void *dev);
541void ath6kl_target_failure(struct ath6kl *ar); 635void ath6kl_target_failure(struct ath6kl *ar);
542 636
543void ath6kl_cfg80211_scan_node(struct wiphy *wiphy, struct bss *ni);
544#endif /* CORE_H */ 637#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 316136c8b903..ba3f23d71150 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -15,7 +15,26 @@
15 */ 15 */
16 16
17#include "core.h" 17#include "core.h"
18
19#include <linux/circ_buf.h>
20#include <linux/fs.h>
21#include <linux/vmalloc.h>
22
18#include "debug.h" 23#include "debug.h"
24#include "target.h"
25
26struct ath6kl_fwlog_slot {
27 __le32 timestamp;
28 __le32 length;
29
30 /* max ATH6KL_FWLOG_PAYLOAD_SIZE bytes */
31 u8 payload[0];
32};
33
34#define ATH6KL_FWLOG_SIZE 32768
35#define ATH6KL_FWLOG_SLOT_SIZE (sizeof(struct ath6kl_fwlog_slot) + \
36 ATH6KL_FWLOG_PAYLOAD_SIZE)
37#define ATH6KL_FWLOG_VALID_MASK 0x1ffff
19 38
20int ath6kl_printk(const char *level, const char *fmt, ...) 39int ath6kl_printk(const char *level, const char *fmt, ...)
21{ 40{
@@ -36,6 +55,27 @@ int ath6kl_printk(const char *level, const char *fmt, ...)
36} 55}
37 56
38#ifdef CONFIG_ATH6KL_DEBUG 57#ifdef CONFIG_ATH6KL_DEBUG
58
59#define REG_OUTPUT_LEN_PER_LINE 25
60#define REGTYPE_STR_LEN 100
61
62struct ath6kl_diag_reg_info {
63 u32 reg_start;
64 u32 reg_end;
65 const char *reg_info;
66};
67
68static const struct ath6kl_diag_reg_info diag_reg[] = {
69 { 0x20000, 0x200fc, "General DMA and Rx registers" },
70 { 0x28000, 0x28900, "MAC PCU register & keycache" },
71 { 0x20800, 0x20a40, "QCU" },
72 { 0x21000, 0x212f0, "DCU" },
73 { 0x4000, 0x42e4, "RTC" },
74 { 0x540000, 0x540000 + (256 * 1024), "RAM" },
75 { 0x29800, 0x2B210, "Base Band" },
76 { 0x1C000, 0x1C748, "Analog" },
77};
78
39void ath6kl_dump_registers(struct ath6kl_device *dev, 79void ath6kl_dump_registers(struct ath6kl_device *dev,
40 struct ath6kl_irq_proc_registers *irq_proc_reg, 80 struct ath6kl_irq_proc_registers *irq_proc_reg,
41 struct ath6kl_irq_enable_reg *irq_enable_reg) 81 struct ath6kl_irq_enable_reg *irq_enable_reg)
@@ -147,4 +187,748 @@ void dump_cred_dist_stats(struct htc_target *target)
147 target->cred_dist_cntxt->cur_free_credits); 187 target->cred_dist_cntxt->cur_free_credits);
148} 188}
149 189
190static int ath6kl_debugfs_open(struct inode *inode, struct file *file)
191{
192 file->private_data = inode->i_private;
193 return 0;
194}
195
196void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war)
197{
198 switch (war) {
199 case ATH6KL_WAR_INVALID_RATE:
200 ar->debug.war_stats.invalid_rate++;
201 break;
202 }
203}
204
205static ssize_t read_file_war_stats(struct file *file, char __user *user_buf,
206 size_t count, loff_t *ppos)
207{
208 struct ath6kl *ar = file->private_data;
209 char *buf;
210 unsigned int len = 0, buf_len = 1500;
211 ssize_t ret_cnt;
212
213 buf = kzalloc(buf_len, GFP_KERNEL);
214 if (!buf)
215 return -ENOMEM;
216
217 len += scnprintf(buf + len, buf_len - len, "\n");
218 len += scnprintf(buf + len, buf_len - len, "%25s\n",
219 "Workaround stats");
220 len += scnprintf(buf + len, buf_len - len, "%25s\n\n",
221 "=================");
222 len += scnprintf(buf + len, buf_len - len, "%20s %10u\n",
223 "Invalid rates", ar->debug.war_stats.invalid_rate);
224
225 if (WARN_ON(len > buf_len))
226 len = buf_len;
227
228 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
229
230 kfree(buf);
231 return ret_cnt;
232}
233
234static const struct file_operations fops_war_stats = {
235 .read = read_file_war_stats,
236 .open = ath6kl_debugfs_open,
237 .owner = THIS_MODULE,
238 .llseek = default_llseek,
239};
240
241static void ath6kl_debug_fwlog_add(struct ath6kl *ar, const void *buf,
242 size_t buf_len)
243{
244 struct circ_buf *fwlog = &ar->debug.fwlog_buf;
245 size_t space;
246 int i;
247
248 /* entries must all be equal size */
249 if (WARN_ON(buf_len != ATH6KL_FWLOG_SLOT_SIZE))
250 return;
251
252 space = CIRC_SPACE(fwlog->head, fwlog->tail, ATH6KL_FWLOG_SIZE);
253 if (space < buf_len)
254 /* discard oldest slot */
255 fwlog->tail = (fwlog->tail + ATH6KL_FWLOG_SLOT_SIZE) &
256 (ATH6KL_FWLOG_SIZE - 1);
257
258 for (i = 0; i < buf_len; i += space) {
259 space = CIRC_SPACE_TO_END(fwlog->head, fwlog->tail,
260 ATH6KL_FWLOG_SIZE);
261
262 if ((size_t) space > buf_len - i)
263 space = buf_len - i;
264
265 memcpy(&fwlog->buf[fwlog->head], buf, space);
266 fwlog->head = (fwlog->head + space) & (ATH6KL_FWLOG_SIZE - 1);
267 }
268
269}
270
271void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len)
272{
273 struct ath6kl_fwlog_slot *slot = ar->debug.fwlog_tmp;
274 size_t slot_len;
275
276 if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE))
277 return;
278
279 spin_lock_bh(&ar->debug.fwlog_lock);
280
281 slot->timestamp = cpu_to_le32(jiffies);
282 slot->length = cpu_to_le32(len);
283 memcpy(slot->payload, buf, len);
284
285 slot_len = sizeof(*slot) + len;
286
287 if (slot_len < ATH6KL_FWLOG_SLOT_SIZE)
288 memset(slot->payload + len, 0,
289 ATH6KL_FWLOG_SLOT_SIZE - slot_len);
290
291 ath6kl_debug_fwlog_add(ar, slot, ATH6KL_FWLOG_SLOT_SIZE);
292
293 spin_unlock_bh(&ar->debug.fwlog_lock);
294}
295
296static bool ath6kl_debug_fwlog_empty(struct ath6kl *ar)
297{
298 return CIRC_CNT(ar->debug.fwlog_buf.head,
299 ar->debug.fwlog_buf.tail,
300 ATH6KL_FWLOG_SLOT_SIZE) == 0;
301}
302
303static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf,
304 size_t count, loff_t *ppos)
305{
306 struct ath6kl *ar = file->private_data;
307 struct circ_buf *fwlog = &ar->debug.fwlog_buf;
308 size_t len = 0, buf_len = count;
309 ssize_t ret_cnt;
310 char *buf;
311 int ccnt;
312
313 buf = vmalloc(buf_len);
314 if (!buf)
315 return -ENOMEM;
316
317 /* read undelivered logs from firmware */
318 ath6kl_read_fwlogs(ar);
319
320 spin_lock_bh(&ar->debug.fwlog_lock);
321
322 while (len < buf_len && !ath6kl_debug_fwlog_empty(ar)) {
323 ccnt = CIRC_CNT_TO_END(fwlog->head, fwlog->tail,
324 ATH6KL_FWLOG_SIZE);
325
326 if ((size_t) ccnt > buf_len - len)
327 ccnt = buf_len - len;
328
329 memcpy(buf + len, &fwlog->buf[fwlog->tail], ccnt);
330 len += ccnt;
331
332 fwlog->tail = (fwlog->tail + ccnt) &
333 (ATH6KL_FWLOG_SIZE - 1);
334 }
335
336 spin_unlock_bh(&ar->debug.fwlog_lock);
337
338 if (WARN_ON(len > buf_len))
339 len = buf_len;
340
341 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
342
343 vfree(buf);
344
345 return ret_cnt;
346}
347
348static const struct file_operations fops_fwlog = {
349 .open = ath6kl_debugfs_open,
350 .read = ath6kl_fwlog_read,
351 .owner = THIS_MODULE,
352 .llseek = default_llseek,
353};
354
355static ssize_t ath6kl_fwlog_mask_read(struct file *file, char __user *user_buf,
356 size_t count, loff_t *ppos)
357{
358 struct ath6kl *ar = file->private_data;
359 char buf[16];
360 int len;
361
362 len = snprintf(buf, sizeof(buf), "0x%x\n", ar->debug.fwlog_mask);
363
364 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
365}
366
367static ssize_t ath6kl_fwlog_mask_write(struct file *file,
368 const char __user *user_buf,
369 size_t count, loff_t *ppos)
370{
371 struct ath6kl *ar = file->private_data;
372 int ret;
373
374 ret = kstrtou32_from_user(user_buf, count, 0, &ar->debug.fwlog_mask);
375 if (ret)
376 return ret;
377
378 ret = ath6kl_wmi_config_debug_module_cmd(ar->wmi,
379 ATH6KL_FWLOG_VALID_MASK,
380 ar->debug.fwlog_mask);
381 if (ret)
382 return ret;
383
384 return count;
385}
386
387static const struct file_operations fops_fwlog_mask = {
388 .open = ath6kl_debugfs_open,
389 .read = ath6kl_fwlog_mask_read,
390 .write = ath6kl_fwlog_mask_write,
391 .owner = THIS_MODULE,
392 .llseek = default_llseek,
393};
394
395static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
396 size_t count, loff_t *ppos)
397{
398 struct ath6kl *ar = file->private_data;
399 struct target_stats *tgt_stats = &ar->target_stats;
400 char *buf;
401 unsigned int len = 0, buf_len = 1500;
402 int i;
403 long left;
404 ssize_t ret_cnt;
405
406 buf = kzalloc(buf_len, GFP_KERNEL);
407 if (!buf)
408 return -ENOMEM;
409
410 if (down_interruptible(&ar->sem)) {
411 kfree(buf);
412 return -EBUSY;
413 }
414
415 set_bit(STATS_UPDATE_PEND, &ar->flag);
416
417 if (ath6kl_wmi_get_stats_cmd(ar->wmi)) {
418 up(&ar->sem);
419 kfree(buf);
420 return -EIO;
421 }
422
423 left = wait_event_interruptible_timeout(ar->event_wq,
424 !test_bit(STATS_UPDATE_PEND,
425 &ar->flag), WMI_TIMEOUT);
426
427 up(&ar->sem);
428
429 if (left <= 0) {
430 kfree(buf);
431 return -ETIMEDOUT;
432 }
433
434 len += scnprintf(buf + len, buf_len - len, "\n");
435 len += scnprintf(buf + len, buf_len - len, "%25s\n",
436 "Target Tx stats");
437 len += scnprintf(buf + len, buf_len - len, "%25s\n\n",
438 "=================");
439 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
440 "Ucast packets", tgt_stats->tx_ucast_pkt);
441 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
442 "Bcast packets", tgt_stats->tx_bcast_pkt);
443 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
444 "Ucast byte", tgt_stats->tx_ucast_byte);
445 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
446 "Bcast byte", tgt_stats->tx_bcast_byte);
447 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
448 "Rts success cnt", tgt_stats->tx_rts_success_cnt);
449 for (i = 0; i < 4; i++)
450 len += scnprintf(buf + len, buf_len - len,
451 "%18s %d %10llu\n", "PER on ac",
452 i, tgt_stats->tx_pkt_per_ac[i]);
453 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
454 "Error", tgt_stats->tx_err);
455 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
456 "Fail count", tgt_stats->tx_fail_cnt);
457 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
458 "Retry count", tgt_stats->tx_retry_cnt);
459 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
460 "Multi retry cnt", tgt_stats->tx_mult_retry_cnt);
461 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
462 "Rts fail cnt", tgt_stats->tx_rts_fail_cnt);
463 len += scnprintf(buf + len, buf_len - len, "%25s %10llu\n\n",
464 "TKIP counter measure used",
465 tgt_stats->tkip_cnter_measures_invoked);
466
467 len += scnprintf(buf + len, buf_len - len, "%25s\n",
468 "Target Rx stats");
469 len += scnprintf(buf + len, buf_len - len, "%25s\n",
470 "=================");
471
472 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
473 "Ucast packets", tgt_stats->rx_ucast_pkt);
474 len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
475 "Ucast Rate", tgt_stats->rx_ucast_rate);
476 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
477 "Bcast packets", tgt_stats->rx_bcast_pkt);
478 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
479 "Ucast byte", tgt_stats->rx_ucast_byte);
480 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
481 "Bcast byte", tgt_stats->rx_bcast_byte);
482 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
483 "Fragmented pkt", tgt_stats->rx_frgment_pkt);
484 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
485 "Error", tgt_stats->rx_err);
486 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
487 "CRC Err", tgt_stats->rx_crc_err);
488 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
489 "Key chache miss", tgt_stats->rx_key_cache_miss);
490 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
491 "Decrypt Err", tgt_stats->rx_decrypt_err);
492 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
493 "Duplicate frame", tgt_stats->rx_dupl_frame);
494 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
495 "Tkip Mic failure", tgt_stats->tkip_local_mic_fail);
496 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
497 "TKIP format err", tgt_stats->tkip_fmt_err);
498 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
499 "CCMP format Err", tgt_stats->ccmp_fmt_err);
500 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n",
501 "CCMP Replay Err", tgt_stats->ccmp_replays);
502
503 len += scnprintf(buf + len, buf_len - len, "%25s\n",
504 "Misc Target stats");
505 len += scnprintf(buf + len, buf_len - len, "%25s\n",
506 "=================");
507 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
508 "Beacon Miss count", tgt_stats->cs_bmiss_cnt);
509 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
510 "Num Connects", tgt_stats->cs_connect_cnt);
511 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
512 "Num disconnects", tgt_stats->cs_discon_cnt);
513 len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
514 "Beacon avg rssi", tgt_stats->cs_ave_beacon_rssi);
515
516 if (len > buf_len)
517 len = buf_len;
518
519 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
520
521 kfree(buf);
522 return ret_cnt;
523}
524
525static const struct file_operations fops_tgt_stats = {
526 .read = read_file_tgt_stats,
527 .open = ath6kl_debugfs_open,
528 .owner = THIS_MODULE,
529 .llseek = default_llseek,
530};
531
532#define print_credit_info(fmt_str, ep_list_field) \
533 (len += scnprintf(buf + len, buf_len - len, fmt_str, \
534 ep_list->ep_list_field))
535#define CREDIT_INFO_DISPLAY_STRING_LEN 200
536#define CREDIT_INFO_LEN 128
537
538static ssize_t read_file_credit_dist_stats(struct file *file,
539 char __user *user_buf,
540 size_t count, loff_t *ppos)
541{
542 struct ath6kl *ar = file->private_data;
543 struct htc_target *target = ar->htc_target;
544 struct htc_endpoint_credit_dist *ep_list;
545 char *buf;
546 unsigned int buf_len, len = 0;
547 ssize_t ret_cnt;
548
549 buf_len = CREDIT_INFO_DISPLAY_STRING_LEN +
550 get_queue_depth(&target->cred_dist_list) * CREDIT_INFO_LEN;
551 buf = kzalloc(buf_len, GFP_KERNEL);
552 if (!buf)
553 return -ENOMEM;
554
555 len += scnprintf(buf + len, buf_len - len, "%25s%5d\n",
556 "Total Avail Credits: ",
557 target->cred_dist_cntxt->total_avail_credits);
558 len += scnprintf(buf + len, buf_len - len, "%25s%5d\n",
559 "Free credits :",
560 target->cred_dist_cntxt->cur_free_credits);
561
562 len += scnprintf(buf + len, buf_len - len,
563 " Epid Flags Cred_norm Cred_min Credits Cred_assngd"
564 " Seek_cred Cred_sz Cred_per_msg Cred_to_dist"
565 " qdepth\n");
566
567 list_for_each_entry(ep_list, &target->cred_dist_list, list) {
568 print_credit_info(" %2d", endpoint);
569 print_credit_info("%10x", dist_flags);
570 print_credit_info("%8d", cred_norm);
571 print_credit_info("%9d", cred_min);
572 print_credit_info("%9d", credits);
573 print_credit_info("%10d", cred_assngd);
574 print_credit_info("%13d", seek_cred);
575 print_credit_info("%12d", cred_sz);
576 print_credit_info("%9d", cred_per_msg);
577 print_credit_info("%14d", cred_to_dist);
578 len += scnprintf(buf + len, buf_len - len, "%12d\n",
579 get_queue_depth(&((struct htc_endpoint *)
580 ep_list->htc_rsvd)->txq));
581 }
582
583 if (len > buf_len)
584 len = buf_len;
585
586 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
587 kfree(buf);
588 return ret_cnt;
589}
590
591static const struct file_operations fops_credit_dist_stats = {
592 .read = read_file_credit_dist_stats,
593 .open = ath6kl_debugfs_open,
594 .owner = THIS_MODULE,
595 .llseek = default_llseek,
596};
597
598static unsigned long ath6kl_get_num_reg(void)
599{
600 int i;
601 unsigned long n_reg = 0;
602
603 for (i = 0; i < ARRAY_SIZE(diag_reg); i++)
604 n_reg = n_reg +
605 (diag_reg[i].reg_end - diag_reg[i].reg_start) / 4 + 1;
606
607 return n_reg;
608}
609
610static bool ath6kl_dbg_is_diag_reg_valid(u32 reg_addr)
611{
612 int i;
613
614 for (i = 0; i < ARRAY_SIZE(diag_reg); i++) {
615 if (reg_addr >= diag_reg[i].reg_start &&
616 reg_addr <= diag_reg[i].reg_end)
617 return true;
618 }
619
620 return false;
621}
622
623static ssize_t ath6kl_regread_read(struct file *file, char __user *user_buf,
624 size_t count, loff_t *ppos)
625{
626 struct ath6kl *ar = file->private_data;
627 u8 buf[50];
628 unsigned int len = 0;
629
630 if (ar->debug.dbgfs_diag_reg)
631 len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n",
632 ar->debug.dbgfs_diag_reg);
633 else
634 len += scnprintf(buf + len, sizeof(buf) - len,
635 "All diag registers\n");
636
637 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
638}
639
640static ssize_t ath6kl_regread_write(struct file *file,
641 const char __user *user_buf,
642 size_t count, loff_t *ppos)
643{
644 struct ath6kl *ar = file->private_data;
645 u8 buf[50];
646 unsigned int len;
647 unsigned long reg_addr;
648
649 len = min(count, sizeof(buf) - 1);
650 if (copy_from_user(buf, user_buf, len))
651 return -EFAULT;
652
653 buf[len] = '\0';
654
655 if (strict_strtoul(buf, 0, &reg_addr))
656 return -EINVAL;
657
658 if ((reg_addr % 4) != 0)
659 return -EINVAL;
660
661 if (reg_addr && !ath6kl_dbg_is_diag_reg_valid(reg_addr))
662 return -EINVAL;
663
664 ar->debug.dbgfs_diag_reg = reg_addr;
665
666 return count;
667}
668
669static const struct file_operations fops_diag_reg_read = {
670 .read = ath6kl_regread_read,
671 .write = ath6kl_regread_write,
672 .open = ath6kl_debugfs_open,
673 .owner = THIS_MODULE,
674 .llseek = default_llseek,
675};
676
677static int ath6kl_regdump_open(struct inode *inode, struct file *file)
678{
679 struct ath6kl *ar = inode->i_private;
680 u8 *buf;
681 unsigned long int reg_len;
682 unsigned int len = 0, n_reg;
683 u32 addr;
684 __le32 reg_val;
685 int i, status;
686
687 /* Dump all the registers if no register is specified */
688 if (!ar->debug.dbgfs_diag_reg)
689 n_reg = ath6kl_get_num_reg();
690 else
691 n_reg = 1;
692
693 reg_len = n_reg * REG_OUTPUT_LEN_PER_LINE;
694 if (n_reg > 1)
695 reg_len += REGTYPE_STR_LEN;
696
697 buf = vmalloc(reg_len);
698 if (!buf)
699 return -ENOMEM;
700
701 if (n_reg == 1) {
702 addr = ar->debug.dbgfs_diag_reg;
703
704 status = ath6kl_diag_read32(ar,
705 TARG_VTOP(ar->target_type, addr),
706 (u32 *)&reg_val);
707 if (status)
708 goto fail_reg_read;
709
710 len += scnprintf(buf + len, reg_len - len,
711 "0x%06x 0x%08x\n", addr, le32_to_cpu(reg_val));
712 goto done;
713 }
714
715 for (i = 0; i < ARRAY_SIZE(diag_reg); i++) {
716 len += scnprintf(buf + len, reg_len - len,
717 "%s\n", diag_reg[i].reg_info);
718 for (addr = diag_reg[i].reg_start;
719 addr <= diag_reg[i].reg_end; addr += 4) {
720 status = ath6kl_diag_read32(ar,
721 TARG_VTOP(ar->target_type, addr),
722 (u32 *)&reg_val);
723 if (status)
724 goto fail_reg_read;
725
726 len += scnprintf(buf + len, reg_len - len,
727 "0x%06x 0x%08x\n",
728 addr, le32_to_cpu(reg_val));
729 }
730 }
731
732done:
733 file->private_data = buf;
734 return 0;
735
736fail_reg_read:
737 ath6kl_warn("Unable to read memory:%u\n", addr);
738 vfree(buf);
739 return -EIO;
740}
741
742static ssize_t ath6kl_regdump_read(struct file *file, char __user *user_buf,
743 size_t count, loff_t *ppos)
744{
745 u8 *buf = file->private_data;
746 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
747}
748
749static int ath6kl_regdump_release(struct inode *inode, struct file *file)
750{
751 vfree(file->private_data);
752 return 0;
753}
754
755static const struct file_operations fops_reg_dump = {
756 .open = ath6kl_regdump_open,
757 .read = ath6kl_regdump_read,
758 .release = ath6kl_regdump_release,
759 .owner = THIS_MODULE,
760 .llseek = default_llseek,
761};
762
763static ssize_t ath6kl_lrssi_roam_write(struct file *file,
764 const char __user *user_buf,
765 size_t count, loff_t *ppos)
766{
767 struct ath6kl *ar = file->private_data;
768 unsigned long lrssi_roam_threshold;
769 char buf[32];
770 ssize_t len;
771
772 len = min(count, sizeof(buf) - 1);
773 if (copy_from_user(buf, user_buf, len))
774 return -EFAULT;
775
776 buf[len] = '\0';
777 if (strict_strtoul(buf, 0, &lrssi_roam_threshold))
778 return -EINVAL;
779
780 ar->lrssi_roam_threshold = lrssi_roam_threshold;
781
782 ath6kl_wmi_set_roam_lrssi_cmd(ar->wmi, ar->lrssi_roam_threshold);
783
784 return count;
785}
786
787static ssize_t ath6kl_lrssi_roam_read(struct file *file,
788 char __user *user_buf,
789 size_t count, loff_t *ppos)
790{
791 struct ath6kl *ar = file->private_data;
792 char buf[32];
793 unsigned int len;
794
795 len = snprintf(buf, sizeof(buf), "%u\n", ar->lrssi_roam_threshold);
796
797 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
798}
799
800static const struct file_operations fops_lrssi_roam_threshold = {
801 .read = ath6kl_lrssi_roam_read,
802 .write = ath6kl_lrssi_roam_write,
803 .open = ath6kl_debugfs_open,
804 .owner = THIS_MODULE,
805 .llseek = default_llseek,
806};
807
808static ssize_t ath6kl_regwrite_read(struct file *file,
809 char __user *user_buf,
810 size_t count, loff_t *ppos)
811{
812 struct ath6kl *ar = file->private_data;
813 u8 buf[32];
814 unsigned int len = 0;
815
816 len = scnprintf(buf, sizeof(buf), "Addr: 0x%x Val: 0x%x\n",
817 ar->debug.diag_reg_addr_wr, ar->debug.diag_reg_val_wr);
818
819 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
820}
821
822static ssize_t ath6kl_regwrite_write(struct file *file,
823 const char __user *user_buf,
824 size_t count, loff_t *ppos)
825{
826 struct ath6kl *ar = file->private_data;
827 char buf[32];
828 char *sptr, *token;
829 unsigned int len = 0;
830 u32 reg_addr, reg_val;
831
832 len = min(count, sizeof(buf) - 1);
833 if (copy_from_user(buf, user_buf, len))
834 return -EFAULT;
835
836 buf[len] = '\0';
837 sptr = buf;
838
839 token = strsep(&sptr, "=");
840 if (!token)
841 return -EINVAL;
842
843 if (kstrtou32(token, 0, &reg_addr))
844 return -EINVAL;
845
846 if (!ath6kl_dbg_is_diag_reg_valid(reg_addr))
847 return -EINVAL;
848
849 if (kstrtou32(sptr, 0, &reg_val))
850 return -EINVAL;
851
852 ar->debug.diag_reg_addr_wr = reg_addr;
853 ar->debug.diag_reg_val_wr = reg_val;
854
855 if (ath6kl_diag_write32(ar, ar->debug.diag_reg_addr_wr,
856 cpu_to_le32(ar->debug.diag_reg_val_wr)))
857 return -EIO;
858
859 return count;
860}
861
862static const struct file_operations fops_diag_reg_write = {
863 .read = ath6kl_regwrite_read,
864 .write = ath6kl_regwrite_write,
865 .open = ath6kl_debugfs_open,
866 .owner = THIS_MODULE,
867 .llseek = default_llseek,
868};
869
870int ath6kl_debug_init(struct ath6kl *ar)
871{
872 ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE);
873 if (ar->debug.fwlog_buf.buf == NULL)
874 return -ENOMEM;
875
876 ar->debug.fwlog_tmp = kmalloc(ATH6KL_FWLOG_SLOT_SIZE, GFP_KERNEL);
877 if (ar->debug.fwlog_tmp == NULL) {
878 vfree(ar->debug.fwlog_buf.buf);
879 return -ENOMEM;
880 }
881
882 spin_lock_init(&ar->debug.fwlog_lock);
883
884 /*
885 * Actually we are lying here but don't know how to read the mask
886 * value from the firmware.
887 */
888 ar->debug.fwlog_mask = 0;
889
890 ar->debugfs_phy = debugfs_create_dir("ath6kl",
891 ar->wdev->wiphy->debugfsdir);
892 if (!ar->debugfs_phy) {
893 vfree(ar->debug.fwlog_buf.buf);
894 kfree(ar->debug.fwlog_tmp);
895 return -ENOMEM;
896 }
897
898 debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar,
899 &fops_tgt_stats);
900
901 debugfs_create_file("credit_dist_stats", S_IRUSR, ar->debugfs_phy, ar,
902 &fops_credit_dist_stats);
903
904 debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar,
905 &fops_fwlog);
906
907 debugfs_create_file("fwlog_mask", S_IRUSR | S_IWUSR, ar->debugfs_phy,
908 ar, &fops_fwlog_mask);
909
910 debugfs_create_file("reg_addr", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar,
911 &fops_diag_reg_read);
912
913 debugfs_create_file("reg_dump", S_IRUSR, ar->debugfs_phy, ar,
914 &fops_reg_dump);
915
916 debugfs_create_file("lrssi_roam_threshold", S_IRUSR | S_IWUSR,
917 ar->debugfs_phy, ar, &fops_lrssi_roam_threshold);
918
919 debugfs_create_file("reg_write", S_IRUSR | S_IWUSR,
920 ar->debugfs_phy, ar, &fops_diag_reg_write);
921
922 debugfs_create_file("war_stats", S_IRUSR, ar->debugfs_phy, ar,
923 &fops_war_stats);
924
925 return 0;
926}
927
928void ath6kl_debug_cleanup(struct ath6kl *ar)
929{
930 vfree(ar->debug.fwlog_buf.buf);
931 kfree(ar->debug.fwlog_tmp);
932}
933
150#endif 934#endif
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
index 66b399962f01..9288a3ce1e39 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -34,8 +34,12 @@ enum ATH6K_DEBUG_MASK {
34 ATH6KL_DBG_TRC = BIT(11), /* generic func tracing */ 34 ATH6KL_DBG_TRC = BIT(11), /* generic func tracing */
35 ATH6KL_DBG_SCATTER = BIT(12), /* hif scatter tracing */ 35 ATH6KL_DBG_SCATTER = BIT(12), /* hif scatter tracing */
36 ATH6KL_DBG_WLAN_CFG = BIT(13), /* cfg80211 i/f file tracing */ 36 ATH6KL_DBG_WLAN_CFG = BIT(13), /* cfg80211 i/f file tracing */
37 ATH6KL_DBG_RAW_BYTES = BIT(14), /* dump tx/rx and wmi frames */ 37 ATH6KL_DBG_RAW_BYTES = BIT(14), /* dump tx/rx frames */
38 ATH6KL_DBG_AGGR = BIT(15), /* aggregation */ 38 ATH6KL_DBG_AGGR = BIT(15), /* aggregation */
39 ATH6KL_DBG_SDIO = BIT(16),
40 ATH6KL_DBG_SDIO_DUMP = BIT(17),
41 ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */
42 ATH6KL_DBG_WMI_DUMP = BIT(19),
39 ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ 43 ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */
40}; 44};
41 45
@@ -52,6 +56,10 @@ extern int ath6kl_printk(const char *level, const char *fmt, ...)
52 56
53#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask) 57#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask)
54 58
59enum ath6kl_war {
60 ATH6KL_WAR_INVALID_RATE,
61};
62
55#ifdef CONFIG_ATH6KL_DEBUG 63#ifdef CONFIG_ATH6KL_DEBUG
56#define ath6kl_dbg(mask, fmt, ...) \ 64#define ath6kl_dbg(mask, fmt, ...) \
57 ({ \ 65 ({ \
@@ -65,12 +73,14 @@ extern int ath6kl_printk(const char *level, const char *fmt, ...)
65 }) 73 })
66 74
67static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, 75static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
68 const char *msg, const void *buf, 76 const char *msg, const char *prefix,
69 size_t len) 77 const void *buf, size_t len)
70{ 78{
71 if (debug_mask & mask) { 79 if (debug_mask & mask) {
72 ath6kl_dbg(mask, "%s\n", msg); 80 if (msg)
73 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); 81 ath6kl_dbg(mask, "%s\n", msg);
82
83 print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
74 } 84 }
75} 85}
76 86
@@ -78,6 +88,11 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
78 struct ath6kl_irq_proc_registers *irq_proc_reg, 88 struct ath6kl_irq_proc_registers *irq_proc_reg,
79 struct ath6kl_irq_enable_reg *irq_en_reg); 89 struct ath6kl_irq_enable_reg *irq_en_reg);
80void dump_cred_dist_stats(struct htc_target *target); 90void dump_cred_dist_stats(struct htc_target *target);
91void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len);
92void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war);
93int ath6kl_debug_init(struct ath6kl *ar);
94void ath6kl_debug_cleanup(struct ath6kl *ar);
95
81#else 96#else
82static inline int ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask, 97static inline int ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask,
83 const char *fmt, ...) 98 const char *fmt, ...)
@@ -86,8 +101,8 @@ static inline int ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask,
86} 101}
87 102
88static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, 103static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
89 const char *msg, const void *buf, 104 const char *msg, const char *prefix,
90 size_t len) 105 const void *buf, size_t len)
91{ 106{
92} 107}
93 108
@@ -100,6 +115,24 @@ static inline void ath6kl_dump_registers(struct ath6kl_device *dev,
100static inline void dump_cred_dist_stats(struct htc_target *target) 115static inline void dump_cred_dist_stats(struct htc_target *target)
101{ 116{
102} 117}
103#endif
104 118
119static inline void ath6kl_debug_fwlog_event(struct ath6kl *ar,
120 const void *buf, size_t len)
121{
122}
123
124static inline void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war)
125{
126}
127
128static inline int ath6kl_debug_init(struct ath6kl *ar)
129{
130 return 0;
131}
132
133static inline void ath6kl_debug_cleanup(struct ath6kl *ar)
134{
135}
136
137#endif
105#endif 138#endif
diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h
index c923979776a0..d6c898f3d0b3 100644
--- a/drivers/net/wireless/ath/ath6kl/hif-ops.h
+++ b/drivers/net/wireless/ath/ath6kl/hif-ops.h
@@ -69,4 +69,9 @@ static inline void ath6kl_hif_cleanup_scatter(struct ath6kl *ar)
69 return ar->hif_ops->cleanup_scatter(ar); 69 return ar->hif_ops->cleanup_scatter(ar);
70} 70}
71 71
72static inline int ath6kl_hif_suspend(struct ath6kl *ar)
73{
74 return ar->hif_ops->suspend(ar);
75}
76
72#endif 77#endif
diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h
index 5ceff54775a1..797e2d1d9bf9 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.h
+++ b/drivers/net/wireless/ath/ath6kl/hif.h
@@ -202,6 +202,7 @@ struct ath6kl_hif_ops {
202 int (*scat_req_rw) (struct ath6kl *ar, 202 int (*scat_req_rw) (struct ath6kl *ar,
203 struct hif_scatter_req *scat_req); 203 struct hif_scatter_req *scat_req);
204 void (*cleanup_scatter)(struct ath6kl *ar); 204 void (*cleanup_scatter)(struct ath6kl *ar);
205 int (*suspend)(struct ath6kl *ar);
205}; 206};
206 207
207#endif 208#endif
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index a8dc5c3ea567..f88a7c9e4148 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -22,8 +22,19 @@
22 22
23#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask)) 23#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
24 24
25static void htc_prep_send_pkt(struct htc_packet *packet, u8 flags, int ctrl0, 25static void ath6kl_htc_tx_buf_align(u8 **buf, unsigned long len)
26 int ctrl1) 26{
27 u8 *align_addr;
28
29 if (!IS_ALIGNED((unsigned long) *buf, 4)) {
30 align_addr = PTR_ALIGN(*buf - 4, 4);
31 memmove(align_addr, *buf, len);
32 *buf = align_addr;
33 }
34}
35
36static void ath6kl_htc_tx_prep_pkt(struct htc_packet *packet, u8 flags,
37 int ctrl0, int ctrl1)
27{ 38{
28 struct htc_frame_hdr *hdr; 39 struct htc_frame_hdr *hdr;
29 40
@@ -167,7 +178,8 @@ static void htc_async_tx_scat_complete(struct htc_target *target,
167 htc_tx_complete(endpoint, &tx_compq); 178 htc_tx_complete(endpoint, &tx_compq);
168} 179}
169 180
170static int htc_issue_send(struct htc_target *target, struct htc_packet *packet) 181static int ath6kl_htc_tx_issue(struct htc_target *target,
182 struct htc_packet *packet)
171{ 183{
172 int status; 184 int status;
173 bool sync = false; 185 bool sync = false;
@@ -196,7 +208,7 @@ static int htc_issue_send(struct htc_target *target, struct htc_packet *packet)
196 HIF_WR_SYNC_BLOCK_INC); 208 HIF_WR_SYNC_BLOCK_INC);
197 209
198 packet->status = status; 210 packet->status = status;
199 packet->buf += HTC_HDR_LENGTH; 211 packet->buf += HTC_HDR_LENGTH;
200 } else 212 } else
201 status = hif_write_async(target->dev->ar, 213 status = hif_write_async(target->dev->ar,
202 target->dev->ar->mbox_info.htc_addr, 214 target->dev->ar->mbox_info.htc_addr,
@@ -265,9 +277,9 @@ static int htc_check_credits(struct htc_target *target,
265 return 0; 277 return 0;
266} 278}
267 279
268static void htc_tx_pkts_get(struct htc_target *target, 280static void ath6kl_htc_tx_pkts_get(struct htc_target *target,
269 struct htc_endpoint *endpoint, 281 struct htc_endpoint *endpoint,
270 struct list_head *queue) 282 struct list_head *queue)
271{ 283{
272 int req_cred; 284 int req_cred;
273 u8 flags; 285 u8 flags;
@@ -346,11 +358,11 @@ static int htc_get_credit_padding(unsigned int cred_sz, int *len,
346 return cred_pad; 358 return cred_pad;
347} 359}
348 360
349static int htc_setup_send_scat_list(struct htc_target *target, 361static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target,
350 struct htc_endpoint *endpoint, 362 struct htc_endpoint *endpoint,
351 struct hif_scatter_req *scat_req, 363 struct hif_scatter_req *scat_req,
352 int n_scat, 364 int n_scat,
353 struct list_head *queue) 365 struct list_head *queue)
354{ 366{
355 struct htc_packet *packet; 367 struct htc_packet *packet;
356 int i, len, rem_scat, cred_pad; 368 int i, len, rem_scat, cred_pad;
@@ -370,27 +382,23 @@ static int htc_setup_send_scat_list(struct htc_target *target,
370 382
371 cred_pad = htc_get_credit_padding(target->tgt_cred_sz, 383 cred_pad = htc_get_credit_padding(target->tgt_cred_sz,
372 &len, endpoint); 384 &len, endpoint);
373 if (cred_pad < 0) { 385 if (cred_pad < 0 || rem_scat < len) {
374 status = -EINVAL;
375 break;
376 }
377
378 if (rem_scat < len) {
379 /* exceeds what we can transfer */
380 status = -ENOSPC; 386 status = -ENOSPC;
381 break; 387 break;
382 } 388 }
383 389
384 rem_scat -= len; 390 rem_scat -= len;
385 /* now remove it from the queue */ 391 /* now remove it from the queue */
386 packet = list_first_entry(queue, struct htc_packet, list);
387 list_del(&packet->list); 392 list_del(&packet->list);
388 393
389 scat_req->scat_list[i].packet = packet; 394 scat_req->scat_list[i].packet = packet;
390 /* prepare packet and flag message as part of a send bundle */ 395 /* prepare packet and flag message as part of a send bundle */
391 htc_prep_send_pkt(packet, 396 ath6kl_htc_tx_prep_pkt(packet,
392 packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE, 397 packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE,
393 cred_pad, packet->info.tx.seqno); 398 cred_pad, packet->info.tx.seqno);
399 /* Make sure the buffer is 4-byte aligned */
400 ath6kl_htc_tx_buf_align(&packet->buf,
401 packet->act_len + HTC_HDR_LENGTH);
394 scat_req->scat_list[i].buf = packet->buf; 402 scat_req->scat_list[i].buf = packet->buf;
395 scat_req->scat_list[i].len = len; 403 scat_req->scat_list[i].len = len;
396 404
@@ -402,7 +410,7 @@ static int htc_setup_send_scat_list(struct htc_target *target,
402 } 410 }
403 411
404 /* Roll back scatter setup in case of any failure */ 412 /* Roll back scatter setup in case of any failure */
405 if (status || (scat_req->scat_entries < HTC_MIN_HTC_MSGS_TO_BUNDLE)) { 413 if (scat_req->scat_entries < HTC_MIN_HTC_MSGS_TO_BUNDLE) {
406 for (i = scat_req->scat_entries - 1; i >= 0; i--) { 414 for (i = scat_req->scat_entries - 1; i >= 0; i--) {
407 packet = scat_req->scat_list[i].packet; 415 packet = scat_req->scat_list[i].packet;
408 if (packet) { 416 if (packet) {
@@ -410,31 +418,32 @@ static int htc_setup_send_scat_list(struct htc_target *target,
410 list_add(&packet->list, queue); 418 list_add(&packet->list, queue);
411 } 419 }
412 } 420 }
413 return -EINVAL; 421 return -EAGAIN;
414 } 422 }
415 423
416 return 0; 424 return status;
417} 425}
418 426
419/* 427/*
420 * htc_issue_send_bundle: drain a queue and send as bundles 428 * Drain a queue and send as bundles this function may return without fully
421 * this function may return without fully draining the queue 429 * draining the queue when
422 * when
423 * 430 *
424 * 1. scatter resources are exhausted 431 * 1. scatter resources are exhausted
425 * 2. a message that will consume a partial credit will stop the 432 * 2. a message that will consume a partial credit will stop the
426 * bundling process early 433 * bundling process early
427 * 3. we drop below the minimum number of messages for a bundle 434 * 3. we drop below the minimum number of messages for a bundle
428 */ 435 */
429static void htc_issue_send_bundle(struct htc_endpoint *endpoint, 436static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
430 struct list_head *queue, 437 struct list_head *queue,
431 int *sent_bundle, int *n_bundle_pkts) 438 int *sent_bundle, int *n_bundle_pkts)
432{ 439{
433 struct htc_target *target = endpoint->target; 440 struct htc_target *target = endpoint->target;
434 struct hif_scatter_req *scat_req = NULL; 441 struct hif_scatter_req *scat_req = NULL;
435 int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0; 442 int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0;
443 int status;
436 444
437 while (true) { 445 while (true) {
446 status = 0;
438 n_scat = get_queue_depth(queue); 447 n_scat = get_queue_depth(queue);
439 n_scat = min(n_scat, target->msg_per_bndl_max); 448 n_scat = min(n_scat, target->msg_per_bndl_max);
440 449
@@ -457,8 +466,10 @@ static void htc_issue_send_bundle(struct htc_endpoint *endpoint,
457 scat_req->len = 0; 466 scat_req->len = 0;
458 scat_req->scat_entries = 0; 467 scat_req->scat_entries = 0;
459 468
460 if (htc_setup_send_scat_list(target, endpoint, scat_req, 469 status = ath6kl_htc_tx_setup_scat_list(target, endpoint,
461 n_scat, queue)) { 470 scat_req, n_scat,
471 queue);
472 if (status == -EAGAIN) {
462 hif_scatter_req_add(target->dev->ar, scat_req); 473 hif_scatter_req_add(target->dev->ar, scat_req);
463 break; 474 break;
464 } 475 }
@@ -472,18 +483,21 @@ static void htc_issue_send_bundle(struct htc_endpoint *endpoint,
472 "send scatter total bytes: %d , entries: %d\n", 483 "send scatter total bytes: %d , entries: %d\n",
473 scat_req->len, scat_req->scat_entries); 484 scat_req->len, scat_req->scat_entries);
474 ath6kldev_submit_scat_req(target->dev, scat_req, false); 485 ath6kldev_submit_scat_req(target->dev, scat_req, false);
486
487 if (status)
488 break;
475 } 489 }
476 490
477 *sent_bundle = n_sent_bundle; 491 *sent_bundle = n_sent_bundle;
478 *n_bundle_pkts = tot_pkts_bundle; 492 *n_bundle_pkts = tot_pkts_bundle;
479 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "htc_issue_send_bundle (sent:%d)\n", 493 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "%s (sent:%d)\n",
480 n_sent_bundle); 494 __func__, n_sent_bundle);
481 495
482 return; 496 return;
483} 497}
484 498
485static void htc_tx_from_ep_txq(struct htc_target *target, 499static void ath6kl_htc_tx_from_queue(struct htc_target *target,
486 struct htc_endpoint *endpoint) 500 struct htc_endpoint *endpoint)
487{ 501{
488 struct list_head txq; 502 struct list_head txq;
489 struct htc_packet *packet; 503 struct htc_packet *packet;
@@ -511,7 +525,7 @@ static void htc_tx_from_ep_txq(struct htc_target *target,
511 if (list_empty(&endpoint->txq)) 525 if (list_empty(&endpoint->txq))
512 break; 526 break;
513 527
514 htc_tx_pkts_get(target, endpoint, &txq); 528 ath6kl_htc_tx_pkts_get(target, endpoint, &txq);
515 529
516 if (list_empty(&txq)) 530 if (list_empty(&txq))
517 break; 531 break;
@@ -528,8 +542,8 @@ static void htc_tx_from_ep_txq(struct htc_target *target,
528 HTC_MIN_HTC_MSGS_TO_BUNDLE)) { 542 HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
529 int temp1 = 0, temp2 = 0; 543 int temp1 = 0, temp2 = 0;
530 544
531 htc_issue_send_bundle(endpoint, &txq, 545 ath6kl_htc_tx_bundle(endpoint, &txq,
532 &temp1, &temp2); 546 &temp1, &temp2);
533 bundle_sent += temp1; 547 bundle_sent += temp1;
534 n_pkts_bundle += temp2; 548 n_pkts_bundle += temp2;
535 } 549 }
@@ -541,9 +555,9 @@ static void htc_tx_from_ep_txq(struct htc_target *target,
541 list); 555 list);
542 list_del(&packet->list); 556 list_del(&packet->list);
543 557
544 htc_prep_send_pkt(packet, packet->info.tx.flags, 558 ath6kl_htc_tx_prep_pkt(packet, packet->info.tx.flags,
545 0, packet->info.tx.seqno); 559 0, packet->info.tx.seqno);
546 htc_issue_send(target, packet); 560 ath6kl_htc_tx_issue(target, packet);
547 } 561 }
548 562
549 spin_lock_bh(&target->tx_lock); 563 spin_lock_bh(&target->tx_lock);
@@ -556,9 +570,9 @@ static void htc_tx_from_ep_txq(struct htc_target *target,
556 spin_unlock_bh(&target->tx_lock); 570 spin_unlock_bh(&target->tx_lock);
557} 571}
558 572
559static bool htc_try_send(struct htc_target *target, 573static bool ath6kl_htc_tx_try(struct htc_target *target,
560 struct htc_endpoint *endpoint, 574 struct htc_endpoint *endpoint,
561 struct htc_packet *tx_pkt) 575 struct htc_packet *tx_pkt)
562{ 576{
563 struct htc_ep_callbacks ep_cb; 577 struct htc_ep_callbacks ep_cb;
564 int txq_depth; 578 int txq_depth;
@@ -594,7 +608,7 @@ static bool htc_try_send(struct htc_target *target,
594 list_add_tail(&tx_pkt->list, &endpoint->txq); 608 list_add_tail(&tx_pkt->list, &endpoint->txq);
595 spin_unlock_bh(&target->tx_lock); 609 spin_unlock_bh(&target->tx_lock);
596 610
597 htc_tx_from_ep_txq(target, endpoint); 611 ath6kl_htc_tx_from_queue(target, endpoint);
598 612
599 return true; 613 return true;
600} 614}
@@ -628,7 +642,7 @@ static void htc_chk_ep_txq(struct htc_target *target)
628 * chance to reclaim credits from lower priority 642 * chance to reclaim credits from lower priority
629 * ones. 643 * ones.
630 */ 644 */
631 htc_tx_from_ep_txq(target, endpoint); 645 ath6kl_htc_tx_from_queue(target, endpoint);
632 spin_lock_bh(&target->tx_lock); 646 spin_lock_bh(&target->tx_lock);
633 } 647 }
634 spin_unlock_bh(&target->tx_lock); 648 spin_unlock_bh(&target->tx_lock);
@@ -680,8 +694,8 @@ static int htc_setup_tx_complete(struct htc_target *target)
680 694
681 /* we want synchronous operation */ 695 /* we want synchronous operation */
682 send_pkt->completion = NULL; 696 send_pkt->completion = NULL;
683 htc_prep_send_pkt(send_pkt, 0, 0, 0); 697 ath6kl_htc_tx_prep_pkt(send_pkt, 0, 0, 0);
684 status = htc_issue_send(target, send_pkt); 698 status = ath6kl_htc_tx_issue(target, send_pkt);
685 699
686 if (send_pkt != NULL) 700 if (send_pkt != NULL)
687 htc_reclaim_txctrl_buf(target, send_pkt); 701 htc_reclaim_txctrl_buf(target, send_pkt);
@@ -733,7 +747,7 @@ int ath6kl_htc_tx(struct htc_target *target, struct htc_packet *packet)
733 747
734 endpoint = &target->endpoint[packet->endpoint]; 748 endpoint = &target->endpoint[packet->endpoint];
735 749
736 if (!htc_try_send(target, endpoint, packet)) { 750 if (!ath6kl_htc_tx_try(target, endpoint, packet)) {
737 packet->status = (target->htc_flags & HTC_OP_STATE_STOPPING) ? 751 packet->status = (target->htc_flags & HTC_OP_STATE_STOPPING) ?
738 -ECANCELED : -ENOSPC; 752 -ECANCELED : -ENOSPC;
739 INIT_LIST_HEAD(&queue); 753 INIT_LIST_HEAD(&queue);
@@ -846,8 +860,8 @@ void ath6kl_htc_indicate_activity_change(struct htc_target *target,
846 860
847/* HTC Rx */ 861/* HTC Rx */
848 862
849static inline void htc_update_rx_stats(struct htc_endpoint *endpoint, 863static inline void ath6kl_htc_rx_update_stats(struct htc_endpoint *endpoint,
850 int n_look_ahds) 864 int n_look_ahds)
851{ 865{
852 endpoint->ep_st.rx_pkts++; 866 endpoint->ep_st.rx_pkts++;
853 if (n_look_ahds == 1) 867 if (n_look_ahds == 1)
@@ -894,8 +908,9 @@ static void reclaim_rx_ctrl_buf(struct htc_target *target,
894 spin_unlock_bh(&target->htc_lock); 908 spin_unlock_bh(&target->htc_lock);
895} 909}
896 910
897static int dev_rx_pkt(struct htc_target *target, struct htc_packet *packet, 911static int ath6kl_htc_rx_packet(struct htc_target *target,
898 u32 rx_len) 912 struct htc_packet *packet,
913 u32 rx_len)
899{ 914{
900 struct ath6kl_device *dev = target->dev; 915 struct ath6kl_device *dev = target->dev;
901 u32 padded_len; 916 u32 padded_len;
@@ -929,9 +944,9 @@ static int dev_rx_pkt(struct htc_target *target, struct htc_packet *packet,
929 * "hint" that there are more single-packets to fetch 944 * "hint" that there are more single-packets to fetch
930 * on this endpoint. 945 * on this endpoint.
931 */ 946 */
932static void set_rxpkt_indication_flag(u32 lk_ahd, 947static void ath6kl_htc_rx_set_indicate(u32 lk_ahd,
933 struct htc_endpoint *endpoint, 948 struct htc_endpoint *endpoint,
934 struct htc_packet *packet) 949 struct htc_packet *packet)
935{ 950{
936 struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)&lk_ahd; 951 struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)&lk_ahd;
937 952
@@ -942,7 +957,7 @@ static void set_rxpkt_indication_flag(u32 lk_ahd,
942 } 957 }
943} 958}
944 959
945static void chk_rx_water_mark(struct htc_endpoint *endpoint) 960static void ath6kl_htc_rx_chk_water_mark(struct htc_endpoint *endpoint)
946{ 961{
947 struct htc_ep_callbacks ep_cb = endpoint->ep_cb; 962 struct htc_ep_callbacks ep_cb = endpoint->ep_cb;
948 963
@@ -959,8 +974,9 @@ static void chk_rx_water_mark(struct htc_endpoint *endpoint)
959} 974}
960 975
961/* This function is called with rx_lock held */ 976/* This function is called with rx_lock held */
962static int htc_setup_rxpkts(struct htc_target *target, struct htc_endpoint *ep, 977static int ath6kl_htc_rx_setup(struct htc_target *target,
963 u32 *lk_ahds, struct list_head *queue, int n_msg) 978 struct htc_endpoint *ep,
979 u32 *lk_ahds, struct list_head *queue, int n_msg)
964{ 980{
965 struct htc_packet *packet; 981 struct htc_packet *packet;
966 /* FIXME: type of lk_ahds can't be right */ 982 /* FIXME: type of lk_ahds can't be right */
@@ -1060,10 +1076,10 @@ static int htc_setup_rxpkts(struct htc_target *target, struct htc_endpoint *ep,
1060 return status; 1076 return status;
1061} 1077}
1062 1078
1063static int alloc_and_prep_rxpkts(struct htc_target *target, 1079static int ath6kl_htc_rx_alloc(struct htc_target *target,
1064 u32 lk_ahds[], int msg, 1080 u32 lk_ahds[], int msg,
1065 struct htc_endpoint *endpoint, 1081 struct htc_endpoint *endpoint,
1066 struct list_head *queue) 1082 struct list_head *queue)
1067{ 1083{
1068 int status = 0; 1084 int status = 0;
1069 struct htc_packet *packet, *tmp_pkt; 1085 struct htc_packet *packet, *tmp_pkt;
@@ -1129,8 +1145,8 @@ static int alloc_and_prep_rxpkts(struct htc_target *target,
1129 n_msg = 1; 1145 n_msg = 1;
1130 1146
1131 /* Setup packet buffers for each message */ 1147 /* Setup packet buffers for each message */
1132 status = htc_setup_rxpkts(target, endpoint, &lk_ahds[i], queue, 1148 status = ath6kl_htc_rx_setup(target, endpoint, &lk_ahds[i],
1133 n_msg); 1149 queue, n_msg);
1134 1150
1135 /* 1151 /*
1136 * This is due to unavailabilty of buffers to rx entire data. 1152 * This is due to unavailabilty of buffers to rx entire data.
@@ -1176,9 +1192,9 @@ static void htc_ctrl_rx(struct htc_target *context, struct htc_packet *packets)
1176 packets->act_len + HTC_HDR_LENGTH); 1192 packets->act_len + HTC_HDR_LENGTH);
1177 1193
1178 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, 1194 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES,
1179 "Unexpected ENDPOINT 0 Message", 1195 "Unexpected ENDPOINT 0 Message", "",
1180 packets->buf - HTC_HDR_LENGTH, 1196 packets->buf - HTC_HDR_LENGTH,
1181 packets->act_len + HTC_HDR_LENGTH); 1197 packets->act_len + HTC_HDR_LENGTH);
1182 } 1198 }
1183 1199
1184 htc_reclaim_rxbuf(context, packets, &context->endpoint[0]); 1200 htc_reclaim_rxbuf(context, packets, &context->endpoint[0]);
@@ -1312,7 +1328,7 @@ static int htc_parse_trailer(struct htc_target *target,
1312 memcpy((u8 *)&next_lk_ahds[0], lk_ahd->lk_ahd, 4); 1328 memcpy((u8 *)&next_lk_ahds[0], lk_ahd->lk_ahd, 4);
1313 1329
1314 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Next Look Ahead", 1330 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Next Look Ahead",
1315 next_lk_ahds, 4); 1331 "", next_lk_ahds, 4);
1316 1332
1317 *n_lk_ahds = 1; 1333 *n_lk_ahds = 1;
1318 } 1334 }
@@ -1331,7 +1347,7 @@ static int htc_parse_trailer(struct htc_target *target,
1331 (struct htc_bundle_lkahd_rpt *) record_buf; 1347 (struct htc_bundle_lkahd_rpt *) record_buf;
1332 1348
1333 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Bundle lk_ahd", 1349 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Bundle lk_ahd",
1334 record_buf, record->len); 1350 "", record_buf, record->len);
1335 1351
1336 for (i = 0; i < len; i++) { 1352 for (i = 0; i < len; i++) {
1337 memcpy((u8 *)&next_lk_ahds[i], 1353 memcpy((u8 *)&next_lk_ahds[i],
@@ -1364,7 +1380,8 @@ static int htc_proc_trailer(struct htc_target *target,
1364 1380
1365 ath6kl_dbg(ATH6KL_DBG_HTC_RECV, "+htc_proc_trailer (len:%d)\n", len); 1381 ath6kl_dbg(ATH6KL_DBG_HTC_RECV, "+htc_proc_trailer (len:%d)\n", len);
1366 1382
1367 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Recv Trailer", buf, len); 1383 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Recv Trailer", "",
1384 buf, len);
1368 1385
1369 orig_buf = buf; 1386 orig_buf = buf;
1370 orig_len = len; 1387 orig_len = len;
@@ -1402,14 +1419,14 @@ static int htc_proc_trailer(struct htc_target *target,
1402 1419
1403 if (status) 1420 if (status)
1404 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "BAD Recv Trailer", 1421 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "BAD Recv Trailer",
1405 orig_buf, orig_len); 1422 "", orig_buf, orig_len);
1406 1423
1407 return status; 1424 return status;
1408} 1425}
1409 1426
1410static int htc_proc_rxhdr(struct htc_target *target, 1427static int ath6kl_htc_rx_process_hdr(struct htc_target *target,
1411 struct htc_packet *packet, 1428 struct htc_packet *packet,
1412 u32 *next_lkahds, int *n_lkahds) 1429 u32 *next_lkahds, int *n_lkahds)
1413{ 1430{
1414 int status = 0; 1431 int status = 0;
1415 u16 payload_len; 1432 u16 payload_len;
@@ -1419,8 +1436,8 @@ static int htc_proc_rxhdr(struct htc_target *target,
1419 if (n_lkahds != NULL) 1436 if (n_lkahds != NULL)
1420 *n_lkahds = 0; 1437 *n_lkahds = 0;
1421 1438
1422 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "HTC Recv PKT", packet->buf, 1439 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "HTC Recv PKT", "htc ",
1423 packet->act_len); 1440 packet->buf, packet->act_len);
1424 1441
1425 /* 1442 /*
1426 * NOTE: we cannot assume the alignment of buf, so we use the safe 1443 * NOTE: we cannot assume the alignment of buf, so we use the safe
@@ -1461,12 +1478,12 @@ static int htc_proc_rxhdr(struct htc_target *target,
1461 } 1478 }
1462 1479
1463 if (lk_ahd != packet->info.rx.exp_hdr) { 1480 if (lk_ahd != packet->info.rx.exp_hdr) {
1464 ath6kl_err("htc_proc_rxhdr, lk_ahd mismatch! (pPkt:0x%p flags:0x%X)\n", 1481 ath6kl_err("%s(): lk_ahd mismatch! (pPkt:0x%p flags:0x%X)\n",
1465 packet, packet->info.rx.rx_flags); 1482 __func__, packet, packet->info.rx.rx_flags);
1466 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Expected Message lk_ahd", 1483 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Expected Message lk_ahd",
1467 &packet->info.rx.exp_hdr, 4); 1484 "", &packet->info.rx.exp_hdr, 4);
1468 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Current Frame Header", 1485 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Current Frame Header",
1469 (u8 *)&lk_ahd, sizeof(lk_ahd)); 1486 "", (u8 *)&lk_ahd, sizeof(lk_ahd));
1470 status = -ENOMEM; 1487 status = -ENOMEM;
1471 goto fail_rx; 1488 goto fail_rx;
1472 } 1489 }
@@ -1474,8 +1491,8 @@ static int htc_proc_rxhdr(struct htc_target *target,
1474 if (htc_hdr->flags & HTC_FLG_RX_TRAILER) { 1491 if (htc_hdr->flags & HTC_FLG_RX_TRAILER) {
1475 if (htc_hdr->ctrl[0] < sizeof(struct htc_record_hdr) || 1492 if (htc_hdr->ctrl[0] < sizeof(struct htc_record_hdr) ||
1476 htc_hdr->ctrl[0] > payload_len) { 1493 htc_hdr->ctrl[0] > payload_len) {
1477 ath6kl_err("htc_proc_rxhdr, invalid hdr (payload len should be :%d, CB[0] is:%d)\n", 1494 ath6kl_err("%s(): invalid hdr (payload len should be :%d, CB[0] is:%d)\n",
1478 payload_len, htc_hdr->ctrl[0]); 1495 __func__, payload_len, htc_hdr->ctrl[0]);
1479 status = -ENOMEM; 1496 status = -ENOMEM;
1480 goto fail_rx; 1497 goto fail_rx;
1481 } 1498 }
@@ -1502,20 +1519,20 @@ static int htc_proc_rxhdr(struct htc_target *target,
1502fail_rx: 1519fail_rx:
1503 if (status) 1520 if (status)
1504 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "BAD HTC Recv PKT", 1521 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "BAD HTC Recv PKT",
1505 packet->buf, 1522 "", packet->buf,
1506 packet->act_len < 256 ? packet->act_len : 256); 1523 packet->act_len < 256 ? packet->act_len : 256);
1507 else { 1524 else {
1508 if (packet->act_len > 0) 1525 if (packet->act_len > 0)
1509 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, 1526 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES,
1510 "HTC - Application Msg", 1527 "HTC - Application Msg", "",
1511 packet->buf, packet->act_len); 1528 packet->buf, packet->act_len);
1512 } 1529 }
1513 1530
1514 return status; 1531 return status;
1515} 1532}
1516 1533
1517static void do_rx_completion(struct htc_endpoint *endpoint, 1534static void ath6kl_htc_rx_complete(struct htc_endpoint *endpoint,
1518 struct htc_packet *packet) 1535 struct htc_packet *packet)
1519{ 1536{
1520 ath6kl_dbg(ATH6KL_DBG_HTC_RECV, 1537 ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
1521 "htc calling ep %d recv callback on packet 0x%p\n", 1538 "htc calling ep %d recv callback on packet 0x%p\n",
@@ -1523,10 +1540,10 @@ static void do_rx_completion(struct htc_endpoint *endpoint,
1523 endpoint->ep_cb.rx(endpoint->target, packet); 1540 endpoint->ep_cb.rx(endpoint->target, packet);
1524} 1541}
1525 1542
1526static int htc_issue_rxpkt_bundle(struct htc_target *target, 1543static int ath6kl_htc_rx_bundle(struct htc_target *target,
1527 struct list_head *rxq, 1544 struct list_head *rxq,
1528 struct list_head *sync_compq, 1545 struct list_head *sync_compq,
1529 int *n_pkt_fetched, bool part_bundle) 1546 int *n_pkt_fetched, bool part_bundle)
1530{ 1547{
1531 struct hif_scatter_req *scat_req; 1548 struct hif_scatter_req *scat_req;
1532 struct htc_packet *packet; 1549 struct htc_packet *packet;
@@ -1548,15 +1565,15 @@ static int htc_issue_rxpkt_bundle(struct htc_target *target,
1548 * This would only happen if the target ignored our max 1565 * This would only happen if the target ignored our max
1549 * bundle limit. 1566 * bundle limit.
1550 */ 1567 */
1551 ath6kl_warn("htc_issue_rxpkt_bundle : partial bundle detected num:%d , %d\n", 1568 ath6kl_warn("%s(): partial bundle detected num:%d , %d\n",
1552 get_queue_depth(rxq), n_scat_pkt); 1569 __func__, get_queue_depth(rxq), n_scat_pkt);
1553 } 1570 }
1554 1571
1555 len = 0; 1572 len = 0;
1556 1573
1557 ath6kl_dbg(ATH6KL_DBG_HTC_RECV, 1574 ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
1558 "htc_issue_rxpkt_bundle (numpackets: %d , actual : %d)\n", 1575 "%s(): (numpackets: %d , actual : %d)\n",
1559 get_queue_depth(rxq), n_scat_pkt); 1576 __func__, get_queue_depth(rxq), n_scat_pkt);
1560 1577
1561 scat_req = hif_scatter_req_get(target->dev->ar); 1578 scat_req = hif_scatter_req_get(target->dev->ar);
1562 1579
@@ -1616,9 +1633,10 @@ fail_rx_pkt:
1616 return status; 1633 return status;
1617} 1634}
1618 1635
1619static int htc_proc_fetched_rxpkts(struct htc_target *target, 1636static int ath6kl_htc_rx_process_packets(struct htc_target *target,
1620 struct list_head *comp_pktq, u32 lk_ahds[], 1637 struct list_head *comp_pktq,
1621 int *n_lk_ahd) 1638 u32 lk_ahds[],
1639 int *n_lk_ahd)
1622{ 1640{
1623 struct htc_packet *packet, *tmp_pkt; 1641 struct htc_packet *packet, *tmp_pkt;
1624 struct htc_endpoint *ep; 1642 struct htc_endpoint *ep;
@@ -1629,7 +1647,8 @@ static int htc_proc_fetched_rxpkts(struct htc_target *target,
1629 ep = &target->endpoint[packet->endpoint]; 1647 ep = &target->endpoint[packet->endpoint];
1630 1648
1631 /* process header for each of the recv packet */ 1649 /* process header for each of the recv packet */
1632 status = htc_proc_rxhdr(target, packet, lk_ahds, n_lk_ahd); 1650 status = ath6kl_htc_rx_process_hdr(target, packet, lk_ahds,
1651 n_lk_ahd);
1633 if (status) 1652 if (status)
1634 return status; 1653 return status;
1635 1654
@@ -1639,8 +1658,8 @@ static int htc_proc_fetched_rxpkts(struct htc_target *target,
1639 * based on the lookahead. 1658 * based on the lookahead.
1640 */ 1659 */
1641 if (*n_lk_ahd > 0) 1660 if (*n_lk_ahd > 0)
1642 set_rxpkt_indication_flag(lk_ahds[0], 1661 ath6kl_htc_rx_set_indicate(lk_ahds[0],
1643 ep, packet); 1662 ep, packet);
1644 } else 1663 } else
1645 /* 1664 /*
1646 * Packets in a bundle automatically have 1665 * Packets in a bundle automatically have
@@ -1649,20 +1668,20 @@ static int htc_proc_fetched_rxpkts(struct htc_target *target,
1649 packet->info.rx.indicat_flags |= 1668 packet->info.rx.indicat_flags |=
1650 HTC_RX_FLAGS_INDICATE_MORE_PKTS; 1669 HTC_RX_FLAGS_INDICATE_MORE_PKTS;
1651 1670
1652 htc_update_rx_stats(ep, *n_lk_ahd); 1671 ath6kl_htc_rx_update_stats(ep, *n_lk_ahd);
1653 1672
1654 if (packet->info.rx.rx_flags & HTC_RX_PKT_PART_OF_BUNDLE) 1673 if (packet->info.rx.rx_flags & HTC_RX_PKT_PART_OF_BUNDLE)
1655 ep->ep_st.rx_bundl += 1; 1674 ep->ep_st.rx_bundl += 1;
1656 1675
1657 do_rx_completion(ep, packet); 1676 ath6kl_htc_rx_complete(ep, packet);
1658 } 1677 }
1659 1678
1660 return status; 1679 return status;
1661} 1680}
1662 1681
1663static int htc_fetch_rxpkts(struct htc_target *target, 1682static int ath6kl_htc_rx_fetch(struct htc_target *target,
1664 struct list_head *rx_pktq, 1683 struct list_head *rx_pktq,
1665 struct list_head *comp_pktq) 1684 struct list_head *comp_pktq)
1666{ 1685{
1667 int fetched_pkts; 1686 int fetched_pkts;
1668 bool part_bundle = false; 1687 bool part_bundle = false;
@@ -1678,10 +1697,10 @@ static int htc_fetch_rxpkts(struct htc_target *target,
1678 * bundle transfer and recv bundling is 1697 * bundle transfer and recv bundling is
1679 * allowed. 1698 * allowed.
1680 */ 1699 */
1681 status = htc_issue_rxpkt_bundle(target, rx_pktq, 1700 status = ath6kl_htc_rx_bundle(target, rx_pktq,
1682 comp_pktq, 1701 comp_pktq,
1683 &fetched_pkts, 1702 &fetched_pkts,
1684 part_bundle); 1703 part_bundle);
1685 if (status) 1704 if (status)
1686 return status; 1705 return status;
1687 1706
@@ -1710,7 +1729,8 @@ static int htc_fetch_rxpkts(struct htc_target *target,
1710 HTC_RX_PKT_IGNORE_LOOKAHEAD; 1729 HTC_RX_PKT_IGNORE_LOOKAHEAD;
1711 1730
1712 /* go fetch the packet */ 1731 /* go fetch the packet */
1713 status = dev_rx_pkt(target, packet, packet->act_len); 1732 status = ath6kl_htc_rx_packet(target, packet,
1733 packet->act_len);
1714 if (status) 1734 if (status)
1715 return status; 1735 return status;
1716 1736
@@ -1764,9 +1784,9 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
1764 * Try to allocate as many HTC RX packets indicated by the 1784 * Try to allocate as many HTC RX packets indicated by the
1765 * look_aheads. 1785 * look_aheads.
1766 */ 1786 */
1767 status = alloc_and_prep_rxpkts(target, look_aheads, 1787 status = ath6kl_htc_rx_alloc(target, look_aheads,
1768 num_look_ahead, endpoint, 1788 num_look_ahead, endpoint,
1769 &rx_pktq); 1789 &rx_pktq);
1770 if (status) 1790 if (status)
1771 break; 1791 break;
1772 1792
@@ -1781,14 +1801,15 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
1781 1801
1782 num_look_ahead = 0; 1802 num_look_ahead = 0;
1783 1803
1784 status = htc_fetch_rxpkts(target, &rx_pktq, &comp_pktq); 1804 status = ath6kl_htc_rx_fetch(target, &rx_pktq, &comp_pktq);
1785 1805
1786 if (!status) 1806 if (!status)
1787 chk_rx_water_mark(endpoint); 1807 ath6kl_htc_rx_chk_water_mark(endpoint);
1788 1808
1789 /* Process fetched packets */ 1809 /* Process fetched packets */
1790 status = htc_proc_fetched_rxpkts(target, &comp_pktq, 1810 status = ath6kl_htc_rx_process_packets(target, &comp_pktq,
1791 look_aheads, &num_look_ahead); 1811 look_aheads,
1812 &num_look_ahead);
1792 1813
1793 if (!num_look_ahead || status) 1814 if (!num_look_ahead || status)
1794 break; 1815 break;
@@ -1881,14 +1902,14 @@ static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target)
1881 packet->completion = NULL; 1902 packet->completion = NULL;
1882 1903
1883 /* get the message from the device, this will block */ 1904 /* get the message from the device, this will block */
1884 if (dev_rx_pkt(target, packet, packet->act_len)) 1905 if (ath6kl_htc_rx_packet(target, packet, packet->act_len))
1885 goto fail_ctrl_rx; 1906 goto fail_ctrl_rx;
1886 1907
1887 /* process receive header */ 1908 /* process receive header */
1888 packet->status = htc_proc_rxhdr(target, packet, NULL, NULL); 1909 packet->status = ath6kl_htc_rx_process_hdr(target, packet, NULL, NULL);
1889 1910
1890 if (packet->status) { 1911 if (packet->status) {
1891 ath6kl_err("htc_wait_for_ctrl_msg, htc_proc_rxhdr failed (status = %d)\n", 1912 ath6kl_err("htc_wait_for_ctrl_msg, ath6kl_htc_rx_process_hdr failed (status = %d)\n",
1892 packet->status); 1913 packet->status);
1893 goto fail_ctrl_rx; 1914 goto fail_ctrl_rx;
1894 } 1915 }
@@ -1935,7 +1956,7 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
1935 list_for_each_entry_safe(packet, tmp_pkt, pkt_queue, list) { 1956 list_for_each_entry_safe(packet, tmp_pkt, pkt_queue, list) {
1936 packet->status = -ECANCELED; 1957 packet->status = -ECANCELED;
1937 list_del(&packet->list); 1958 list_del(&packet->list);
1938 do_rx_completion(endpoint, packet); 1959 ath6kl_htc_rx_complete(endpoint, packet);
1939 } 1960 }
1940 1961
1941 return status; 1962 return status;
@@ -2034,8 +2055,8 @@ int ath6kl_htc_conn_service(struct htc_target *target,
2034 2055
2035 /* we want synchronous operation */ 2056 /* we want synchronous operation */
2036 tx_pkt->completion = NULL; 2057 tx_pkt->completion = NULL;
2037 htc_prep_send_pkt(tx_pkt, 0, 0, 0); 2058 ath6kl_htc_tx_prep_pkt(tx_pkt, 0, 0, 0);
2038 status = htc_issue_send(target, tx_pkt); 2059 status = ath6kl_htc_tx_issue(target, tx_pkt);
2039 2060
2040 if (status) 2061 if (status)
2041 goto fail_tx; 2062 goto fail_tx;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 9d10322eac41..c1d2366704b5 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -15,6 +15,8 @@
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */ 16 */
17 17
18#include <linux/moduleparam.h>
19#include <linux/of.h>
18#include <linux/mmc/sdio_func.h> 20#include <linux/mmc/sdio_func.h>
19#include "core.h" 21#include "core.h"
20#include "cfg80211.h" 22#include "cfg80211.h"
@@ -23,8 +25,10 @@
23#include "hif-ops.h" 25#include "hif-ops.h"
24 26
25unsigned int debug_mask; 27unsigned int debug_mask;
28static unsigned int testmode;
26 29
27module_param(debug_mask, uint, 0644); 30module_param(debug_mask, uint, 0644);
31module_param(testmode, uint, 0644);
28 32
29/* 33/*
30 * Include definitions here that can be used to tune the WLAN module 34 * Include definitions here that can be used to tune the WLAN module
@@ -53,12 +57,6 @@ module_param(debug_mask, uint, 0644);
53 57
54#define CONFIG_AR600x_DEBUG_UART_TX_PIN 8 58#define CONFIG_AR600x_DEBUG_UART_TX_PIN 8
55 59
56enum addr_type {
57 DATASET_PATCH_ADDR,
58 APP_LOAD_ADDR,
59 APP_START_OVERRIDE_ADDR,
60};
61
62#define ATH6KL_DATA_OFFSET 64 60#define ATH6KL_DATA_OFFSET 64
63struct sk_buff *ath6kl_buf_alloc(int size) 61struct sk_buff *ath6kl_buf_alloc(int size)
64{ 62{
@@ -67,7 +65,7 @@ struct sk_buff *ath6kl_buf_alloc(int size)
67 65
68 /* Add chacheline space at front and back of buffer */ 66 /* Add chacheline space at front and back of buffer */
69 reserved = (2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET + 67 reserved = (2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
70 sizeof(struct htc_packet); 68 sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES;
71 skb = dev_alloc_skb(size + reserved); 69 skb = dev_alloc_skb(size + reserved);
72 70
73 if (skb) 71 if (skb)
@@ -85,7 +83,7 @@ void ath6kl_init_profile_info(struct ath6kl *ar)
85 ar->prwise_crypto = NONE_CRYPT; 83 ar->prwise_crypto = NONE_CRYPT;
86 ar->prwise_crypto_len = 0; 84 ar->prwise_crypto_len = 0;
87 ar->grp_crypto = NONE_CRYPT; 85 ar->grp_crypto = NONE_CRYPT;
88 ar->grp_crpto_len = 0; 86 ar->grp_crypto_len = 0;
89 memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list)); 87 memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
90 memset(ar->req_bssid, 0, sizeof(ar->req_bssid)); 88 memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
91 memset(ar->bssid, 0, sizeof(ar->bssid)); 89 memset(ar->bssid, 0, sizeof(ar->bssid));
@@ -108,17 +106,6 @@ static u8 ath6kl_get_fw_iftype(struct ath6kl *ar)
108 } 106 }
109} 107}
110 108
111static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
112 u32 item_offset)
113{
114 u32 addr = 0;
115
116 if (ar->target_type == TARGET_TYPE_AR6003)
117 addr = ATH6KL_HI_START_ADDR + item_offset;
118
119 return addr;
120}
121
122static int ath6kl_set_host_app_area(struct ath6kl *ar) 109static int ath6kl_set_host_app_area(struct ath6kl *ar)
123{ 110{
124 u32 address, data; 111 u32 address, data;
@@ -127,16 +114,15 @@ static int ath6kl_set_host_app_area(struct ath6kl *ar)
127 /* Fetch the address of the host_app_area_s 114 /* Fetch the address of the host_app_area_s
128 * instance in the host interest area */ 115 * instance in the host interest area */
129 address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_app_host_interest)); 116 address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_app_host_interest));
130 address = TARG_VTOP(address); 117 address = TARG_VTOP(ar->target_type, address);
131 118
132 if (ath6kl_read_reg_diag(ar, &address, &data)) 119 if (ath6kl_diag_read32(ar, address, &data))
133 return -EIO; 120 return -EIO;
134 121
135 address = TARG_VTOP(data); 122 address = TARG_VTOP(ar->target_type, data);
136 host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION; 123 host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION;
137 if (ath6kl_access_datadiag(ar, address, 124 if (ath6kl_diag_write(ar, address, (u8 *) &host_app_area,
138 (u8 *)&host_app_area, 125 sizeof(struct host_app_area)))
139 sizeof(struct host_app_area), false))
140 return -EIO; 126 return -EIO;
141 127
142 return 0; 128 return 0;
@@ -290,6 +276,7 @@ static void ath6kl_init_control_info(struct ath6kl *ar)
290 memset(&ar->sc_params, 0, sizeof(ar->sc_params)); 276 memset(&ar->sc_params, 0, sizeof(ar->sc_params));
291 ar->sc_params.short_scan_ratio = WMI_SHORTSCANRATIO_DEFAULT; 277 ar->sc_params.short_scan_ratio = WMI_SHORTSCANRATIO_DEFAULT;
292 ar->sc_params.scan_ctrl_flags = DEFAULT_SCAN_CTRL_FLAGS; 278 ar->sc_params.scan_ctrl_flags = DEFAULT_SCAN_CTRL_FLAGS;
279 ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD;
293 280
294 memset((u8 *)ar->sta_list, 0, 281 memset((u8 *)ar->sta_list, 0,
295 AP_MAX_NUM_STA * sizeof(struct ath6kl_sta)); 282 AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
@@ -370,10 +357,10 @@ static void ath6kl_dump_target_assert_info(struct ath6kl *ar)
370 357
371 /* the reg dump pointer is copied to the host interest area */ 358 /* the reg dump pointer is copied to the host interest area */
372 address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state)); 359 address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state));
373 address = TARG_VTOP(address); 360 address = TARG_VTOP(ar->target_type, address);
374 361
375 /* read RAM location through diagnostic window */ 362 /* read RAM location through diagnostic window */
376 status = ath6kl_read_reg_diag(ar, &address, &regdump_loc); 363 status = ath6kl_diag_read32(ar, address, &regdump_loc);
377 364
378 if (status || !regdump_loc) { 365 if (status || !regdump_loc) {
379 ath6kl_err("failed to get ptr to register dump area\n"); 366 ath6kl_err("failed to get ptr to register dump area\n");
@@ -382,15 +369,11 @@ static void ath6kl_dump_target_assert_info(struct ath6kl *ar)
382 369
383 ath6kl_dbg(ATH6KL_DBG_TRC, "location of register dump data: 0x%X\n", 370 ath6kl_dbg(ATH6KL_DBG_TRC, "location of register dump data: 0x%X\n",
384 regdump_loc); 371 regdump_loc);
385 372 regdump_loc = TARG_VTOP(ar->target_type, regdump_loc);
386 regdump_loc = TARG_VTOP(regdump_loc);
387 373
388 /* fetch register dump data */ 374 /* fetch register dump data */
389 status = ath6kl_access_datadiag(ar, 375 status = ath6kl_diag_read(ar, regdump_loc, (u8 *)&regdump_val[0],
390 regdump_loc, 376 REG_DUMP_COUNT_AR6003 * (sizeof(u32)));
391 (u8 *)&regdump_val[0],
392 REG_DUMP_COUNT_AR6003 * (sizeof(u32)),
393 true);
394 377
395 if (status) { 378 if (status) {
396 ath6kl_err("failed to get register dump\n"); 379 ath6kl_err("failed to get register dump\n");
@@ -416,6 +399,7 @@ void ath6kl_target_failure(struct ath6kl *ar)
416static int ath6kl_target_config_wlan_params(struct ath6kl *ar) 399static int ath6kl_target_config_wlan_params(struct ath6kl *ar)
417{ 400{
418 int status = 0; 401 int status = 0;
402 int ret;
419 403
420 /* 404 /*
421 * Configure the device for rx dot11 header rules. "0,0" are the 405 * Configure the device for rx dot11 header rules. "0,0" are the
@@ -460,6 +444,28 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar)
460 status = -EIO; 444 status = -EIO;
461 } 445 }
462 446
447 if (ar->p2p) {
448 ret = ath6kl_wmi_info_req_cmd(ar->wmi,
449 P2P_FLAG_CAPABILITIES_REQ |
450 P2P_FLAG_MACADDR_REQ |
451 P2P_FLAG_HMODEL_REQ);
452 if (ret) {
453 ath6kl_dbg(ATH6KL_DBG_TRC, "failed to request P2P "
454 "capabilities (%d) - assuming P2P not "
455 "supported\n", ret);
456 ar->p2p = 0;
457 }
458 }
459
460 if (ar->p2p) {
461 /* Enable Probe Request reporting for P2P */
462 ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, true);
463 if (ret) {
464 ath6kl_dbg(ATH6KL_DBG_TRC, "failed to enable Probe "
465 "Request reporting (%d)\n", ret);
466 }
467 }
468
463 return status; 469 return status;
464} 470}
465 471
@@ -495,6 +501,10 @@ int ath6kl_configure_target(struct ath6kl *ar)
495 501
496 param |= (1 << HI_OPTION_NUM_DEV_SHIFT); 502 param |= (1 << HI_OPTION_NUM_DEV_SHIFT);
497 param |= (fw_iftype << HI_OPTION_FW_MODE_SHIFT); 503 param |= (fw_iftype << HI_OPTION_FW_MODE_SHIFT);
504 if (ar->p2p && fw_iftype == HI_OPTION_FW_MODE_BSS_STA) {
505 param |= HI_OPTION_FW_SUBMODE_P2PDEV <<
506 HI_OPTION_FW_SUBMODE_SHIFT;
507 }
498 param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT); 508 param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
499 param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT); 509 param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
500 510
@@ -518,29 +528,21 @@ int ath6kl_configure_target(struct ath6kl *ar)
518 * but possible in theory. 528 * but possible in theory.
519 */ 529 */
520 530
521 if (ar->target_type == TARGET_TYPE_AR6003) { 531 param = ar->hw.board_ext_data_addr;
522 if (ar->version.target_ver == AR6003_REV2_VERSION) { 532 ram_reserved_size = ar->hw.reserved_ram_size;
523 param = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
524 ram_reserved_size = AR6003_REV2_RAM_RESERVE_SIZE;
525 } else {
526 param = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
527 ram_reserved_size = AR6003_REV3_RAM_RESERVE_SIZE;
528 }
529 533
530 if (ath6kl_bmi_write(ar, 534 if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
531 ath6kl_get_hi_item_addr(ar, 535 HI_ITEM(hi_board_ext_data)),
532 HI_ITEM(hi_board_ext_data)), 536 (u8 *)&param, 4) != 0) {
533 (u8 *)&param, 4) != 0) { 537 ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n");
534 ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n"); 538 return -EIO;
535 return -EIO; 539 }
536 } 540
537 if (ath6kl_bmi_write(ar, 541 if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
538 ath6kl_get_hi_item_addr(ar, 542 HI_ITEM(hi_end_ram_reserve_sz)),
539 HI_ITEM(hi_end_ram_reserve_sz)), 543 (u8 *)&ram_reserved_size, 4) != 0) {
540 (u8 *)&ram_reserved_size, 4) != 0) { 544 ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n");
541 ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n"); 545 return -EIO;
542 return -EIO;
543 }
544 } 546 }
545 547
546 /* set the block size for the target */ 548 /* set the block size for the target */
@@ -568,6 +570,12 @@ struct ath6kl *ath6kl_core_alloc(struct device *sdev)
568 ar->wdev = wdev; 570 ar->wdev = wdev;
569 wdev->iftype = NL80211_IFTYPE_STATION; 571 wdev->iftype = NL80211_IFTYPE_STATION;
570 572
573 if (ath6kl_debug_init(ar)) {
574 ath6kl_err("Failed to initialize debugfs\n");
575 ath6kl_cfg80211_deinit(ar);
576 return NULL;
577 }
578
571 dev = alloc_netdev(0, "wlan%d", ether_setup); 579 dev = alloc_netdev(0, "wlan%d", ether_setup);
572 if (!dev) { 580 if (!dev) {
573 ath6kl_err("no memory for network device instance\n"); 581 ath6kl_err("no memory for network device instance\n");
@@ -579,7 +587,6 @@ struct ath6kl *ath6kl_core_alloc(struct device *sdev)
579 SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy)); 587 SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
580 wdev->netdev = dev; 588 wdev->netdev = dev;
581 ar->sme_state = SME_DISCONNECTED; 589 ar->sme_state = SME_DISCONNECTED;
582 ar->auto_auth_stage = AUTH_IDLE;
583 590
584 init_netdev(dev); 591 init_netdev(dev);
585 592
@@ -611,29 +618,6 @@ int ath6kl_unavail_ev(struct ath6kl *ar)
611} 618}
612 619
613/* firmware upload */ 620/* firmware upload */
614static u32 ath6kl_get_load_address(u32 target_ver, enum addr_type type)
615{
616 WARN_ON(target_ver != AR6003_REV2_VERSION &&
617 target_ver != AR6003_REV3_VERSION);
618
619 switch (type) {
620 case DATASET_PATCH_ADDR:
621 return (target_ver == AR6003_REV2_VERSION) ?
622 AR6003_REV2_DATASET_PATCH_ADDRESS :
623 AR6003_REV3_DATASET_PATCH_ADDRESS;
624 case APP_LOAD_ADDR:
625 return (target_ver == AR6003_REV2_VERSION) ?
626 AR6003_REV2_APP_LOAD_ADDRESS :
627 0x1234;
628 case APP_START_OVERRIDE_ADDR:
629 return (target_ver == AR6003_REV2_VERSION) ?
630 AR6003_REV2_APP_START_OVERRIDE :
631 AR6003_REV3_APP_START_OVERRIDE;
632 default:
633 return 0;
634 }
635}
636
637static int ath6kl_get_fw(struct ath6kl *ar, const char *filename, 621static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
638 u8 **fw, size_t *fw_len) 622 u8 **fw, size_t *fw_len)
639{ 623{
@@ -655,15 +639,79 @@ static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
655 return ret; 639 return ret;
656} 640}
657 641
642#ifdef CONFIG_OF
643static const char *get_target_ver_dir(const struct ath6kl *ar)
644{
645 switch (ar->version.target_ver) {
646 case AR6003_REV1_VERSION:
647 return "ath6k/AR6003/hw1.0";
648 case AR6003_REV2_VERSION:
649 return "ath6k/AR6003/hw2.0";
650 case AR6003_REV3_VERSION:
651 return "ath6k/AR6003/hw2.1.1";
652 }
653 ath6kl_warn("%s: unsupported target version 0x%x.\n", __func__,
654 ar->version.target_ver);
655 return NULL;
656}
657
658/*
659 * Check the device tree for a board-id and use it to construct
660 * the pathname to the firmware file. Used (for now) to find a
661 * fallback to the "bdata.bin" file--typically a symlink to the
662 * appropriate board-specific file.
663 */
664static bool check_device_tree(struct ath6kl *ar)
665{
666 static const char *board_id_prop = "atheros,board-id";
667 struct device_node *node;
668 char board_filename[64];
669 const char *board_id;
670 int ret;
671
672 for_each_compatible_node(node, NULL, "atheros,ath6kl") {
673 board_id = of_get_property(node, board_id_prop, NULL);
674 if (board_id == NULL) {
675 ath6kl_warn("No \"%s\" property on %s node.\n",
676 board_id_prop, node->name);
677 continue;
678 }
679 snprintf(board_filename, sizeof(board_filename),
680 "%s/bdata.%s.bin", get_target_ver_dir(ar), board_id);
681
682 ret = ath6kl_get_fw(ar, board_filename, &ar->fw_board,
683 &ar->fw_board_len);
684 if (ret) {
685 ath6kl_err("Failed to get DT board file %s: %d\n",
686 board_filename, ret);
687 continue;
688 }
689 return true;
690 }
691 return false;
692}
693#else
694static bool check_device_tree(struct ath6kl *ar)
695{
696 return false;
697}
698#endif /* CONFIG_OF */
699
658static int ath6kl_fetch_board_file(struct ath6kl *ar) 700static int ath6kl_fetch_board_file(struct ath6kl *ar)
659{ 701{
660 const char *filename; 702 const char *filename;
661 int ret; 703 int ret;
662 704
705 if (ar->fw_board != NULL)
706 return 0;
707
663 switch (ar->version.target_ver) { 708 switch (ar->version.target_ver) {
664 case AR6003_REV2_VERSION: 709 case AR6003_REV2_VERSION:
665 filename = AR6003_REV2_BOARD_DATA_FILE; 710 filename = AR6003_REV2_BOARD_DATA_FILE;
666 break; 711 break;
712 case AR6004_REV1_VERSION:
713 filename = AR6004_REV1_BOARD_DATA_FILE;
714 break;
667 default: 715 default:
668 filename = AR6003_REV3_BOARD_DATA_FILE; 716 filename = AR6003_REV3_BOARD_DATA_FILE;
669 break; 717 break;
@@ -676,6 +724,11 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar)
676 return 0; 724 return 0;
677 } 725 }
678 726
727 if (check_device_tree(ar)) {
728 /* got board file from device tree */
729 return 0;
730 }
731
679 /* there was no proper board file, try to use default instead */ 732 /* there was no proper board file, try to use default instead */
680 ath6kl_warn("Failed to get board file %s (%d), trying to find default board file.\n", 733 ath6kl_warn("Failed to get board file %s (%d), trying to find default board file.\n",
681 filename, ret); 734 filename, ret);
@@ -684,6 +737,9 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar)
684 case AR6003_REV2_VERSION: 737 case AR6003_REV2_VERSION:
685 filename = AR6003_REV2_DEFAULT_BOARD_DATA_FILE; 738 filename = AR6003_REV2_DEFAULT_BOARD_DATA_FILE;
686 break; 739 break;
740 case AR6004_REV1_VERSION:
741 filename = AR6004_REV1_DEFAULT_BOARD_DATA_FILE;
742 break;
687 default: 743 default:
688 filename = AR6003_REV3_DEFAULT_BOARD_DATA_FILE; 744 filename = AR6003_REV3_DEFAULT_BOARD_DATA_FILE;
689 break; 745 break;
@@ -703,25 +759,346 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar)
703 return 0; 759 return 0;
704} 760}
705 761
762static int ath6kl_fetch_otp_file(struct ath6kl *ar)
763{
764 const char *filename;
765 int ret;
706 766
707static int ath6kl_upload_board_file(struct ath6kl *ar) 767 if (ar->fw_otp != NULL)
768 return 0;
769
770 switch (ar->version.target_ver) {
771 case AR6003_REV2_VERSION:
772 filename = AR6003_REV2_OTP_FILE;
773 break;
774 case AR6004_REV1_VERSION:
775 ath6kl_dbg(ATH6KL_DBG_TRC, "AR6004 doesn't need OTP file\n");
776 return 0;
777 break;
778 default:
779 filename = AR6003_REV3_OTP_FILE;
780 break;
781 }
782
783 ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
784 &ar->fw_otp_len);
785 if (ret) {
786 ath6kl_err("Failed to get OTP file %s: %d\n",
787 filename, ret);
788 return ret;
789 }
790
791 return 0;
792}
793
794static int ath6kl_fetch_fw_file(struct ath6kl *ar)
708{ 795{
709 u32 board_address, board_ext_address, param; 796 const char *filename;
797 int ret;
798
799 if (ar->fw != NULL)
800 return 0;
801
802 if (testmode) {
803 switch (ar->version.target_ver) {
804 case AR6003_REV2_VERSION:
805 filename = AR6003_REV2_TCMD_FIRMWARE_FILE;
806 break;
807 case AR6003_REV3_VERSION:
808 filename = AR6003_REV3_TCMD_FIRMWARE_FILE;
809 break;
810 case AR6004_REV1_VERSION:
811 ath6kl_warn("testmode not supported with ar6004\n");
812 return -EOPNOTSUPP;
813 default:
814 ath6kl_warn("unknown target version: 0x%x\n",
815 ar->version.target_ver);
816 return -EINVAL;
817 }
818
819 set_bit(TESTMODE, &ar->flag);
820
821 goto get_fw;
822 }
823
824 switch (ar->version.target_ver) {
825 case AR6003_REV2_VERSION:
826 filename = AR6003_REV2_FIRMWARE_FILE;
827 break;
828 case AR6004_REV1_VERSION:
829 filename = AR6004_REV1_FIRMWARE_FILE;
830 break;
831 default:
832 filename = AR6003_REV3_FIRMWARE_FILE;
833 break;
834 }
835
836get_fw:
837 ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
838 if (ret) {
839 ath6kl_err("Failed to get firmware file %s: %d\n",
840 filename, ret);
841 return ret;
842 }
843
844 return 0;
845}
846
847static int ath6kl_fetch_patch_file(struct ath6kl *ar)
848{
849 const char *filename;
710 int ret; 850 int ret;
711 851
712 if (ar->fw_board == NULL) { 852 switch (ar->version.target_ver) {
713 ret = ath6kl_fetch_board_file(ar); 853 case AR6003_REV2_VERSION:
714 if (ret) 854 filename = AR6003_REV2_PATCH_FILE;
855 break;
856 case AR6004_REV1_VERSION:
857 /* FIXME: implement for AR6004 */
858 return 0;
859 break;
860 default:
861 filename = AR6003_REV3_PATCH_FILE;
862 break;
863 }
864
865 if (ar->fw_patch == NULL) {
866 ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
867 &ar->fw_patch_len);
868 if (ret) {
869 ath6kl_err("Failed to get patch file %s: %d\n",
870 filename, ret);
715 return ret; 871 return ret;
872 }
716 } 873 }
717 874
718 /* Determine where in Target RAM to write Board Data */ 875 return 0;
719 ath6kl_bmi_read(ar, 876}
720 ath6kl_get_hi_item_addr(ar, 877
721 HI_ITEM(hi_board_data)), 878static int ath6kl_fetch_fw_api1(struct ath6kl *ar)
722 (u8 *) &board_address, 4); 879{
723 ath6kl_dbg(ATH6KL_DBG_TRC, "board data download addr: 0x%x\n", 880 int ret;
724 board_address); 881
882 ret = ath6kl_fetch_otp_file(ar);
883 if (ret)
884 return ret;
885
886 ret = ath6kl_fetch_fw_file(ar);
887 if (ret)
888 return ret;
889
890 ret = ath6kl_fetch_patch_file(ar);
891 if (ret)
892 return ret;
893
894 return 0;
895}
896
897static int ath6kl_fetch_fw_api2(struct ath6kl *ar)
898{
899 size_t magic_len, len, ie_len;
900 const struct firmware *fw;
901 struct ath6kl_fw_ie *hdr;
902 const char *filename;
903 const u8 *data;
904 int ret, ie_id, i, index, bit;
905 __le32 *val;
906
907 switch (ar->version.target_ver) {
908 case AR6003_REV2_VERSION:
909 filename = AR6003_REV2_FIRMWARE_2_FILE;
910 break;
911 case AR6003_REV3_VERSION:
912 filename = AR6003_REV3_FIRMWARE_2_FILE;
913 break;
914 case AR6004_REV1_VERSION:
915 filename = AR6004_REV1_FIRMWARE_2_FILE;
916 break;
917 default:
918 return -EOPNOTSUPP;
919 }
920
921 ret = request_firmware(&fw, filename, ar->dev);
922 if (ret)
923 return ret;
924
925 data = fw->data;
926 len = fw->size;
927
928 /* magic also includes the null byte, check that as well */
929 magic_len = strlen(ATH6KL_FIRMWARE_MAGIC) + 1;
930
931 if (len < magic_len) {
932 ret = -EINVAL;
933 goto out;
934 }
935
936 if (memcmp(data, ATH6KL_FIRMWARE_MAGIC, magic_len) != 0) {
937 ret = -EINVAL;
938 goto out;
939 }
940
941 len -= magic_len;
942 data += magic_len;
943
944 /* loop elements */
945 while (len > sizeof(struct ath6kl_fw_ie)) {
946 /* hdr is unaligned! */
947 hdr = (struct ath6kl_fw_ie *) data;
948
949 ie_id = le32_to_cpup(&hdr->id);
950 ie_len = le32_to_cpup(&hdr->len);
951
952 len -= sizeof(*hdr);
953 data += sizeof(*hdr);
954
955 if (len < ie_len) {
956 ret = -EINVAL;
957 goto out;
958 }
959
960 switch (ie_id) {
961 case ATH6KL_FW_IE_OTP_IMAGE:
962 ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n",
963 ie_len);
964
965 ar->fw_otp = kmemdup(data, ie_len, GFP_KERNEL);
966
967 if (ar->fw_otp == NULL) {
968 ret = -ENOMEM;
969 goto out;
970 }
971
972 ar->fw_otp_len = ie_len;
973 break;
974 case ATH6KL_FW_IE_FW_IMAGE:
975 ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n",
976 ie_len);
977
978 ar->fw = kmemdup(data, ie_len, GFP_KERNEL);
979
980 if (ar->fw == NULL) {
981 ret = -ENOMEM;
982 goto out;
983 }
984
985 ar->fw_len = ie_len;
986 break;
987 case ATH6KL_FW_IE_PATCH_IMAGE:
988 ath6kl_dbg(ATH6KL_DBG_BOOT, "found patch image ie (%zd B)\n",
989 ie_len);
990
991 ar->fw_patch = kmemdup(data, ie_len, GFP_KERNEL);
992
993 if (ar->fw_patch == NULL) {
994 ret = -ENOMEM;
995 goto out;
996 }
997
998 ar->fw_patch_len = ie_len;
999 break;
1000 case ATH6KL_FW_IE_RESERVED_RAM_SIZE:
1001 val = (__le32 *) data;
1002 ar->hw.reserved_ram_size = le32_to_cpup(val);
1003
1004 ath6kl_dbg(ATH6KL_DBG_BOOT,
1005 "found reserved ram size ie 0x%d\n",
1006 ar->hw.reserved_ram_size);
1007 break;
1008 case ATH6KL_FW_IE_CAPABILITIES:
1009 ath6kl_dbg(ATH6KL_DBG_BOOT,
1010 "found firmware capabilities ie (%zd B)\n",
1011 ie_len);
1012
1013 for (i = 0; i < ATH6KL_FW_CAPABILITY_MAX; i++) {
1014 index = ALIGN(i, 8) / 8;
1015 bit = i % 8;
1016
1017 if (data[index] & (1 << bit))
1018 __set_bit(i, ar->fw_capabilities);
1019 }
1020
1021 ath6kl_dbg_dump(ATH6KL_DBG_BOOT, "capabilities", "",
1022 ar->fw_capabilities,
1023 sizeof(ar->fw_capabilities));
1024 break;
1025 case ATH6KL_FW_IE_PATCH_ADDR:
1026 if (ie_len != sizeof(*val))
1027 break;
1028
1029 val = (__le32 *) data;
1030 ar->hw.dataset_patch_addr = le32_to_cpup(val);
1031
1032 ath6kl_dbg(ATH6KL_DBG_BOOT,
1033 "found patch address ie 0x%d\n",
1034 ar->hw.dataset_patch_addr);
1035 break;
1036 default:
1037 ath6kl_dbg(ATH6KL_DBG_BOOT, "Unknown fw ie: %u\n",
1038 le32_to_cpup(&hdr->id));
1039 break;
1040 }
1041
1042 len -= ie_len;
1043 data += ie_len;
1044 };
1045
1046 ret = 0;
1047out:
1048 release_firmware(fw);
1049
1050 return ret;
1051}
1052
1053static int ath6kl_fetch_firmwares(struct ath6kl *ar)
1054{
1055 int ret;
1056
1057 ret = ath6kl_fetch_board_file(ar);
1058 if (ret)
1059 return ret;
1060
1061 ret = ath6kl_fetch_fw_api2(ar);
1062 if (ret == 0) {
1063 ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 2\n");
1064 return 0;
1065 }
1066
1067 ret = ath6kl_fetch_fw_api1(ar);
1068 if (ret)
1069 return ret;
1070
1071 ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 1\n");
1072
1073 return 0;
1074}
1075
1076static int ath6kl_upload_board_file(struct ath6kl *ar)
1077{
1078 u32 board_address, board_ext_address, param;
1079 u32 board_data_size, board_ext_data_size;
1080 int ret;
1081
1082 if (WARN_ON(ar->fw_board == NULL))
1083 return -ENOENT;
1084
1085 /*
1086 * Determine where in Target RAM to write Board Data.
1087 * For AR6004, host determine Target RAM address for
1088 * writing board data.
1089 */
1090 if (ar->target_type == TARGET_TYPE_AR6004) {
1091 board_address = AR6004_REV1_BOARD_DATA_ADDRESS;
1092 ath6kl_bmi_write(ar,
1093 ath6kl_get_hi_item_addr(ar,
1094 HI_ITEM(hi_board_data)),
1095 (u8 *) &board_address, 4);
1096 } else {
1097 ath6kl_bmi_read(ar,
1098 ath6kl_get_hi_item_addr(ar,
1099 HI_ITEM(hi_board_data)),
1100 (u8 *) &board_address, 4);
1101 }
725 1102
726 /* determine where in target ram to write extended board data */ 1103 /* determine where in target ram to write extended board data */
727 ath6kl_bmi_read(ar, 1104 ath6kl_bmi_read(ar,
@@ -729,21 +1106,37 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
729 HI_ITEM(hi_board_ext_data)), 1106 HI_ITEM(hi_board_ext_data)),
730 (u8 *) &board_ext_address, 4); 1107 (u8 *) &board_ext_address, 4);
731 1108
732 ath6kl_dbg(ATH6KL_DBG_TRC, "board file download addr: 0x%x\n",
733 board_ext_address);
734
735 if (board_ext_address == 0) { 1109 if (board_ext_address == 0) {
736 ath6kl_err("Failed to get board file target address.\n"); 1110 ath6kl_err("Failed to get board file target address.\n");
737 return -EINVAL; 1111 return -EINVAL;
738 } 1112 }
739 1113
740 if (ar->fw_board_len == (AR6003_BOARD_DATA_SZ + 1114 switch (ar->target_type) {
741 AR6003_BOARD_EXT_DATA_SZ)) { 1115 case TARGET_TYPE_AR6003:
1116 board_data_size = AR6003_BOARD_DATA_SZ;
1117 board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ;
1118 break;
1119 case TARGET_TYPE_AR6004:
1120 board_data_size = AR6004_BOARD_DATA_SZ;
1121 board_ext_data_size = AR6004_BOARD_EXT_DATA_SZ;
1122 break;
1123 default:
1124 WARN_ON(1);
1125 return -EINVAL;
1126 break;
1127 }
1128
1129 if (ar->fw_board_len == (board_data_size +
1130 board_ext_data_size)) {
1131
742 /* write extended board data */ 1132 /* write extended board data */
743 ret = ath6kl_bmi_write(ar, board_ext_address, 1133 ath6kl_dbg(ATH6KL_DBG_BOOT,
744 ar->fw_board + AR6003_BOARD_DATA_SZ, 1134 "writing extended board data to 0x%x (%d B)\n",
745 AR6003_BOARD_EXT_DATA_SZ); 1135 board_ext_address, board_ext_data_size);
746 1136
1137 ret = ath6kl_bmi_write(ar, board_ext_address,
1138 ar->fw_board + board_data_size,
1139 board_ext_data_size);
747 if (ret) { 1140 if (ret) {
748 ath6kl_err("Failed to write extended board data: %d\n", 1141 ath6kl_err("Failed to write extended board data: %d\n",
749 ret); 1142 ret);
@@ -751,21 +1144,25 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
751 } 1144 }
752 1145
753 /* record that extended board data is initialized */ 1146 /* record that extended board data is initialized */
754 param = (AR6003_BOARD_EXT_DATA_SZ << 16) | 1; 1147 param = (board_ext_data_size << 16) | 1;
1148
755 ath6kl_bmi_write(ar, 1149 ath6kl_bmi_write(ar,
756 ath6kl_get_hi_item_addr(ar, 1150 ath6kl_get_hi_item_addr(ar,
757 HI_ITEM(hi_board_ext_data_config)), 1151 HI_ITEM(hi_board_ext_data_config)),
758 (unsigned char *) &param, 4); 1152 (unsigned char *) &param, 4);
759 } 1153 }
760 1154
761 if (ar->fw_board_len < AR6003_BOARD_DATA_SZ) { 1155 if (ar->fw_board_len < board_data_size) {
762 ath6kl_err("Too small board file: %zu\n", ar->fw_board_len); 1156 ath6kl_err("Too small board file: %zu\n", ar->fw_board_len);
763 ret = -EINVAL; 1157 ret = -EINVAL;
764 return ret; 1158 return ret;
765 } 1159 }
766 1160
1161 ath6kl_dbg(ATH6KL_DBG_BOOT, "writing board file to 0x%x (%d B)\n",
1162 board_address, board_data_size);
1163
767 ret = ath6kl_bmi_write(ar, board_address, ar->fw_board, 1164 ret = ath6kl_bmi_write(ar, board_address, ar->fw_board,
768 AR6003_BOARD_DATA_SZ); 1165 board_data_size);
769 1166
770 if (ret) { 1167 if (ret) {
771 ath6kl_err("Board file bmi write failed: %d\n", ret); 1168 ath6kl_err("Board file bmi write failed: %d\n", ret);
@@ -784,31 +1181,16 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
784 1181
785static int ath6kl_upload_otp(struct ath6kl *ar) 1182static int ath6kl_upload_otp(struct ath6kl *ar)
786{ 1183{
787 const char *filename;
788 u32 address, param; 1184 u32 address, param;
789 int ret; 1185 int ret;
790 1186
791 switch (ar->version.target_ver) { 1187 if (WARN_ON(ar->fw_otp == NULL))
792 case AR6003_REV2_VERSION: 1188 return -ENOENT;
793 filename = AR6003_REV2_OTP_FILE;
794 break;
795 default:
796 filename = AR6003_REV3_OTP_FILE;
797 break;
798 }
799 1189
800 if (ar->fw_otp == NULL) { 1190 address = ar->hw.app_load_addr;
801 ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
802 &ar->fw_otp_len);
803 if (ret) {
804 ath6kl_err("Failed to get OTP file %s: %d\n",
805 filename, ret);
806 return ret;
807 }
808 }
809 1191
810 address = ath6kl_get_load_address(ar->version.target_ver, 1192 ath6kl_dbg(ATH6KL_DBG_BOOT, "writing otp to 0x%x (%zd B)\n", address,
811 APP_LOAD_ADDR); 1193 ar->fw_otp_len);
812 1194
813 ret = ath6kl_bmi_fast_download(ar, address, ar->fw_otp, 1195 ret = ath6kl_bmi_fast_download(ar, address, ar->fw_otp,
814 ar->fw_otp_len); 1196 ar->fw_otp_len);
@@ -817,10 +1199,25 @@ static int ath6kl_upload_otp(struct ath6kl *ar)
817 return ret; 1199 return ret;
818 } 1200 }
819 1201
1202 /* read firmware start address */
1203 ret = ath6kl_bmi_read(ar,
1204 ath6kl_get_hi_item_addr(ar,
1205 HI_ITEM(hi_app_start)),
1206 (u8 *) &address, sizeof(address));
1207
1208 if (ret) {
1209 ath6kl_err("Failed to read hi_app_start: %d\n", ret);
1210 return ret;
1211 }
1212
1213 ar->hw.app_start_override_addr = address;
1214
1215 ath6kl_dbg(ATH6KL_DBG_BOOT, "app_start_override_addr 0x%x\n",
1216 ar->hw.app_start_override_addr);
1217
820 /* execute the OTP code */ 1218 /* execute the OTP code */
1219 ath6kl_dbg(ATH6KL_DBG_BOOT, "executing OTP at 0x%x\n", address);
821 param = 0; 1220 param = 0;
822 address = ath6kl_get_load_address(ar->version.target_ver,
823 APP_START_OVERRIDE_ADDR);
824 ath6kl_bmi_execute(ar, address, &param); 1221 ath6kl_bmi_execute(ar, address, &param);
825 1222
826 return ret; 1223 return ret;
@@ -828,30 +1225,16 @@ static int ath6kl_upload_otp(struct ath6kl *ar)
828 1225
829static int ath6kl_upload_firmware(struct ath6kl *ar) 1226static int ath6kl_upload_firmware(struct ath6kl *ar)
830{ 1227{
831 const char *filename;
832 u32 address; 1228 u32 address;
833 int ret; 1229 int ret;
834 1230
835 switch (ar->version.target_ver) { 1231 if (WARN_ON(ar->fw == NULL))
836 case AR6003_REV2_VERSION: 1232 return -ENOENT;
837 filename = AR6003_REV2_FIRMWARE_FILE;
838 break;
839 default:
840 filename = AR6003_REV3_FIRMWARE_FILE;
841 break;
842 }
843 1233
844 if (ar->fw == NULL) { 1234 address = ar->hw.app_load_addr;
845 ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
846 if (ret) {
847 ath6kl_err("Failed to get firmware file %s: %d\n",
848 filename, ret);
849 return ret;
850 }
851 }
852 1235
853 address = ath6kl_get_load_address(ar->version.target_ver, 1236 ath6kl_dbg(ATH6KL_DBG_BOOT, "writing firmware to 0x%x (%zd B)\n",
854 APP_LOAD_ADDR); 1237 address, ar->fw_len);
855 1238
856 ret = ath6kl_bmi_fast_download(ar, address, ar->fw, ar->fw_len); 1239 ret = ath6kl_bmi_fast_download(ar, address, ar->fw, ar->fw_len);
857 1240
@@ -860,41 +1243,29 @@ static int ath6kl_upload_firmware(struct ath6kl *ar)
860 return ret; 1243 return ret;
861 } 1244 }
862 1245
863 /* Set starting address for firmware */ 1246 /*
864 address = ath6kl_get_load_address(ar->version.target_ver, 1247 * Set starting address for firmware
865 APP_START_OVERRIDE_ADDR); 1248 * Don't need to setup app_start override addr on AR6004
866 ath6kl_bmi_set_app_start(ar, address); 1249 */
867 1250 if (ar->target_type != TARGET_TYPE_AR6004) {
1251 address = ar->hw.app_start_override_addr;
1252 ath6kl_bmi_set_app_start(ar, address);
1253 }
868 return ret; 1254 return ret;
869} 1255}
870 1256
871static int ath6kl_upload_patch(struct ath6kl *ar) 1257static int ath6kl_upload_patch(struct ath6kl *ar)
872{ 1258{
873 const char *filename;
874 u32 address, param; 1259 u32 address, param;
875 int ret; 1260 int ret;
876 1261
877 switch (ar->version.target_ver) { 1262 if (WARN_ON(ar->fw_patch == NULL))
878 case AR6003_REV2_VERSION: 1263 return -ENOENT;
879 filename = AR6003_REV2_PATCH_FILE;
880 break;
881 default:
882 filename = AR6003_REV3_PATCH_FILE;
883 break;
884 }
885 1264
886 if (ar->fw_patch == NULL) { 1265 address = ar->hw.dataset_patch_addr;
887 ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
888 &ar->fw_patch_len);
889 if (ret) {
890 ath6kl_err("Failed to get patch file %s: %d\n",
891 filename, ret);
892 return ret;
893 }
894 }
895 1266
896 address = ath6kl_get_load_address(ar->version.target_ver, 1267 ath6kl_dbg(ATH6KL_DBG_BOOT, "writing patch to 0x%x (%zd B)\n",
897 DATASET_PATCH_ADDR); 1268 address, ar->fw_patch_len);
898 1269
899 ret = ath6kl_bmi_write(ar, address, ar->fw_patch, ar->fw_patch_len); 1270 ret = ath6kl_bmi_write(ar, address, ar->fw_patch, ar->fw_patch_len);
900 if (ret) { 1271 if (ret) {
@@ -916,7 +1287,8 @@ static int ath6kl_init_upload(struct ath6kl *ar)
916 u32 param, options, sleep, address; 1287 u32 param, options, sleep, address;
917 int status = 0; 1288 int status = 0;
918 1289
919 if (ar->target_type != TARGET_TYPE_AR6003) 1290 if (ar->target_type != TARGET_TYPE_AR6003 &&
1291 ar->target_type != TARGET_TYPE_AR6004)
920 return -EINVAL; 1292 return -EINVAL;
921 1293
922 /* temporarily disable system sleep */ 1294 /* temporarily disable system sleep */
@@ -948,18 +1320,22 @@ static int ath6kl_init_upload(struct ath6kl *ar)
948 options, sleep); 1320 options, sleep);
949 1321
950 /* program analog PLL register */ 1322 /* program analog PLL register */
951 status = ath6kl_bmi_reg_write(ar, ATH6KL_ANALOG_PLL_REGISTER, 1323 /* no need to control 40/44MHz clock on AR6004 */
952 0xF9104001); 1324 if (ar->target_type != TARGET_TYPE_AR6004) {
953 if (status) 1325 status = ath6kl_bmi_reg_write(ar, ATH6KL_ANALOG_PLL_REGISTER,
954 return status; 1326 0xF9104001);
955 1327
956 /* Run at 80/88MHz by default */ 1328 if (status)
957 param = SM(CPU_CLOCK_STANDARD, 1); 1329 return status;
958 1330
959 address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS; 1331 /* Run at 80/88MHz by default */
960 status = ath6kl_bmi_reg_write(ar, address, param); 1332 param = SM(CPU_CLOCK_STANDARD, 1);
961 if (status) 1333
962 return status; 1334 address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
1335 status = ath6kl_bmi_reg_write(ar, address, param);
1336 if (status)
1337 return status;
1338 }
963 1339
964 param = 0; 1340 param = 0;
965 address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS; 1341 address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
@@ -1036,6 +1412,45 @@ static int ath6kl_init_upload(struct ath6kl *ar)
1036 return status; 1412 return status;
1037} 1413}
1038 1414
1415static int ath6kl_init_hw_params(struct ath6kl *ar)
1416{
1417 switch (ar->version.target_ver) {
1418 case AR6003_REV2_VERSION:
1419 ar->hw.dataset_patch_addr = AR6003_REV2_DATASET_PATCH_ADDRESS;
1420 ar->hw.app_load_addr = AR6003_REV2_APP_LOAD_ADDRESS;
1421 ar->hw.board_ext_data_addr = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
1422 ar->hw.reserved_ram_size = AR6003_REV2_RAM_RESERVE_SIZE;
1423 break;
1424 case AR6003_REV3_VERSION:
1425 ar->hw.dataset_patch_addr = AR6003_REV3_DATASET_PATCH_ADDRESS;
1426 ar->hw.app_load_addr = 0x1234;
1427 ar->hw.board_ext_data_addr = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
1428 ar->hw.reserved_ram_size = AR6003_REV3_RAM_RESERVE_SIZE;
1429 break;
1430 case AR6004_REV1_VERSION:
1431 ar->hw.dataset_patch_addr = AR6003_REV2_DATASET_PATCH_ADDRESS;
1432 ar->hw.app_load_addr = AR6003_REV3_APP_LOAD_ADDRESS;
1433 ar->hw.board_ext_data_addr = AR6004_REV1_BOARD_EXT_DATA_ADDRESS;
1434 ar->hw.reserved_ram_size = AR6004_REV1_RAM_RESERVE_SIZE;
1435 break;
1436 default:
1437 ath6kl_err("Unsupported hardware version: 0x%x\n",
1438 ar->version.target_ver);
1439 return -EINVAL;
1440 }
1441
1442 ath6kl_dbg(ATH6KL_DBG_BOOT,
1443 "target_ver 0x%x target_type 0x%x dataset_patch 0x%x app_load_addr 0x%x\n",
1444 ar->version.target_ver, ar->target_type,
1445 ar->hw.dataset_patch_addr, ar->hw.app_load_addr);
1446 ath6kl_dbg(ATH6KL_DBG_BOOT,
1447 "app_start_override_addr 0x%x board_ext_data_addr 0x%x reserved_ram_size 0x%x",
1448 ar->hw.app_start_override_addr, ar->hw.board_ext_data_addr,
1449 ar->hw.reserved_ram_size);
1450
1451 return 0;
1452}
1453
1039static int ath6kl_init(struct net_device *dev) 1454static int ath6kl_init(struct net_device *dev)
1040{ 1455{
1041 struct ath6kl *ar = ath6kl_priv(dev); 1456 struct ath6kl *ar = ath6kl_priv(dev);
@@ -1062,8 +1477,6 @@ static int ath6kl_init(struct net_device *dev)
1062 1477
1063 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi); 1478 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
1064 1479
1065 wlan_node_table_init(&ar->scan_table);
1066
1067 /* 1480 /*
1068 * The reason we have to wait for the target here is that the 1481 * The reason we have to wait for the target here is that the
1069 * driver layer has to init BMI in order to set the host block 1482 * driver layer has to init BMI in order to set the host block
@@ -1111,6 +1524,8 @@ static int ath6kl_init(struct net_device *dev)
1111 &ar->flag), 1524 &ar->flag),
1112 WMI_TIMEOUT); 1525 WMI_TIMEOUT);
1113 1526
1527 ath6kl_dbg(ATH6KL_DBG_BOOT, "firmware booted\n");
1528
1114 if (ar->version.abi_ver != ATH6KL_ABI_VERSION) { 1529 if (ar->version.abi_ver != ATH6KL_ABI_VERSION) {
1115 ath6kl_err("abi version mismatch: host(0x%x), target(0x%x)\n", 1530 ath6kl_err("abi version mismatch: host(0x%x), target(0x%x)\n",
1116 ATH6KL_ABI_VERSION, ar->version.abi_ver); 1531 ATH6KL_ABI_VERSION, ar->version.abi_ver);
@@ -1133,6 +1548,8 @@ static int ath6kl_init(struct net_device *dev)
1133 ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | 1548 ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
1134 ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; 1549 ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
1135 1550
1551 ar->wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
1552
1136 status = ath6kl_target_config_wlan_params(ar); 1553 status = ath6kl_target_config_wlan_params(ar);
1137 if (!status) 1554 if (!status)
1138 goto ath6kl_init_done; 1555 goto ath6kl_init_done;
@@ -1145,7 +1562,6 @@ err_rxbuf_cleanup:
1145err_cleanup_scatter: 1562err_cleanup_scatter:
1146 ath6kl_hif_cleanup_scatter(ar); 1563 ath6kl_hif_cleanup_scatter(ar);
1147err_node_cleanup: 1564err_node_cleanup:
1148 wlan_node_table_cleanup(&ar->scan_table);
1149 ath6kl_wmi_shutdown(ar->wmi); 1565 ath6kl_wmi_shutdown(ar->wmi);
1150 clear_bit(WMI_ENABLED, &ar->flag); 1566 clear_bit(WMI_ENABLED, &ar->flag);
1151 ar->wmi = NULL; 1567 ar->wmi = NULL;
@@ -1175,6 +1591,10 @@ int ath6kl_core_init(struct ath6kl *ar)
1175 ar->target_type = le32_to_cpu(targ_info.type); 1591 ar->target_type = le32_to_cpu(targ_info.type);
1176 ar->wdev->wiphy->hw_version = le32_to_cpu(targ_info.version); 1592 ar->wdev->wiphy->hw_version = le32_to_cpu(targ_info.version);
1177 1593
1594 ret = ath6kl_init_hw_params(ar);
1595 if (ret)
1596 goto err_bmi_cleanup;
1597
1178 ret = ath6kl_configure_target(ar); 1598 ret = ath6kl_configure_target(ar);
1179 if (ret) 1599 if (ret)
1180 goto err_bmi_cleanup; 1600 goto err_bmi_cleanup;
@@ -1193,6 +1613,10 @@ int ath6kl_core_init(struct ath6kl *ar)
1193 goto err_htc_cleanup; 1613 goto err_htc_cleanup;
1194 } 1614 }
1195 1615
1616 ret = ath6kl_fetch_firmwares(ar);
1617 if (ret)
1618 goto err_htc_cleanup;
1619
1196 ret = ath6kl_init_upload(ar); 1620 ret = ath6kl_init_upload(ar);
1197 if (ret) 1621 if (ret)
1198 goto err_htc_cleanup; 1622 goto err_htc_cleanup;
@@ -1285,6 +1709,8 @@ void ath6kl_destroy(struct net_device *dev, unsigned int unregister)
1285 1709
1286 ath6kl_bmi_cleanup(ar); 1710 ath6kl_bmi_cleanup(ar);
1287 1711
1712 ath6kl_debug_cleanup(ar);
1713
1288 if (unregister && test_bit(NETDEV_REGISTERED, &ar->flag)) { 1714 if (unregister && test_bit(NETDEV_REGISTERED, &ar->flag)) {
1289 unregister_netdev(dev); 1715 unregister_netdev(dev);
1290 clear_bit(NETDEV_REGISTERED, &ar->flag); 1716 clear_bit(NETDEV_REGISTERED, &ar->flag);
@@ -1292,8 +1718,6 @@ void ath6kl_destroy(struct net_device *dev, unsigned int unregister)
1292 1718
1293 free_netdev(dev); 1719 free_netdev(dev);
1294 1720
1295 wlan_node_table_cleanup(&ar->scan_table);
1296
1297 kfree(ar->fw_board); 1721 kfree(ar->fw_board);
1298 kfree(ar->fw_otp); 1722 kfree(ar->fw_otp);
1299 kfree(ar->fw); 1723 kfree(ar->fw);
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index c336eae0cf48..30b5a53db9ed 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -61,7 +61,8 @@ static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie,
61 61
62 sta = &ar->sta_list[free_slot]; 62 sta = &ar->sta_list[free_slot];
63 memcpy(sta->mac, mac, ETH_ALEN); 63 memcpy(sta->mac, mac, ETH_ALEN);
64 memcpy(sta->wpa_ie, wpaie, ielen); 64 if (ielen <= ATH6KL_MAX_IE)
65 memcpy(sta->wpa_ie, wpaie, ielen);
65 sta->aid = aid; 66 sta->aid = aid;
66 sta->keymgmt = keymgmt; 67 sta->keymgmt = keymgmt;
67 sta->ucipher = ucipher; 68 sta->ucipher = ucipher;
@@ -177,8 +178,8 @@ void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie)
177static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr) 178static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
178{ 179{
179 int status; 180 int status;
180 u8 addr_val[4];
181 s32 i; 181 s32 i;
182 __le32 addr_val;
182 183
183 /* 184 /*
184 * Write bytes 1,2,3 of the register to set the upper address bytes, 185 * Write bytes 1,2,3 of the register to set the upper address bytes,
@@ -188,16 +189,18 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
188 for (i = 1; i <= 3; i++) { 189 for (i = 1; i <= 3; i++) {
189 /* 190 /*
190 * Fill the buffer with the address byte value we want to 191 * Fill the buffer with the address byte value we want to
191 * hit 4 times. 192 * hit 4 times. No need to worry about endianness as the
193 * same byte is copied to all four bytes of addr_val at
194 * any time.
192 */ 195 */
193 memset(addr_val, ((u8 *)&addr)[i], 4); 196 memset((u8 *)&addr_val, ((u8 *)&addr)[i], 4);
194 197
195 /* 198 /*
196 * Hit each byte of the register address with a 4-byte 199 * Hit each byte of the register address with a 4-byte
197 * write operation to the same address, this is a harmless 200 * write operation to the same address, this is a harmless
198 * operation. 201 * operation.
199 */ 202 */
200 status = hif_read_write_sync(ar, reg_addr + i, addr_val, 203 status = hif_read_write_sync(ar, reg_addr + i, (u8 *)&addr_val,
201 4, HIF_WR_SYNC_BYTE_FIX); 204 4, HIF_WR_SYNC_BYTE_FIX);
202 if (status) 205 if (status)
203 break; 206 break;
@@ -215,7 +218,9 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
215 * cycle to start, the extra 3 byte write to bytes 1,2,3 has no 218 * cycle to start, the extra 3 byte write to bytes 1,2,3 has no
216 * effect since we are writing the same values again 219 * effect since we are writing the same values again
217 */ 220 */
218 status = hif_read_write_sync(ar, reg_addr, (u8 *)(&addr), 221 addr_val = cpu_to_le32(addr);
222 status = hif_read_write_sync(ar, reg_addr,
223 (u8 *)&(addr_val),
219 4, HIF_WR_SYNC_BYTE_INC); 224 4, HIF_WR_SYNC_BYTE_INC);
220 225
221 if (status) { 226 if (status) {
@@ -228,90 +233,193 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
228} 233}
229 234
230/* 235/*
231 * Read from the ATH6KL through its diagnostic window. No cooperation from 236 * Read from the hardware through its diagnostic window. No cooperation
232 * the Target is required for this. 237 * from the firmware is required for this.
233 */ 238 */
234int ath6kl_read_reg_diag(struct ath6kl *ar, u32 *address, u32 *data) 239int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value)
235{ 240{
236 int status; 241 int ret;
237 242
238 /* set window register to start read cycle */ 243 /* set window register to start read cycle */
239 status = ath6kl_set_addrwin_reg(ar, WINDOW_READ_ADDR_ADDRESS, 244 ret = ath6kl_set_addrwin_reg(ar, WINDOW_READ_ADDR_ADDRESS, address);
240 *address); 245 if (ret)
241 246 return ret;
242 if (status)
243 return status;
244 247
245 /* read the data */ 248 /* read the data */
246 status = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *)data, 249 ret = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *) value,
247 sizeof(u32), HIF_RD_SYNC_BYTE_INC); 250 sizeof(*value), HIF_RD_SYNC_BYTE_INC);
248 if (status) { 251 if (ret) {
249 ath6kl_err("failed to read from window data addr\n"); 252 ath6kl_warn("failed to read32 through diagnose window: %d\n",
250 return status; 253 ret);
254 return ret;
251 } 255 }
252 256
253 return status; 257 return 0;
254} 258}
255 259
256
257/* 260/*
258 * Write to the ATH6KL through its diagnostic window. No cooperation from 261 * Write to the ATH6KL through its diagnostic window. No cooperation from
259 * the Target is required for this. 262 * the Target is required for this.
260 */ 263 */
261static int ath6kl_write_reg_diag(struct ath6kl *ar, u32 *address, u32 *data) 264int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value)
262{ 265{
263 int status; 266 int ret;
264 267
265 /* set write data */ 268 /* set write data */
266 status = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *)data, 269 ret = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *) &value,
267 sizeof(u32), HIF_WR_SYNC_BYTE_INC); 270 sizeof(value), HIF_WR_SYNC_BYTE_INC);
268 if (status) { 271 if (ret) {
269 ath6kl_err("failed to write 0x%x to window data addr\n", *data); 272 ath6kl_err("failed to write 0x%x during diagnose window to 0x%d\n",
270 return status; 273 address, value);
274 return ret;
271 } 275 }
272 276
273 /* set window register, which starts the write cycle */ 277 /* set window register, which starts the write cycle */
274 return ath6kl_set_addrwin_reg(ar, WINDOW_WRITE_ADDR_ADDRESS, 278 return ath6kl_set_addrwin_reg(ar, WINDOW_WRITE_ADDR_ADDRESS,
275 *address); 279 address);
276} 280}
277 281
278int ath6kl_access_datadiag(struct ath6kl *ar, u32 address, 282int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length)
279 u8 *data, u32 length, bool read) 283{
284 u32 count, *buf = data;
285 int ret;
286
287 if (WARN_ON(length % 4))
288 return -EINVAL;
289
290 for (count = 0; count < length / 4; count++, address += 4) {
291 ret = ath6kl_diag_read32(ar, address, &buf[count]);
292 if (ret)
293 return ret;
294 }
295
296 return 0;
297}
298
299int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length)
280{ 300{
281 u32 count; 301 u32 count;
282 int status = 0; 302 __le32 *buf = data;
303 int ret;
283 304
284 for (count = 0; count < length; count += 4, address += 4) { 305 if (WARN_ON(length % 4))
285 if (read) { 306 return -EINVAL;
286 status = ath6kl_read_reg_diag(ar, &address, 307
287 (u32 *) &data[count]); 308 for (count = 0; count < length / 4; count++, address += 4) {
288 if (status) 309 ret = ath6kl_diag_write32(ar, address, buf[count]);
289 break; 310 if (ret)
290 } else { 311 return ret;
291 status = ath6kl_write_reg_diag(ar, &address, 312 }
292 (u32 *) &data[count]); 313
293 if (status) 314 return 0;
294 break; 315}
295 } 316
317int ath6kl_read_fwlogs(struct ath6kl *ar)
318{
319 struct ath6kl_dbglog_hdr debug_hdr;
320 struct ath6kl_dbglog_buf debug_buf;
321 u32 address, length, dropped, firstbuf, debug_hdr_addr;
322 int ret = 0, loop;
323 u8 *buf;
324
325 buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL);
326 if (!buf)
327 return -ENOMEM;
328
329 address = TARG_VTOP(ar->target_type,
330 ath6kl_get_hi_item_addr(ar,
331 HI_ITEM(hi_dbglog_hdr)));
332
333 ret = ath6kl_diag_read32(ar, address, &debug_hdr_addr);
334 if (ret)
335 goto out;
336
337 /* Get the contents of the ring buffer */
338 if (debug_hdr_addr == 0) {
339 ath6kl_warn("Invalid address for debug_hdr_addr\n");
340 ret = -EINVAL;
341 goto out;
296 } 342 }
297 343
298 return status; 344 address = TARG_VTOP(ar->target_type, debug_hdr_addr);
345 ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr));
346
347 address = TARG_VTOP(ar->target_type,
348 le32_to_cpu(debug_hdr.dbuf_addr));
349 firstbuf = address;
350 dropped = le32_to_cpu(debug_hdr.dropped);
351 ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
352
353 loop = 100;
354
355 do {
356 address = TARG_VTOP(ar->target_type,
357 le32_to_cpu(debug_buf.buffer_addr));
358 length = le32_to_cpu(debug_buf.length);
359
360 if (length != 0 && (le32_to_cpu(debug_buf.length) <=
361 le32_to_cpu(debug_buf.bufsize))) {
362 length = ALIGN(length, 4);
363
364 ret = ath6kl_diag_read(ar, address,
365 buf, length);
366 if (ret)
367 goto out;
368
369 ath6kl_debug_fwlog_event(ar, buf, length);
370 }
371
372 address = TARG_VTOP(ar->target_type,
373 le32_to_cpu(debug_buf.next));
374 ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
375 if (ret)
376 goto out;
377
378 loop--;
379
380 if (WARN_ON(loop == 0)) {
381 ret = -ETIMEDOUT;
382 goto out;
383 }
384 } while (address != firstbuf);
385
386out:
387 kfree(buf);
388
389 return ret;
299} 390}
300 391
392/* FIXME: move to a better place, target.h? */
393#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
394#define AR6004_RESET_CONTROL_ADDRESS 0x00004000
395
301static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, 396static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
302 bool wait_fot_compltn, bool cold_reset) 397 bool wait_fot_compltn, bool cold_reset)
303{ 398{
304 int status = 0; 399 int status = 0;
305 u32 address; 400 u32 address;
306 u32 data; 401 __le32 data;
307 402
308 if (target_type != TARGET_TYPE_AR6003) 403 if (target_type != TARGET_TYPE_AR6003 &&
404 target_type != TARGET_TYPE_AR6004)
309 return; 405 return;
310 406
311 data = cold_reset ? RESET_CONTROL_COLD_RST : RESET_CONTROL_MBOX_RST; 407 data = cold_reset ? cpu_to_le32(RESET_CONTROL_COLD_RST) :
408 cpu_to_le32(RESET_CONTROL_MBOX_RST);
312 409
313 address = RTC_BASE_ADDRESS; 410 switch (target_type) {
314 status = ath6kl_write_reg_diag(ar, &address, &data); 411 case TARGET_TYPE_AR6003:
412 address = AR6003_RESET_CONTROL_ADDRESS;
413 break;
414 case TARGET_TYPE_AR6004:
415 address = AR6004_RESET_CONTROL_ADDRESS;
416 break;
417 default:
418 address = AR6003_RESET_CONTROL_ADDRESS;
419 break;
420 }
421
422 status = ath6kl_diag_write32(ar, address, data);
315 423
316 if (status) 424 if (status)
317 ath6kl_err("failed to reset target\n"); 425 ath6kl_err("failed to reset target\n");
@@ -411,68 +519,107 @@ static void ath6kl_install_static_wep_keys(struct ath6kl *ar)
411 } 519 }
412} 520}
413 521
414static void ath6kl_connect_ap_mode(struct ath6kl *ar, u16 channel, u8 *bssid, 522void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel)
415 u16 listen_int, u16 beacon_int,
416 u8 assoc_resp_len, u8 *assoc_info)
417{ 523{
418 struct net_device *dev = ar->net_dev;
419 struct station_info sinfo;
420 struct ath6kl_req_key *ik; 524 struct ath6kl_req_key *ik;
421 enum crypto_type keyType = NONE_CRYPT; 525 int res;
526 u8 key_rsc[ATH6KL_KEY_SEQ_LEN];
422 527
423 if (memcmp(dev->dev_addr, bssid, ETH_ALEN) == 0) { 528 ik = &ar->ap_mode_bkey;
424 ik = &ar->ap_mode_bkey;
425 529
426 switch (ar->auth_mode) { 530 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "AP mode started on %u MHz\n", channel);
427 case NONE_AUTH: 531
428 if (ar->prwise_crypto == WEP_CRYPT) 532 switch (ar->auth_mode) {
429 ath6kl_install_static_wep_keys(ar); 533 case NONE_AUTH:
430 break; 534 if (ar->prwise_crypto == WEP_CRYPT)
431 case WPA_PSK_AUTH: 535 ath6kl_install_static_wep_keys(ar);
432 case WPA2_PSK_AUTH: 536 break;
433 case (WPA_PSK_AUTH|WPA2_PSK_AUTH): 537 case WPA_PSK_AUTH:
434 switch (ik->ik_type) { 538 case WPA2_PSK_AUTH:
435 case ATH6KL_CIPHER_TKIP: 539 case (WPA_PSK_AUTH | WPA2_PSK_AUTH):
436 keyType = TKIP_CRYPT; 540 if (!ik->valid)
437 break;
438 case ATH6KL_CIPHER_AES_CCM:
439 keyType = AES_CRYPT;
440 break;
441 default:
442 goto skip_key;
443 }
444 ath6kl_wmi_addkey_cmd(ar->wmi, ik->ik_keyix, keyType,
445 GROUP_USAGE, ik->ik_keylen,
446 (u8 *)&ik->ik_keyrsc,
447 ik->ik_keydata,
448 KEY_OP_INIT_VAL, ik->ik_macaddr,
449 SYNC_BOTH_WMIFLAG);
450 break; 541 break;
542
543 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed addkey for "
544 "the initial group key for AP mode\n");
545 memset(key_rsc, 0, sizeof(key_rsc));
546 res = ath6kl_wmi_addkey_cmd(
547 ar->wmi, ik->key_index, ik->key_type,
548 GROUP_USAGE, ik->key_len, key_rsc, ik->key,
549 KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG);
550 if (res) {
551 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed "
552 "addkey failed: %d\n", res);
451 } 553 }
452skip_key: 554 break;
453 set_bit(CONNECTED, &ar->flag);
454 return;
455 } 555 }
456 556
457 ath6kl_dbg(ATH6KL_DBG_TRC, "new station %pM aid=%d\n", 557 ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
458 bssid, channel); 558 set_bit(CONNECTED, &ar->flag);
559 netif_carrier_on(ar->net_dev);
560}
561
562void ath6kl_connect_ap_mode_sta(struct ath6kl *ar, u16 aid, u8 *mac_addr,
563 u8 keymgmt, u8 ucipher, u8 auth,
564 u8 assoc_req_len, u8 *assoc_info)
565{
566 u8 *ies = NULL, *wpa_ie = NULL, *pos;
567 size_t ies_len = 0;
568 struct station_info sinfo;
459 569
460 ath6kl_add_new_sta(ar, bssid, channel, assoc_info, assoc_resp_len, 570 ath6kl_dbg(ATH6KL_DBG_TRC, "new station %pM aid=%d\n", mac_addr, aid);
461 listen_int & 0xFF, beacon_int, 571
462 (listen_int >> 8) & 0xFF); 572 if (assoc_req_len > sizeof(struct ieee80211_hdr_3addr)) {
573 struct ieee80211_mgmt *mgmt =
574 (struct ieee80211_mgmt *) assoc_info;
575 if (ieee80211_is_assoc_req(mgmt->frame_control) &&
576 assoc_req_len >= sizeof(struct ieee80211_hdr_3addr) +
577 sizeof(mgmt->u.assoc_req)) {
578 ies = mgmt->u.assoc_req.variable;
579 ies_len = assoc_info + assoc_req_len - ies;
580 } else if (ieee80211_is_reassoc_req(mgmt->frame_control) &&
581 assoc_req_len >= sizeof(struct ieee80211_hdr_3addr)
582 + sizeof(mgmt->u.reassoc_req)) {
583 ies = mgmt->u.reassoc_req.variable;
584 ies_len = assoc_info + assoc_req_len - ies;
585 }
586 }
587
588 pos = ies;
589 while (pos && pos + 1 < ies + ies_len) {
590 if (pos + 2 + pos[1] > ies + ies_len)
591 break;
592 if (pos[0] == WLAN_EID_RSN)
593 wpa_ie = pos; /* RSN IE */
594 else if (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
595 pos[1] >= 4 &&
596 pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2) {
597 if (pos[5] == 0x01)
598 wpa_ie = pos; /* WPA IE */
599 else if (pos[5] == 0x04) {
600 wpa_ie = pos; /* WPS IE */
601 break; /* overrides WPA/RSN IE */
602 }
603 }
604 pos += 2 + pos[1];
605 }
606
607 ath6kl_add_new_sta(ar, mac_addr, aid, wpa_ie,
608 wpa_ie ? 2 + wpa_ie[1] : 0,
609 keymgmt, ucipher, auth);
463 610
464 /* send event to application */ 611 /* send event to application */
465 memset(&sinfo, 0, sizeof(sinfo)); 612 memset(&sinfo, 0, sizeof(sinfo));
466 613
467 /* TODO: sinfo.generation */ 614 /* TODO: sinfo.generation */
468 /* TODO: need to deliver (Re)AssocReq IEs somehow.. change in
469 * cfg80211 needed, e.g., by adding those into sinfo
470 */
471 cfg80211_new_sta(ar->net_dev, bssid, &sinfo, GFP_KERNEL);
472 615
473 netif_wake_queue(ar->net_dev); 616 sinfo.assoc_req_ies = ies;
617 sinfo.assoc_req_ies_len = ies_len;
618 sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
474 619
475 return; 620 cfg80211_new_sta(ar->net_dev, mac_addr, &sinfo, GFP_KERNEL);
621
622 netif_wake_queue(ar->net_dev);
476} 623}
477 624
478/* Functions for Tx credit handling */ 625/* Functions for Tx credit handling */
@@ -779,6 +926,41 @@ void ath6kl_disconnect(struct ath6kl *ar)
779 } 926 }
780} 927}
781 928
929void ath6kl_deep_sleep_enable(struct ath6kl *ar)
930{
931 switch (ar->sme_state) {
932 case SME_CONNECTING:
933 cfg80211_connect_result(ar->net_dev, ar->bssid, NULL, 0,
934 NULL, 0,
935 WLAN_STATUS_UNSPECIFIED_FAILURE,
936 GFP_KERNEL);
937 break;
938 case SME_CONNECTED:
939 default:
940 /*
941 * FIXME: oddly enough smeState is in DISCONNECTED during
942 * suspend, why? Need to send disconnected event in that
943 * state.
944 */
945 cfg80211_disconnected(ar->net_dev, 0, NULL, 0, GFP_KERNEL);
946 break;
947 }
948
949 if (test_bit(CONNECTED, &ar->flag) ||
950 test_bit(CONNECT_PEND, &ar->flag))
951 ath6kl_wmi_disconnect_cmd(ar->wmi);
952
953 ar->sme_state = SME_DISCONNECTED;
954
955 /* disable scanning */
956 if (ath6kl_wmi_scanparams_cmd(ar->wmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0,
957 0, 0) != 0)
958 printk(KERN_WARNING "ath6kl: failed to disable scan "
959 "during suspend\n");
960
961 ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED);
962}
963
782/* WMI Event handlers */ 964/* WMI Event handlers */
783 965
784static const char *get_hw_id_string(u32 id) 966static const char *get_hw_id_string(u32 id)
@@ -819,17 +1001,20 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
819 set_bit(WMI_READY, &ar->flag); 1001 set_bit(WMI_READY, &ar->flag);
820 wake_up(&ar->event_wq); 1002 wake_up(&ar->event_wq);
821 1003
822 ath6kl_info("hw %s fw %s\n", 1004 ath6kl_info("hw %s fw %s%s\n",
823 get_hw_id_string(ar->wdev->wiphy->hw_version), 1005 get_hw_id_string(ar->wdev->wiphy->hw_version),
824 ar->wdev->wiphy->fw_version); 1006 ar->wdev->wiphy->fw_version,
1007 test_bit(TESTMODE, &ar->flag) ? " testmode" : "");
825} 1008}
826 1009
827void ath6kl_scan_complete_evt(struct ath6kl *ar, int status) 1010void ath6kl_scan_complete_evt(struct ath6kl *ar, int status)
828{ 1011{
829 ath6kl_cfg80211_scan_complete_event(ar, status); 1012 ath6kl_cfg80211_scan_complete_event(ar, status);
830 1013
831 if (!ar->usr_bss_filter) 1014 if (!ar->usr_bss_filter) {
1015 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
832 ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0); 1016 ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
1017 }
833 1018
834 ath6kl_dbg(ATH6KL_DBG_WLAN_SCAN, "scan complete: %d\n", status); 1019 ath6kl_dbg(ATH6KL_DBG_WLAN_SCAN, "scan complete: %d\n", status);
835} 1020}
@@ -842,13 +1027,6 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
842{ 1027{
843 unsigned long flags; 1028 unsigned long flags;
844 1029
845 if (ar->nw_type == AP_NETWORK) {
846 ath6kl_connect_ap_mode(ar, channel, bssid, listen_int,
847 beacon_int, assoc_resp_len,
848 assoc_info);
849 return;
850 }
851
852 ath6kl_cfg80211_connect_event(ar, channel, bssid, 1030 ath6kl_cfg80211_connect_event(ar, channel, bssid,
853 listen_int, beacon_int, 1031 listen_int, beacon_int,
854 net_type, beacon_ie_len, 1032 net_type, beacon_ie_len,
@@ -880,8 +1058,10 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
880 ar->next_ep_id = ENDPOINT_2; 1058 ar->next_ep_id = ENDPOINT_2;
881 } 1059 }
882 1060
883 if (!ar->usr_bss_filter) 1061 if (!ar->usr_bss_filter) {
884 ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0); 1062 set_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
1063 ath6kl_wmi_bssfilter_cmd(ar->wmi, CURRENT_BSS_FILTER, 0);
1064 }
885} 1065}
886 1066
887void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast) 1067void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast)
@@ -915,26 +1095,11 @@ static void ath6kl_update_target_stats(struct ath6kl *ar, u8 *ptr, u32 len)
915 (struct wmi_target_stats *) ptr; 1095 (struct wmi_target_stats *) ptr;
916 struct target_stats *stats = &ar->target_stats; 1096 struct target_stats *stats = &ar->target_stats;
917 struct tkip_ccmp_stats *ccmp_stats; 1097 struct tkip_ccmp_stats *ccmp_stats;
918 struct bss *conn_bss = NULL;
919 struct cserv_stats *c_stats;
920 u8 ac; 1098 u8 ac;
921 1099
922 if (len < sizeof(*tgt_stats)) 1100 if (len < sizeof(*tgt_stats))
923 return; 1101 return;
924 1102
925 /* update the RSSI of the connected bss */
926 if (test_bit(CONNECTED, &ar->flag)) {
927 conn_bss = ath6kl_wmi_find_node(ar->wmi, ar->bssid);
928 if (conn_bss) {
929 c_stats = &tgt_stats->cserv_stats;
930 conn_bss->ni_rssi =
931 a_sle16_to_cpu(c_stats->cs_ave_beacon_rssi);
932 conn_bss->ni_snr =
933 tgt_stats->cserv_stats.cs_ave_beacon_snr;
934 ath6kl_wmi_node_return(ar->wmi, conn_bss);
935 }
936 }
937
938 ath6kl_dbg(ATH6KL_DBG_TRC, "updating target stats\n"); 1103 ath6kl_dbg(ATH6KL_DBG_TRC, "updating target stats\n");
939 1104
940 stats->tx_pkt += le32_to_cpu(tgt_stats->stats.tx.pkt); 1105 stats->tx_pkt += le32_to_cpu(tgt_stats->stats.tx.pkt);
@@ -1165,7 +1330,6 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
1165 u8 assoc_resp_len, u8 *assoc_info, 1330 u8 assoc_resp_len, u8 *assoc_info,
1166 u16 prot_reason_status) 1331 u16 prot_reason_status)
1167{ 1332{
1168 struct bss *wmi_ssid_node = NULL;
1169 unsigned long flags; 1333 unsigned long flags;
1170 1334
1171 if (ar->nw_type == AP_NETWORK) { 1335 if (ar->nw_type == AP_NETWORK) {
@@ -1188,7 +1352,10 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
1188 cfg80211_del_sta(ar->net_dev, bssid, GFP_KERNEL); 1352 cfg80211_del_sta(ar->net_dev, bssid, GFP_KERNEL);
1189 } 1353 }
1190 1354
1191 clear_bit(CONNECTED, &ar->flag); 1355 if (memcmp(ar->net_dev->dev_addr, bssid, ETH_ALEN) == 0) {
1356 memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
1357 clear_bit(CONNECTED, &ar->flag);
1358 }
1192 return; 1359 return;
1193 } 1360 }
1194 1361
@@ -1222,33 +1389,6 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
1222 } 1389 }
1223 } 1390 }
1224 1391
1225 if ((reason == NO_NETWORK_AVAIL) && test_bit(WMI_READY, &ar->flag)) {
1226 ath6kl_wmi_node_free(ar->wmi, bssid);
1227
1228 /*
1229 * In case any other same SSID nodes are present remove it,
1230 * since those nodes also not available now.
1231 */
1232 do {
1233 /*
1234 * Find the nodes based on SSID and remove it
1235 *
1236 * Note: This case will not work out for
1237 * Hidden-SSID
1238 */
1239 wmi_ssid_node = ath6kl_wmi_find_ssid_node(ar->wmi,
1240 ar->ssid,
1241 ar->ssid_len,
1242 false,
1243 true);
1244
1245 if (wmi_ssid_node)
1246 ath6kl_wmi_node_free(ar->wmi,
1247 wmi_ssid_node->ni_macaddr);
1248
1249 } while (wmi_ssid_node);
1250 }
1251
1252 /* update connect & link status atomically */ 1392 /* update connect & link status atomically */
1253 spin_lock_irqsave(&ar->lock, flags); 1393 spin_lock_irqsave(&ar->lock, flags);
1254 clear_bit(CONNECTED, &ar->flag); 1394 clear_bit(CONNECTED, &ar->flag);
@@ -1331,7 +1471,7 @@ void init_netdev(struct net_device *dev)
1331 dev->needed_headroom = ETH_HLEN; 1471 dev->needed_headroom = ETH_HLEN;
1332 dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) + 1472 dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) +
1333 sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH 1473 sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH
1334 + WMI_MAX_TX_META_SZ; 1474 + WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES;
1335 1475
1336 return; 1476 return;
1337} 1477}
diff --git a/drivers/net/wireless/ath/ath6kl/node.c b/drivers/net/wireless/ath/ath6kl/node.c
deleted file mode 100644
index 131205c610b9..000000000000
--- a/drivers/net/wireless/ath/ath6kl/node.c
+++ /dev/null
@@ -1,234 +0,0 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18#include "wmi.h"
19#include "debug.h"
20
21struct bss *wlan_node_alloc(int wh_size)
22{
23 struct bss *ni;
24
25 ni = kzalloc(sizeof(struct bss), GFP_ATOMIC);
26
27 if ((ni != NULL) && wh_size) {
28 ni->ni_buf = kmalloc(wh_size, GFP_ATOMIC);
29 if (ni->ni_buf == NULL) {
30 kfree(ni);
31 return NULL;
32 }
33 }
34
35 return ni;
36}
37
38void wlan_node_free(struct bss *ni)
39{
40 kfree(ni->ni_buf);
41 kfree(ni);
42}
43
44void wlan_setup_node(struct ath6kl_node_table *nt, struct bss *ni,
45 const u8 *mac_addr)
46{
47 int hash;
48
49 memcpy(ni->ni_macaddr, mac_addr, ETH_ALEN);
50 hash = ATH6KL_NODE_HASH(mac_addr);
51 ni->ni_refcnt = 1;
52
53 ni->ni_tstamp = jiffies_to_msecs(jiffies);
54 ni->ni_actcnt = WLAN_NODE_INACT_CNT;
55
56 spin_lock_bh(&nt->nt_nodelock);
57
58 /* insert at the end of the node list */
59 ni->ni_list_next = NULL;
60 ni->ni_list_prev = nt->nt_node_last;
61 if (nt->nt_node_last != NULL)
62 nt->nt_node_last->ni_list_next = ni;
63
64 nt->nt_node_last = ni;
65 if (nt->nt_node_first == NULL)
66 nt->nt_node_first = ni;
67
68 /* insert into the hash list */
69 ni->ni_hash_next = nt->nt_hash[hash];
70 if (ni->ni_hash_next != NULL)
71 nt->nt_hash[hash]->ni_hash_prev = ni;
72
73 ni->ni_hash_prev = NULL;
74 nt->nt_hash[hash] = ni;
75
76 spin_unlock_bh(&nt->nt_nodelock);
77}
78
79struct bss *wlan_find_node(struct ath6kl_node_table *nt,
80 const u8 *mac_addr)
81{
82 struct bss *ni, *found_ni = NULL;
83 int hash;
84
85 spin_lock_bh(&nt->nt_nodelock);
86
87 hash = ATH6KL_NODE_HASH(mac_addr);
88 for (ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) {
89 if (memcmp(ni->ni_macaddr, mac_addr, ETH_ALEN) == 0) {
90 ni->ni_refcnt++;
91 found_ni = ni;
92 break;
93 }
94 }
95
96 spin_unlock_bh(&nt->nt_nodelock);
97
98 return found_ni;
99}
100
101void wlan_node_reclaim(struct ath6kl_node_table *nt, struct bss *ni)
102{
103 int hash;
104
105 spin_lock_bh(&nt->nt_nodelock);
106
107 if (ni->ni_list_prev == NULL)
108 /* fix list head */
109 nt->nt_node_first = ni->ni_list_next;
110 else
111 ni->ni_list_prev->ni_list_next = ni->ni_list_next;
112
113 if (ni->ni_list_next == NULL)
114 /* fix list tail */
115 nt->nt_node_last = ni->ni_list_prev;
116 else
117 ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
118
119 if (ni->ni_hash_prev == NULL) {
120 /* first in list so fix the list head */
121 hash = ATH6KL_NODE_HASH(ni->ni_macaddr);
122 nt->nt_hash[hash] = ni->ni_hash_next;
123 } else {
124 ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
125 }
126
127 if (ni->ni_hash_next != NULL)
128 ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
129
130 wlan_node_free(ni);
131
132 spin_unlock_bh(&nt->nt_nodelock);
133}
134
135static void wlan_node_dec_free(struct bss *ni)
136{
137 if ((ni->ni_refcnt--) == 1)
138 wlan_node_free(ni);
139}
140
141void wlan_free_allnodes(struct ath6kl_node_table *nt)
142{
143 struct bss *ni;
144
145 while ((ni = nt->nt_node_first) != NULL)
146 wlan_node_reclaim(nt, ni);
147}
148
149void wlan_iterate_nodes(struct ath6kl_node_table *nt, void *arg)
150{
151 struct bss *ni;
152
153 spin_lock_bh(&nt->nt_nodelock);
154 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
155 ni->ni_refcnt++;
156 ath6kl_cfg80211_scan_node(arg, ni);
157 wlan_node_dec_free(ni);
158 }
159 spin_unlock_bh(&nt->nt_nodelock);
160}
161
162void wlan_node_table_init(struct ath6kl_node_table *nt)
163{
164 ath6kl_dbg(ATH6KL_DBG_WLAN_NODE, "node table = 0x%lx\n",
165 (unsigned long)nt);
166
167 memset(nt, 0, sizeof(struct ath6kl_node_table));
168
169 spin_lock_init(&nt->nt_nodelock);
170
171 nt->nt_node_age = WLAN_NODE_INACT_TIMEOUT_MSEC;
172}
173
174void wlan_refresh_inactive_nodes(struct ath6kl *ar)
175{
176 struct ath6kl_node_table *nt = &ar->scan_table;
177 struct bss *bss;
178 u32 now;
179
180 now = jiffies_to_msecs(jiffies);
181 bss = nt->nt_node_first;
182 while (bss != NULL) {
183 /* refresh all nodes except the current bss */
184 if (memcmp(ar->bssid, bss->ni_macaddr, ETH_ALEN) != 0) {
185 if (((now - bss->ni_tstamp) > nt->nt_node_age)
186 || --bss->ni_actcnt == 0) {
187 wlan_node_reclaim(nt, bss);
188 }
189 }
190 bss = bss->ni_list_next;
191 }
192}
193
194void wlan_node_table_cleanup(struct ath6kl_node_table *nt)
195{
196 wlan_free_allnodes(nt);
197}
198
199struct bss *wlan_find_ssid_node(struct ath6kl_node_table *nt, u8 * ssid,
200 u32 ssid_len, bool is_wpa2, bool match_ssid)
201{
202 struct bss *ni, *found_ni = NULL;
203 u8 *ie_ssid;
204
205 spin_lock_bh(&nt->nt_nodelock);
206
207 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
208
209 ie_ssid = ni->ni_cie.ie_ssid;
210
211 if ((ie_ssid[1] <= IEEE80211_MAX_SSID_LEN) &&
212 (memcmp(ssid, &ie_ssid[2], ssid_len) == 0)) {
213
214 if (match_ssid ||
215 (is_wpa2 && ni->ni_cie.ie_rsn != NULL) ||
216 (!is_wpa2 && ni->ni_cie.ie_wpa != NULL)) {
217 ni->ni_refcnt++;
218 found_ni = ni;
219 break;
220 }
221 }
222 }
223
224 spin_unlock_bh(&nt->nt_nodelock);
225
226 return found_ni;
227}
228
229void wlan_node_return(struct ath6kl_node_table *nt, struct bss *ni)
230{
231 spin_lock_bh(&nt->nt_nodelock);
232 wlan_node_dec_free(ni);
233 spin_unlock_bh(&nt->nt_nodelock);
234}
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 34171604cbe4..f1dc311ee0c7 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -25,6 +25,7 @@
25#include "hif-ops.h" 25#include "hif-ops.h"
26#include "target.h" 26#include "target.h"
27#include "debug.h" 27#include "debug.h"
28#include "cfg80211.h"
28 29
29struct ath6kl_sdio { 30struct ath6kl_sdio {
30 struct sdio_func *func; 31 struct sdio_func *func;
@@ -134,10 +135,12 @@ static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr,
134 int ret = 0; 135 int ret = 0;
135 136
136 if (request & HIF_WRITE) { 137 if (request & HIF_WRITE) {
138 /* FIXME: looks like ugly workaround for something */
137 if (addr >= HIF_MBOX_BASE_ADDR && 139 if (addr >= HIF_MBOX_BASE_ADDR &&
138 addr <= HIF_MBOX_END_ADDR) 140 addr <= HIF_MBOX_END_ADDR)
139 addr += (HIF_MBOX_WIDTH - len); 141 addr += (HIF_MBOX_WIDTH - len);
140 142
143 /* FIXME: this also looks like ugly workaround */
141 if (addr == HIF_MBOX0_EXT_BASE_ADDR) 144 if (addr == HIF_MBOX0_EXT_BASE_ADDR)
142 addr += HIF_MBOX0_EXT_WIDTH - len; 145 addr += HIF_MBOX0_EXT_WIDTH - len;
143 146
@@ -152,6 +155,11 @@ static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr,
152 ret = sdio_memcpy_fromio(func, buf, addr, len); 155 ret = sdio_memcpy_fromio(func, buf, addr, len);
153 } 156 }
154 157
158 ath6kl_dbg(ATH6KL_DBG_SDIO, "%s addr 0x%x%s buf 0x%p len %d\n",
159 request & HIF_WRITE ? "wr" : "rd", addr,
160 request & HIF_FIXED_ADDRESS ? " (fixed)" : "", buf, len);
161 ath6kl_dbg_dump(ATH6KL_DBG_SDIO_DUMP, NULL, "sdio ", buf, len);
162
155 return ret; 163 return ret;
156} 164}
157 165
@@ -172,7 +180,8 @@ static struct bus_request *ath6kl_sdio_alloc_busreq(struct ath6kl_sdio *ar_sdio)
172 list_del(&bus_req->list); 180 list_del(&bus_req->list);
173 181
174 spin_unlock_irqrestore(&ar_sdio->lock, flag); 182 spin_unlock_irqrestore(&ar_sdio->lock, flag);
175 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: bus request 0x%p\n", __func__, bus_req); 183 ath6kl_dbg(ATH6KL_DBG_SCATTER, "%s: bus request 0x%p\n",
184 __func__, bus_req);
176 185
177 return bus_req; 186 return bus_req;
178} 187}
@@ -182,7 +191,8 @@ static void ath6kl_sdio_free_bus_req(struct ath6kl_sdio *ar_sdio,
182{ 191{
183 unsigned long flag; 192 unsigned long flag;
184 193
185 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: bus request 0x%p\n", __func__, bus_req); 194 ath6kl_dbg(ATH6KL_DBG_SCATTER, "%s: bus request 0x%p\n",
195 __func__, bus_req);
186 196
187 spin_lock_irqsave(&ar_sdio->lock, flag); 197 spin_lock_irqsave(&ar_sdio->lock, flag);
188 list_add_tail(&bus_req->list, &ar_sdio->bus_req_freeq); 198 list_add_tail(&bus_req->list, &ar_sdio->bus_req_freeq);
@@ -213,16 +223,6 @@ static void ath6kl_sdio_setup_scat_data(struct hif_scatter_req *scat_req,
213 223
214 /* assemble SG list */ 224 /* assemble SG list */
215 for (i = 0; i < scat_req->scat_entries; i++, sg++) { 225 for (i = 0; i < scat_req->scat_entries; i++, sg++) {
216 if ((unsigned long)scat_req->scat_list[i].buf & 0x3)
217 /*
218 * Some scatter engines can handle unaligned
219 * buffers, print this as informational only.
220 */
221 ath6kl_dbg(ATH6KL_DBG_SCATTER,
222 "(%s) scatter buffer is unaligned 0x%p\n",
223 scat_req->req & HIF_WRITE ? "WR" : "RD",
224 scat_req->scat_list[i].buf);
225
226 ath6kl_dbg(ATH6KL_DBG_SCATTER, "%d: addr:0x%p, len:%d\n", 226 ath6kl_dbg(ATH6KL_DBG_SCATTER, "%d: addr:0x%p, len:%d\n",
227 i, scat_req->scat_list[i].buf, 227 i, scat_req->scat_list[i].buf,
228 scat_req->scat_list[i].len); 228 scat_req->scat_list[i].len);
@@ -447,6 +447,8 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)
447 int status; 447 int status;
448 struct ath6kl_sdio *ar_sdio; 448 struct ath6kl_sdio *ar_sdio;
449 449
450 ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n");
451
450 ar_sdio = sdio_get_drvdata(func); 452 ar_sdio = sdio_get_drvdata(func);
451 atomic_set(&ar_sdio->irq_handling, 1); 453 atomic_set(&ar_sdio->irq_handling, 1);
452 454
@@ -684,7 +686,7 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
684 MAX_SCATTER_REQUESTS, virt_scat); 686 MAX_SCATTER_REQUESTS, virt_scat);
685 687
686 if (!ret) { 688 if (!ret) {
687 ath6kl_dbg(ATH6KL_DBG_ANY, 689 ath6kl_dbg(ATH6KL_DBG_SCATTER,
688 "hif-scatter enabled: max scatter req : %d entries: %d\n", 690 "hif-scatter enabled: max scatter req : %d entries: %d\n",
689 MAX_SCATTER_REQUESTS, 691 MAX_SCATTER_REQUESTS,
690 MAX_SCATTER_ENTRIES_PER_REQ); 692 MAX_SCATTER_ENTRIES_PER_REQ);
@@ -709,7 +711,7 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
709 return ret; 711 return ret;
710 } 712 }
711 713
712 ath6kl_dbg(ATH6KL_DBG_ANY, 714 ath6kl_dbg(ATH6KL_DBG_SCATTER,
713 "Vitual scatter enabled, max_scat_req:%d, entries:%d\n", 715 "Vitual scatter enabled, max_scat_req:%d, entries:%d\n",
714 ATH6KL_SCATTER_REQS, ATH6KL_SCATTER_ENTRIES_PER_REQ); 716 ATH6KL_SCATTER_REQS, ATH6KL_SCATTER_ENTRIES_PER_REQ);
715 717
@@ -721,6 +723,34 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
721 return 0; 723 return 0;
722} 724}
723 725
726static int ath6kl_sdio_suspend(struct ath6kl *ar)
727{
728 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
729 struct sdio_func *func = ar_sdio->func;
730 mmc_pm_flag_t flags;
731 int ret;
732
733 flags = sdio_get_host_pm_caps(func);
734
735 if (!(flags & MMC_PM_KEEP_POWER))
736 /* as host doesn't support keep power we need to bail out */
737 ath6kl_dbg(ATH6KL_DBG_SDIO,
738 "func %d doesn't support MMC_PM_KEEP_POWER\n",
739 func->num);
740 return -EINVAL;
741
742 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
743 if (ret) {
744 printk(KERN_ERR "ath6kl: set sdio pm flags failed: %d\n",
745 ret);
746 return ret;
747 }
748
749 ath6kl_deep_sleep_enable(ar);
750
751 return 0;
752}
753
724static const struct ath6kl_hif_ops ath6kl_sdio_ops = { 754static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
725 .read_write_sync = ath6kl_sdio_read_write_sync, 755 .read_write_sync = ath6kl_sdio_read_write_sync,
726 .write_async = ath6kl_sdio_write_async, 756 .write_async = ath6kl_sdio_write_async,
@@ -731,6 +761,7 @@ static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
731 .enable_scatter = ath6kl_sdio_enable_scatter, 761 .enable_scatter = ath6kl_sdio_enable_scatter,
732 .scat_req_rw = ath6kl_sdio_async_rw_scatter, 762 .scat_req_rw = ath6kl_sdio_async_rw_scatter,
733 .cleanup_scatter = ath6kl_sdio_cleanup_scatter, 763 .cleanup_scatter = ath6kl_sdio_cleanup_scatter,
764 .suspend = ath6kl_sdio_suspend,
734}; 765};
735 766
736static int ath6kl_sdio_probe(struct sdio_func *func, 767static int ath6kl_sdio_probe(struct sdio_func *func,
@@ -741,10 +772,10 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
741 struct ath6kl *ar; 772 struct ath6kl *ar;
742 int count; 773 int count;
743 774
744 ath6kl_dbg(ATH6KL_DBG_TRC, 775 ath6kl_dbg(ATH6KL_DBG_SDIO,
745 "%s: func: 0x%X, vendor id: 0x%X, dev id: 0x%X, block size: 0x%X/0x%X\n", 776 "new func %d vendor 0x%x device 0x%x block 0x%x/0x%x\n",
746 __func__, func->num, func->vendor, 777 func->num, func->vendor, func->device,
747 func->device, func->max_blksize, func->cur_blksize); 778 func->max_blksize, func->cur_blksize);
748 779
749 ar_sdio = kzalloc(sizeof(struct ath6kl_sdio), GFP_KERNEL); 780 ar_sdio = kzalloc(sizeof(struct ath6kl_sdio), GFP_KERNEL);
750 if (!ar_sdio) 781 if (!ar_sdio)
@@ -800,10 +831,10 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
800 ath6kl_err("Failed to enable 4-bit async irq mode %d\n", 831 ath6kl_err("Failed to enable 4-bit async irq mode %d\n",
801 ret); 832 ret);
802 sdio_release_host(func); 833 sdio_release_host(func);
803 goto err_dma; 834 goto err_cfg80211;
804 } 835 }
805 836
806 ath6kl_dbg(ATH6KL_DBG_TRC, "4-bit async irq mode enabled\n"); 837 ath6kl_dbg(ATH6KL_DBG_SDIO, "4-bit async irq mode enabled\n");
807 } 838 }
808 839
809 /* give us some time to enable, in ms */ 840 /* give us some time to enable, in ms */
@@ -813,7 +844,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
813 844
814 ret = ath6kl_sdio_power_on(ar_sdio); 845 ret = ath6kl_sdio_power_on(ar_sdio);
815 if (ret) 846 if (ret)
816 goto err_dma; 847 goto err_cfg80211;
817 848
818 sdio_claim_host(func); 849 sdio_claim_host(func);
819 850
@@ -837,6 +868,8 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
837 868
838err_off: 869err_off:
839 ath6kl_sdio_power_off(ar_sdio); 870 ath6kl_sdio_power_off(ar_sdio);
871err_cfg80211:
872 ath6kl_cfg80211_deinit(ar_sdio->ar);
840err_dma: 873err_dma:
841 kfree(ar_sdio->dma_buffer); 874 kfree(ar_sdio->dma_buffer);
842err_hif: 875err_hif:
@@ -849,6 +882,10 @@ static void ath6kl_sdio_remove(struct sdio_func *func)
849{ 882{
850 struct ath6kl_sdio *ar_sdio; 883 struct ath6kl_sdio *ar_sdio;
851 884
885 ath6kl_dbg(ATH6KL_DBG_SDIO,
886 "removed func %d vendor 0x%x device 0x%x\n",
887 func->num, func->vendor, func->device);
888
852 ar_sdio = sdio_get_drvdata(func); 889 ar_sdio = sdio_get_drvdata(func);
853 890
854 ath6kl_stop_txrx(ar_sdio->ar); 891 ath6kl_stop_txrx(ar_sdio->ar);
diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h
index 519a013c9991..c9a76051f042 100644
--- a/drivers/net/wireless/ath/ath6kl/target.h
+++ b/drivers/net/wireless/ath/ath6kl/target.h
@@ -20,6 +20,9 @@
20#define AR6003_BOARD_DATA_SZ 1024 20#define AR6003_BOARD_DATA_SZ 1024
21#define AR6003_BOARD_EXT_DATA_SZ 768 21#define AR6003_BOARD_EXT_DATA_SZ 768
22 22
23#define AR6004_BOARD_DATA_SZ 7168
24#define AR6004_BOARD_EXT_DATA_SZ 0
25
23#define RESET_CONTROL_ADDRESS 0x00000000 26#define RESET_CONTROL_ADDRESS 0x00000000
24#define RESET_CONTROL_COLD_RST 0x00000100 27#define RESET_CONTROL_COLD_RST 0x00000100
25#define RESET_CONTROL_MBOX_RST 0x00000004 28#define RESET_CONTROL_MBOX_RST 0x00000004
@@ -135,7 +138,8 @@
135 * between the two, and is intended to remain constant (with additions only 138 * between the two, and is intended to remain constant (with additions only
136 * at the end). 139 * at the end).
137 */ 140 */
138#define ATH6KL_HI_START_ADDR 0x00540600 141#define ATH6KL_AR6003_HI_START_ADDR 0x00540600
142#define ATH6KL_AR6004_HI_START_ADDR 0x00400800
139 143
140/* 144/*
141 * These are items that the Host may need to access 145 * These are items that the Host may need to access
@@ -300,6 +304,11 @@ struct host_interest {
300#define HI_OPTION_FW_MODE_BSS_STA 0x1 304#define HI_OPTION_FW_MODE_BSS_STA 0x1
301#define HI_OPTION_FW_MODE_AP 0x2 305#define HI_OPTION_FW_MODE_AP 0x2
302 306
307#define HI_OPTION_FW_SUBMODE_NONE 0x0
308#define HI_OPTION_FW_SUBMODE_P2PDEV 0x1
309#define HI_OPTION_FW_SUBMODE_P2PCLIENT 0x2
310#define HI_OPTION_FW_SUBMODE_P2PGO 0x3
311
303#define HI_OPTION_NUM_DEV_SHIFT 0x9 312#define HI_OPTION_NUM_DEV_SHIFT 0x9
304 313
305#define HI_OPTION_FW_BRIDGE_SHIFT 0x04 314#define HI_OPTION_FW_BRIDGE_SHIFT 0x04
@@ -312,20 +321,44 @@ struct host_interest {
312|------------------------------------------------------------------------------| 321|------------------------------------------------------------------------------|
313*/ 322*/
314#define HI_OPTION_FW_MODE_SHIFT 0xC 323#define HI_OPTION_FW_MODE_SHIFT 0xC
324#define HI_OPTION_FW_SUBMODE_SHIFT 0x14
315 325
316/* Convert a Target virtual address into a Target physical address */ 326/* Convert a Target virtual address into a Target physical address */
317#define TARG_VTOP(vaddr) (vaddr & 0x001fffff) 327#define AR6003_VTOP(vaddr) ((vaddr) & 0x001fffff)
328#define AR6004_VTOP(vaddr) (vaddr)
329
330#define TARG_VTOP(target_type, vaddr) \
331 (((target_type) == TARGET_TYPE_AR6003) ? AR6003_VTOP(vaddr) : \
332 (((target_type) == TARGET_TYPE_AR6004) ? AR6004_VTOP(vaddr) : 0))
318 333
319#define AR6003_REV2_APP_START_OVERRIDE 0x944C00
320#define AR6003_REV2_APP_LOAD_ADDRESS 0x543180 334#define AR6003_REV2_APP_LOAD_ADDRESS 0x543180
321#define AR6003_REV2_BOARD_EXT_DATA_ADDRESS 0x57E500 335#define AR6003_REV2_BOARD_EXT_DATA_ADDRESS 0x57E500
322#define AR6003_REV2_DATASET_PATCH_ADDRESS 0x57e884 336#define AR6003_REV2_DATASET_PATCH_ADDRESS 0x57e884
323#define AR6003_REV2_RAM_RESERVE_SIZE 6912 337#define AR6003_REV2_RAM_RESERVE_SIZE 6912
324 338
325#define AR6003_REV3_APP_START_OVERRIDE 0x945d00
326#define AR6003_REV3_APP_LOAD_ADDRESS 0x545000 339#define AR6003_REV3_APP_LOAD_ADDRESS 0x545000
327#define AR6003_REV3_BOARD_EXT_DATA_ADDRESS 0x542330 340#define AR6003_REV3_BOARD_EXT_DATA_ADDRESS 0x542330
328#define AR6003_REV3_DATASET_PATCH_ADDRESS 0x57FF74 341#define AR6003_REV3_DATASET_PATCH_ADDRESS 0x57FF74
329#define AR6003_REV3_RAM_RESERVE_SIZE 512 342#define AR6003_REV3_RAM_RESERVE_SIZE 512
330 343
344#define AR6004_REV1_BOARD_DATA_ADDRESS 0x435400
345#define AR6004_REV1_BOARD_EXT_DATA_ADDRESS 0x437000
346#define AR6004_REV1_RAM_RESERVE_SIZE 11264
347
348#define ATH6KL_FWLOG_PAYLOAD_SIZE 1500
349
350struct ath6kl_dbglog_buf {
351 __le32 next;
352 __le32 buffer_addr;
353 __le32 bufsize;
354 __le32 length;
355 __le32 count;
356 __le32 free;
357} __packed;
358
359struct ath6kl_dbglog_hdr {
360 __le32 dbuf_addr;
361 __le32 dropped;
362} __packed;
363
331#endif 364#endif
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.c b/drivers/net/wireless/ath/ath6kl/testmode.c
new file mode 100644
index 000000000000..381eb66a605f
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/testmode.c
@@ -0,0 +1,167 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "testmode.h"
18
19#include <net/netlink.h>
20
21enum ath6kl_tm_attr {
22 __ATH6KL_TM_ATTR_INVALID = 0,
23 ATH6KL_TM_ATTR_CMD = 1,
24 ATH6KL_TM_ATTR_DATA = 2,
25
26 /* keep last */
27 __ATH6KL_TM_ATTR_AFTER_LAST,
28 ATH6KL_TM_ATTR_MAX = __ATH6KL_TM_ATTR_AFTER_LAST - 1,
29};
30
31enum ath6kl_tm_cmd {
32 ATH6KL_TM_CMD_TCMD = 0,
33 ATH6KL_TM_CMD_RX_REPORT = 1,
34};
35
36#define ATH6KL_TM_DATA_MAX_LEN 5000
37
38static const struct nla_policy ath6kl_tm_policy[ATH6KL_TM_ATTR_MAX + 1] = {
39 [ATH6KL_TM_ATTR_CMD] = { .type = NLA_U32 },
40 [ATH6KL_TM_ATTR_DATA] = { .type = NLA_BINARY,
41 .len = ATH6KL_TM_DATA_MAX_LEN },
42};
43
44void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len)
45{
46 if (down_interruptible(&ar->sem))
47 return;
48
49 kfree(ar->tm.rx_report);
50
51 ar->tm.rx_report = kmemdup(buf, buf_len, GFP_KERNEL);
52 ar->tm.rx_report_len = buf_len;
53
54 up(&ar->sem);
55
56 wake_up(&ar->event_wq);
57}
58
59static int ath6kl_tm_rx_report(struct ath6kl *ar, void *buf, size_t buf_len,
60 struct sk_buff *skb)
61{
62 int ret = 0;
63 long left;
64
65 if (down_interruptible(&ar->sem))
66 return -ERESTARTSYS;
67
68 if (!test_bit(WMI_READY, &ar->flag)) {
69 ret = -EIO;
70 goto out;
71 }
72
73 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
74 ret = -EBUSY;
75 goto out;
76 }
77
78 if (ath6kl_wmi_test_cmd(ar->wmi, buf, buf_len) < 0) {
79 up(&ar->sem);
80 return -EIO;
81 }
82
83 left = wait_event_interruptible_timeout(ar->event_wq,
84 ar->tm.rx_report != NULL,
85 WMI_TIMEOUT);
86
87 if (left == 0) {
88 ret = -ETIMEDOUT;
89 goto out;
90 } else if (left < 0) {
91 ret = left;
92 goto out;
93 }
94
95 if (ar->tm.rx_report == NULL || ar->tm.rx_report_len == 0) {
96 ret = -EINVAL;
97 goto out;
98 }
99
100 NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, ar->tm.rx_report_len,
101 ar->tm.rx_report);
102
103 kfree(ar->tm.rx_report);
104 ar->tm.rx_report = NULL;
105
106out:
107 up(&ar->sem);
108
109 return ret;
110
111nla_put_failure:
112 ret = -ENOBUFS;
113 goto out;
114}
115
116int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
117{
118 struct ath6kl *ar = wiphy_priv(wiphy);
119 struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1];
120 int err, buf_len, reply_len;
121 struct sk_buff *skb;
122 void *buf;
123
124 err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len,
125 ath6kl_tm_policy);
126 if (err)
127 return err;
128
129 if (!tb[ATH6KL_TM_ATTR_CMD])
130 return -EINVAL;
131
132 switch (nla_get_u32(tb[ATH6KL_TM_ATTR_CMD])) {
133 case ATH6KL_TM_CMD_TCMD:
134 if (!tb[ATH6KL_TM_ATTR_DATA])
135 return -EINVAL;
136
137 buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]);
138 buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]);
139
140 ath6kl_wmi_test_cmd(ar->wmi, buf, buf_len);
141
142 return 0;
143
144 break;
145 case ATH6KL_TM_CMD_RX_REPORT:
146 if (!tb[ATH6KL_TM_ATTR_DATA])
147 return -EINVAL;
148
149 buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]);
150 buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]);
151
152 reply_len = nla_total_size(ATH6KL_TM_DATA_MAX_LEN);
153 skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len);
154 if (!skb)
155 return -ENOMEM;
156
157 err = ath6kl_tm_rx_report(ar, buf, buf_len, skb);
158 if (err < 0) {
159 kfree_skb(skb);
160 return err;
161 }
162
163 return cfg80211_testmode_reply(skb);
164 default:
165 return -EOPNOTSUPP;
166 }
167}
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.h b/drivers/net/wireless/ath/ath6kl/testmode.h
new file mode 100644
index 000000000000..43dffcc11fb1
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/testmode.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "core.h"
18
19#ifdef CONFIG_NL80211_TESTMODE
20
21void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len);
22int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len);
23
24#else
25
26static inline void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf,
27 size_t buf_len)
28{
29}
30
31static inline int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
32{
33 return 0;
34}
35
36#endif
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 167bdb9cf68d..a7117074f81c 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -239,7 +239,6 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
239 u16 htc_tag = ATH6KL_DATA_PKT_TAG; 239 u16 htc_tag = ATH6KL_DATA_PKT_TAG;
240 u8 ac = 99 ; /* initialize to unmapped ac */ 240 u8 ac = 99 ; /* initialize to unmapped ac */
241 bool chk_adhoc_ps_mapping = false, more_data = false; 241 bool chk_adhoc_ps_mapping = false, more_data = false;
242 struct wmi_tx_meta_v2 meta_v2;
243 int ret; 242 int ret;
244 243
245 ath6kl_dbg(ATH6KL_DBG_WLAN_TX, 244 ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
@@ -262,8 +261,6 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
262 } 261 }
263 262
264 if (test_bit(WMI_ENABLED, &ar->flag)) { 263 if (test_bit(WMI_ENABLED, &ar->flag)) {
265 memset(&meta_v2, 0, sizeof(meta_v2));
266
267 if (skb_headroom(skb) < dev->needed_headroom) { 264 if (skb_headroom(skb) < dev->needed_headroom) {
268 WARN_ON(1); 265 WARN_ON(1);
269 goto fail_tx; 266 goto fail_tx;
@@ -320,12 +317,31 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
320 317
321 spin_unlock_bh(&ar->lock); 318 spin_unlock_bh(&ar->lock);
322 319
320 if (!IS_ALIGNED((unsigned long) skb->data - HTC_HDR_LENGTH, 4) &&
321 skb_cloned(skb)) {
322 /*
323 * We will touch (move the buffer data to align it. Since the
324 * skb buffer is cloned and not only the header is changed, we
325 * have to copy it to allow the changes. Since we are copying
326 * the data here, we may as well align it by reserving suitable
327 * headroom to avoid the memmove in ath6kl_htc_tx_buf_align().
328 */
329 struct sk_buff *nskb;
330
331 nskb = skb_copy_expand(skb, HTC_HDR_LENGTH, 0, GFP_ATOMIC);
332 if (nskb == NULL)
333 goto fail_tx;
334 kfree_skb(skb);
335 skb = nskb;
336 }
337
323 cookie->skb = skb; 338 cookie->skb = skb;
324 cookie->map_no = map_no; 339 cookie->map_no = map_no;
325 set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len, 340 set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len,
326 eid, htc_tag); 341 eid, htc_tag);
327 342
328 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, skb->data, skb->len); 343 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "tx ",
344 skb->data, skb->len);
329 345
330 /* 346 /*
331 * HTC interface is asynchronous, if this fails, cleanup will 347 * HTC interface is asynchronous, if this fails, cleanup will
@@ -689,6 +705,8 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint)
689 break; 705 break;
690 706
691 packet = (struct htc_packet *) skb->head; 707 packet = (struct htc_packet *) skb->head;
708 if (!IS_ALIGNED((unsigned long) skb->data, 4))
709 skb->data = PTR_ALIGN(skb->data - 4, 4);
692 set_htc_rxpkt_info(packet, skb, skb->data, 710 set_htc_rxpkt_info(packet, skb, skb->data,
693 ATH6KL_BUFFER_SIZE, endpoint); 711 ATH6KL_BUFFER_SIZE, endpoint);
694 list_add_tail(&packet->list, &queue); 712 list_add_tail(&packet->list, &queue);
@@ -709,6 +727,8 @@ void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count)
709 return; 727 return;
710 728
711 packet = (struct htc_packet *) skb->head; 729 packet = (struct htc_packet *) skb->head;
730 if (!IS_ALIGNED((unsigned long) skb->data, 4))
731 skb->data = PTR_ALIGN(skb->data - 4, 4);
712 set_htc_rxpkt_info(packet, skb, skb->data, 732 set_htc_rxpkt_info(packet, skb, skb->data,
713 ATH6KL_AMSDU_BUFFER_SIZE, 0); 733 ATH6KL_AMSDU_BUFFER_SIZE, 0);
714 spin_lock_bh(&ar->lock); 734 spin_lock_bh(&ar->lock);
@@ -812,7 +832,7 @@ static void aggr_slice_amsdu(struct aggr_info *p_aggr,
812 /* Add the length of A-MSDU subframe padding bytes - 832 /* Add the length of A-MSDU subframe padding bytes -
813 * Round to nearest word. 833 * Round to nearest word.
814 */ 834 */
815 frame_8023_len = ALIGN(frame_8023_len + 3, 3); 835 frame_8023_len = ALIGN(frame_8023_len, 4);
816 836
817 framep += frame_8023_len; 837 framep += frame_8023_len;
818 amsdu_len -= frame_8023_len; 838 amsdu_len -= frame_8023_len;
@@ -1044,12 +1064,13 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1044 ar->net_stats.rx_packets++; 1064 ar->net_stats.rx_packets++;
1045 ar->net_stats.rx_bytes += packet->act_len; 1065 ar->net_stats.rx_bytes += packet->act_len;
1046 1066
1067 spin_unlock_bh(&ar->lock);
1068
1047 skb_put(skb, packet->act_len + HTC_HDR_LENGTH); 1069 skb_put(skb, packet->act_len + HTC_HDR_LENGTH);
1048 skb_pull(skb, HTC_HDR_LENGTH); 1070 skb_pull(skb, HTC_HDR_LENGTH);
1049 1071
1050 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, skb->data, skb->len); 1072 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ",
1051 1073 skb->data, skb->len);
1052 spin_unlock_bh(&ar->lock);
1053 1074
1054 skb->dev = ar->net_dev; 1075 skb->dev = ar->net_dev;
1055 1076
@@ -1065,9 +1086,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1065 return; 1086 return;
1066 } 1087 }
1067 1088
1068 min_hdr_len = sizeof(struct ethhdr); 1089 min_hdr_len = sizeof(struct ethhdr) + sizeof(struct wmi_data_hdr) +
1069 min_hdr_len += sizeof(struct wmi_data_hdr) + 1090 sizeof(struct ath6kl_llc_snap_hdr);
1070 sizeof(struct ath6kl_llc_snap_hdr);
1071 1091
1072 dhdr = (struct wmi_data_hdr *) skb->data; 1092 dhdr = (struct wmi_data_hdr *) skb->data;
1073 1093
@@ -1163,8 +1183,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1163 seq_no = wmi_data_hdr_get_seqno(dhdr); 1183 seq_no = wmi_data_hdr_get_seqno(dhdr);
1164 meta_type = wmi_data_hdr_get_meta(dhdr); 1184 meta_type = wmi_data_hdr_get_meta(dhdr);
1165 dot11_hdr = wmi_data_hdr_get_dot11(dhdr); 1185 dot11_hdr = wmi_data_hdr_get_dot11(dhdr);
1166 1186 skb_pull(skb, sizeof(struct wmi_data_hdr));
1167 ath6kl_wmi_data_hdr_remove(ar->wmi, skb);
1168 1187
1169 switch (meta_type) { 1188 switch (meta_type) {
1170 case WMI_META_VERSION_1: 1189 case WMI_META_VERSION_1:
@@ -1231,9 +1250,15 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1231 ath6kl_data_tx(skb1, ar->net_dev); 1250 ath6kl_data_tx(skb1, ar->net_dev);
1232 } 1251 }
1233 1252
1234 if (!aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no, 1253 datap = (struct ethhdr *) skb->data;
1235 is_amsdu, skb)) 1254
1236 ath6kl_deliver_frames_to_nw_stack(ar->net_dev, skb); 1255 if (is_unicast_ether_addr(datap->h_dest) &&
1256 aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no,
1257 is_amsdu, skb))
1258 /* aggregation code will handle the skb */
1259 return;
1260
1261 ath6kl_deliver_frames_to_nw_stack(ar->net_dev, skb);
1237} 1262}
1238 1263
1239static void aggr_timeout(unsigned long arg) 1264static void aggr_timeout(unsigned long arg)
@@ -1250,10 +1275,6 @@ static void aggr_timeout(unsigned long arg)
1250 if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress) 1275 if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress)
1251 continue; 1276 continue;
1252 1277
1253 /*
1254 * FIXME: these timeouts happen quite fruently, something
1255 * line once within 60 seconds. Investigate why.
1256 */
1257 stats->num_timeouts++; 1278 stats->num_timeouts++;
1258 ath6kl_dbg(ATH6KL_DBG_AGGR, 1279 ath6kl_dbg(ATH6KL_DBG_AGGR,
1259 "aggr timeout (st %d end %d)\n", 1280 "aggr timeout (st %d end %d)\n",
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index f5aa33dd4c42..a7de23cbd2c7 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -17,6 +17,9 @@
17#include <linux/ip.h> 17#include <linux/ip.h>
18#include "core.h" 18#include "core.h"
19#include "debug.h" 19#include "debug.h"
20#include "testmode.h"
21#include "../regd.h"
22#include "../regd_common.h"
20 23
21static int ath6kl_wmi_sync_point(struct wmi *wmi); 24static int ath6kl_wmi_sync_point(struct wmi *wmi);
22 25
@@ -167,9 +170,11 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
167 if (WARN_ON(skb == NULL)) 170 if (WARN_ON(skb == NULL))
168 return -EINVAL; 171 return -EINVAL;
169 172
170 ret = ath6kl_wmi_meta_add(wmi, skb, &meta_ver, tx_meta_info); 173 if (tx_meta_info) {
171 if (ret) 174 ret = ath6kl_wmi_meta_add(wmi, skb, &meta_ver, tx_meta_info);
172 return ret; 175 if (ret)
176 return ret;
177 }
173 178
174 skb_push(skb, sizeof(struct wmi_data_hdr)); 179 skb_push(skb, sizeof(struct wmi_data_hdr));
175 180
@@ -376,35 +381,6 @@ int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb)
376 return 0; 381 return 0;
377} 382}
378 383
379int ath6kl_wmi_data_hdr_remove(struct wmi *wmi, struct sk_buff *skb)
380{
381 if (WARN_ON(skb == NULL))
382 return -EINVAL;
383
384 skb_pull(skb, sizeof(struct wmi_data_hdr));
385
386 return 0;
387}
388
389static void ath6kl_wmi_convert_bssinfo_hdr2_to_hdr(struct sk_buff *skb,
390 u8 *datap)
391{
392 struct wmi_bss_info_hdr2 bih2;
393 struct wmi_bss_info_hdr *bih;
394
395 memcpy(&bih2, datap, sizeof(struct wmi_bss_info_hdr2));
396
397 skb_push(skb, 4);
398 bih = (struct wmi_bss_info_hdr *) skb->data;
399
400 bih->ch = bih2.ch;
401 bih->frame_type = bih2.frame_type;
402 bih->snr = bih2.snr;
403 bih->rssi = a_cpu_to_sle16(bih2.snr - 95);
404 bih->ie_mask = cpu_to_le32(le16_to_cpu(bih2.ie_mask));
405 memcpy(bih->bssid, bih2.bssid, ETH_ALEN);
406}
407
408static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len) 384static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len)
409{ 385{
410 struct tx_complete_msg_v1 *msg_v1; 386 struct tx_complete_msg_v1 *msg_v1;
@@ -433,6 +409,201 @@ static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len)
433 return 0; 409 return 0;
434} 410}
435 411
412static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap,
413 int len)
414{
415 struct wmi_remain_on_chnl_event *ev;
416 u32 freq;
417 u32 dur;
418 struct ieee80211_channel *chan;
419 struct ath6kl *ar = wmi->parent_dev;
420
421 if (len < sizeof(*ev))
422 return -EINVAL;
423
424 ev = (struct wmi_remain_on_chnl_event *) datap;
425 freq = le32_to_cpu(ev->freq);
426 dur = le32_to_cpu(ev->duration);
427 ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl: freq=%u dur=%u\n",
428 freq, dur);
429 chan = ieee80211_get_channel(ar->wdev->wiphy, freq);
430 if (!chan) {
431 ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl: Unknown channel "
432 "(freq=%u)\n", freq);
433 return -EINVAL;
434 }
435 cfg80211_ready_on_channel(ar->net_dev, 1, chan, NL80211_CHAN_NO_HT,
436 dur, GFP_ATOMIC);
437
438 return 0;
439}
440
441static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi,
442 u8 *datap, int len)
443{
444 struct wmi_cancel_remain_on_chnl_event *ev;
445 u32 freq;
446 u32 dur;
447 struct ieee80211_channel *chan;
448 struct ath6kl *ar = wmi->parent_dev;
449
450 if (len < sizeof(*ev))
451 return -EINVAL;
452
453 ev = (struct wmi_cancel_remain_on_chnl_event *) datap;
454 freq = le32_to_cpu(ev->freq);
455 dur = le32_to_cpu(ev->duration);
456 ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: freq=%u dur=%u "
457 "status=%u\n", freq, dur, ev->status);
458 chan = ieee80211_get_channel(ar->wdev->wiphy, freq);
459 if (!chan) {
460 ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: Unknown "
461 "channel (freq=%u)\n", freq);
462 return -EINVAL;
463 }
464 cfg80211_remain_on_channel_expired(ar->net_dev, 1, chan,
465 NL80211_CHAN_NO_HT, GFP_ATOMIC);
466
467 return 0;
468}
469
470static int ath6kl_wmi_tx_status_event_rx(struct wmi *wmi, u8 *datap, int len)
471{
472 struct wmi_tx_status_event *ev;
473 u32 id;
474 struct ath6kl *ar = wmi->parent_dev;
475
476 if (len < sizeof(*ev))
477 return -EINVAL;
478
479 ev = (struct wmi_tx_status_event *) datap;
480 id = le32_to_cpu(ev->id);
481 ath6kl_dbg(ATH6KL_DBG_WMI, "tx_status: id=%x ack_status=%u\n",
482 id, ev->ack_status);
483 if (wmi->last_mgmt_tx_frame) {
484 cfg80211_mgmt_tx_status(ar->net_dev, id,
485 wmi->last_mgmt_tx_frame,
486 wmi->last_mgmt_tx_frame_len,
487 !!ev->ack_status, GFP_ATOMIC);
488 kfree(wmi->last_mgmt_tx_frame);
489 wmi->last_mgmt_tx_frame = NULL;
490 wmi->last_mgmt_tx_frame_len = 0;
491 }
492
493 return 0;
494}
495
496static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len)
497{
498 struct wmi_p2p_rx_probe_req_event *ev;
499 u32 freq;
500 u16 dlen;
501 struct ath6kl *ar = wmi->parent_dev;
502
503 if (len < sizeof(*ev))
504 return -EINVAL;
505
506 ev = (struct wmi_p2p_rx_probe_req_event *) datap;
507 freq = le32_to_cpu(ev->freq);
508 dlen = le16_to_cpu(ev->len);
509 if (datap + len < ev->data + dlen) {
510 ath6kl_err("invalid wmi_p2p_rx_probe_req_event: "
511 "len=%d dlen=%u\n", len, dlen);
512 return -EINVAL;
513 }
514 ath6kl_dbg(ATH6KL_DBG_WMI, "rx_probe_req: len=%u freq=%u "
515 "probe_req_report=%d\n",
516 dlen, freq, ar->probe_req_report);
517
518 if (ar->probe_req_report || ar->nw_type == AP_NETWORK)
519 cfg80211_rx_mgmt(ar->net_dev, freq, ev->data, dlen, GFP_ATOMIC);
520
521 return 0;
522}
523
524static int ath6kl_wmi_p2p_capabilities_event_rx(u8 *datap, int len)
525{
526 struct wmi_p2p_capabilities_event *ev;
527 u16 dlen;
528
529 if (len < sizeof(*ev))
530 return -EINVAL;
531
532 ev = (struct wmi_p2p_capabilities_event *) datap;
533 dlen = le16_to_cpu(ev->len);
534 ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_capab: len=%u\n", dlen);
535
536 return 0;
537}
538
539static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len)
540{
541 struct wmi_rx_action_event *ev;
542 u32 freq;
543 u16 dlen;
544 struct ath6kl *ar = wmi->parent_dev;
545
546 if (len < sizeof(*ev))
547 return -EINVAL;
548
549 ev = (struct wmi_rx_action_event *) datap;
550 freq = le32_to_cpu(ev->freq);
551 dlen = le16_to_cpu(ev->len);
552 if (datap + len < ev->data + dlen) {
553 ath6kl_err("invalid wmi_rx_action_event: "
554 "len=%d dlen=%u\n", len, dlen);
555 return -EINVAL;
556 }
557 ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq);
558 cfg80211_rx_mgmt(ar->net_dev, freq, ev->data, dlen, GFP_ATOMIC);
559
560 return 0;
561}
562
563static int ath6kl_wmi_p2p_info_event_rx(u8 *datap, int len)
564{
565 struct wmi_p2p_info_event *ev;
566 u32 flags;
567 u16 dlen;
568
569 if (len < sizeof(*ev))
570 return -EINVAL;
571
572 ev = (struct wmi_p2p_info_event *) datap;
573 flags = le32_to_cpu(ev->info_req_flags);
574 dlen = le16_to_cpu(ev->len);
575 ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_info: flags=%x len=%d\n", flags, dlen);
576
577 if (flags & P2P_FLAG_CAPABILITIES_REQ) {
578 struct wmi_p2p_capabilities *cap;
579 if (dlen < sizeof(*cap))
580 return -EINVAL;
581 cap = (struct wmi_p2p_capabilities *) ev->data;
582 ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_info: GO Power Save = %d\n",
583 cap->go_power_save);
584 }
585
586 if (flags & P2P_FLAG_MACADDR_REQ) {
587 struct wmi_p2p_macaddr *mac;
588 if (dlen < sizeof(*mac))
589 return -EINVAL;
590 mac = (struct wmi_p2p_macaddr *) ev->data;
591 ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_info: MAC Address = %pM\n",
592 mac->mac_addr);
593 }
594
595 if (flags & P2P_FLAG_HMODEL_REQ) {
596 struct wmi_p2p_hmodel *mod;
597 if (dlen < sizeof(*mod))
598 return -EINVAL;
599 mod = (struct wmi_p2p_hmodel *) ev->data;
600 ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_info: P2P Model = %d (%s)\n",
601 mod->p2p_model,
602 mod->p2p_model ? "host" : "firmware");
603 }
604 return 0;
605}
606
436static inline struct sk_buff *ath6kl_wmi_get_new_buf(u32 size) 607static inline struct sk_buff *ath6kl_wmi_get_new_buf(u32 size)
437{ 608{
438 struct sk_buff *skb; 609 struct sk_buff *skb;
@@ -478,18 +649,84 @@ static int ath6kl_wmi_ready_event_rx(struct wmi *wmi, u8 *datap, int len)
478 return 0; 649 return 0;
479} 650}
480 651
652/*
653 * Mechanism to modify the roaming behavior in the firmware. The lower rssi
654 * at which the station has to roam can be passed with
655 * WMI_SET_LRSSI_SCAN_PARAMS. Subtract 96 from RSSI to get the signal level
656 * in dBm.
657 */
658int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi)
659{
660 struct sk_buff *skb;
661 struct roam_ctrl_cmd *cmd;
662
663 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
664 if (!skb)
665 return -ENOMEM;
666
667 cmd = (struct roam_ctrl_cmd *) skb->data;
668
669 cmd->info.params.lrssi_scan_period = cpu_to_le16(DEF_LRSSI_SCAN_PERIOD);
670 cmd->info.params.lrssi_scan_threshold = a_cpu_to_sle16(lrssi +
671 DEF_SCAN_FOR_ROAM_INTVL);
672 cmd->info.params.lrssi_roam_threshold = a_cpu_to_sle16(lrssi);
673 cmd->info.params.roam_rssi_floor = DEF_LRSSI_ROAM_FLOOR;
674 cmd->roam_ctrl = WMI_SET_LRSSI_SCAN_PARAMS;
675
676 ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_ROAM_CTRL_CMDID, NO_SYNC_WMIFLAG);
677
678 return 0;
679}
680
481static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len) 681static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len)
482{ 682{
483 struct wmi_connect_event *ev; 683 struct wmi_connect_event *ev;
484 u8 *pie, *peie; 684 u8 *pie, *peie;
685 struct ath6kl *ar = wmi->parent_dev;
485 686
486 if (len < sizeof(struct wmi_connect_event)) 687 if (len < sizeof(struct wmi_connect_event))
487 return -EINVAL; 688 return -EINVAL;
488 689
489 ev = (struct wmi_connect_event *) datap; 690 ev = (struct wmi_connect_event *) datap;
490 691
491 ath6kl_dbg(ATH6KL_DBG_WMI, "%s: freq %d bssid %pM\n", 692 if (ar->nw_type == AP_NETWORK) {
492 __func__, ev->ch, ev->bssid); 693 /* AP mode start/STA connected event */
694 struct net_device *dev = ar->net_dev;
695 if (memcmp(dev->dev_addr, ev->u.ap_bss.bssid, ETH_ALEN) == 0) {
696 ath6kl_dbg(ATH6KL_DBG_WMI, "%s: freq %d bssid %pM "
697 "(AP started)\n",
698 __func__, le16_to_cpu(ev->u.ap_bss.ch),
699 ev->u.ap_bss.bssid);
700 ath6kl_connect_ap_mode_bss(
701 ar, le16_to_cpu(ev->u.ap_bss.ch));
702 } else {
703 ath6kl_dbg(ATH6KL_DBG_WMI, "%s: aid %u mac_addr %pM "
704 "auth=%u keymgmt=%u cipher=%u apsd_info=%u "
705 "(STA connected)\n",
706 __func__, ev->u.ap_sta.aid,
707 ev->u.ap_sta.mac_addr,
708 ev->u.ap_sta.auth,
709 ev->u.ap_sta.keymgmt,
710 le16_to_cpu(ev->u.ap_sta.cipher),
711 ev->u.ap_sta.apsd_info);
712 ath6kl_connect_ap_mode_sta(
713 ar, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr,
714 ev->u.ap_sta.keymgmt,
715 le16_to_cpu(ev->u.ap_sta.cipher),
716 ev->u.ap_sta.auth, ev->assoc_req_len,
717 ev->assoc_info + ev->beacon_ie_len);
718 }
719 return 0;
720 }
721
722 /* STA/IBSS mode connection event */
723
724 ath6kl_dbg(ATH6KL_DBG_WMI,
725 "wmi event connect freq %d bssid %pM listen_intvl %d beacon_intvl %d type %d\n",
726 le16_to_cpu(ev->u.sta.ch), ev->u.sta.bssid,
727 le16_to_cpu(ev->u.sta.listen_intvl),
728 le16_to_cpu(ev->u.sta.beacon_intvl),
729 le32_to_cpu(ev->u.sta.nw_type));
493 730
494 /* Start of assoc rsp IEs */ 731 /* Start of assoc rsp IEs */
495 pie = ev->assoc_info + ev->beacon_ie_len + 732 pie = ev->assoc_info + ev->beacon_ie_len +
@@ -518,16 +755,92 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len)
518 pie += pie[1] + 2; 755 pie += pie[1] + 2;
519 } 756 }
520 757
521 ath6kl_connect_event(wmi->parent_dev, le16_to_cpu(ev->ch), ev->bssid, 758 ath6kl_connect_event(wmi->parent_dev, le16_to_cpu(ev->u.sta.ch),
522 le16_to_cpu(ev->listen_intvl), 759 ev->u.sta.bssid,
523 le16_to_cpu(ev->beacon_intvl), 760 le16_to_cpu(ev->u.sta.listen_intvl),
524 le32_to_cpu(ev->nw_type), 761 le16_to_cpu(ev->u.sta.beacon_intvl),
762 le32_to_cpu(ev->u.sta.nw_type),
525 ev->beacon_ie_len, ev->assoc_req_len, 763 ev->beacon_ie_len, ev->assoc_req_len,
526 ev->assoc_resp_len, ev->assoc_info); 764 ev->assoc_resp_len, ev->assoc_info);
527 765
528 return 0; 766 return 0;
529} 767}
530 768
769static struct country_code_to_enum_rd *
770ath6kl_regd_find_country(u16 countryCode)
771{
772 int i;
773
774 for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
775 if (allCountries[i].countryCode == countryCode)
776 return &allCountries[i];
777 }
778
779 return NULL;
780}
781
782static struct reg_dmn_pair_mapping *
783ath6kl_get_regpair(u16 regdmn)
784{
785 int i;
786
787 if (regdmn == NO_ENUMRD)
788 return NULL;
789
790 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
791 if (regDomainPairs[i].regDmnEnum == regdmn)
792 return &regDomainPairs[i];
793 }
794
795 return NULL;
796}
797
798static struct country_code_to_enum_rd *
799ath6kl_regd_find_country_by_rd(u16 regdmn)
800{
801 int i;
802
803 for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
804 if (allCountries[i].regDmnEnum == regdmn)
805 return &allCountries[i];
806 }
807
808 return NULL;
809}
810
811static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
812{
813
814 struct ath6kl_wmi_regdomain *ev;
815 struct country_code_to_enum_rd *country = NULL;
816 struct reg_dmn_pair_mapping *regpair = NULL;
817 char alpha2[2];
818 u32 reg_code;
819
820 ev = (struct ath6kl_wmi_regdomain *) datap;
821 reg_code = le32_to_cpu(ev->reg_code);
822
823 if ((reg_code >> ATH6KL_COUNTRY_RD_SHIFT) & COUNTRY_ERD_FLAG)
824 country = ath6kl_regd_find_country((u16) reg_code);
825 else if (!(((u16) reg_code & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)) {
826
827 regpair = ath6kl_get_regpair((u16) reg_code);
828 country = ath6kl_regd_find_country_by_rd((u16) reg_code);
829 ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n",
830 regpair->regDmnEnum);
831 }
832
833 if (country) {
834 alpha2[0] = country->isoName[0];
835 alpha2[1] = country->isoName[1];
836
837 regulatory_hint(wmi->parent_dev->wdev->wiphy, alpha2);
838
839 ath6kl_dbg(ATH6KL_DBG_WMI, "Country alpha2 being used: %c%c\n",
840 alpha2[0], alpha2[1]);
841 }
842}
843
531static int ath6kl_wmi_disconnect_event_rx(struct wmi *wmi, u8 *datap, int len) 844static int ath6kl_wmi_disconnect_event_rx(struct wmi *wmi, u8 *datap, int len)
532{ 845{
533 struct wmi_disconnect_event *ev; 846 struct wmi_disconnect_event *ev;
@@ -538,6 +851,11 @@ static int ath6kl_wmi_disconnect_event_rx(struct wmi *wmi, u8 *datap, int len)
538 851
539 ev = (struct wmi_disconnect_event *) datap; 852 ev = (struct wmi_disconnect_event *) datap;
540 853
854 ath6kl_dbg(ATH6KL_DBG_WMI,
855 "wmi event disconnect proto_reason %d bssid %pM wmi_reason %d assoc_resp_len %d\n",
856 le16_to_cpu(ev->proto_reason_status), ev->bssid,
857 ev->disconn_reason, ev->assoc_resp_len);
858
541 wmi->is_wmm_enabled = false; 859 wmi->is_wmm_enabled = false;
542 wmi->pair_crypto_type = NONE_CRYPT; 860 wmi->pair_crypto_type = NONE_CRYPT;
543 wmi->grp_crypto_type = NONE_CRYPT; 861 wmi->grp_crypto_type = NONE_CRYPT;
@@ -582,315 +900,92 @@ static int ath6kl_wmi_tkip_micerr_event_rx(struct wmi *wmi, u8 *datap, int len)
582 return 0; 900 return 0;
583} 901}
584 902
585static int ath6kl_wlan_parse_beacon(u8 *buf, int frame_len,
586 struct ath6kl_common_ie *cie)
587{
588 u8 *frm, *efrm;
589 u8 elemid_ssid = false;
590
591 frm = buf;
592 efrm = (u8 *) (frm + frame_len);
593
594 /*
595 * beacon/probe response frame format
596 * [8] time stamp
597 * [2] beacon interval
598 * [2] capability information
599 * [tlv] ssid
600 * [tlv] supported rates
601 * [tlv] country information
602 * [tlv] parameter set (FH/DS)
603 * [tlv] erp information
604 * [tlv] extended supported rates
605 * [tlv] WMM
606 * [tlv] WPA or RSN
607 * [tlv] Atheros Advanced Capabilities
608 */
609 if ((efrm - frm) < 12)
610 return -EINVAL;
611
612 memset(cie, 0, sizeof(*cie));
613
614 cie->ie_tstamp = frm;
615 frm += 8;
616 cie->ie_beaconInt = *(u16 *) frm;
617 frm += 2;
618 cie->ie_capInfo = *(u16 *) frm;
619 frm += 2;
620 cie->ie_chan = 0;
621
622 while (frm < efrm) {
623 switch (*frm) {
624 case WLAN_EID_SSID:
625 if (!elemid_ssid) {
626 cie->ie_ssid = frm;
627 elemid_ssid = true;
628 }
629 break;
630 case WLAN_EID_SUPP_RATES:
631 cie->ie_rates = frm;
632 break;
633 case WLAN_EID_COUNTRY:
634 cie->ie_country = frm;
635 break;
636 case WLAN_EID_FH_PARAMS:
637 break;
638 case WLAN_EID_DS_PARAMS:
639 cie->ie_chan = frm[2];
640 break;
641 case WLAN_EID_TIM:
642 cie->ie_tim = frm;
643 break;
644 case WLAN_EID_IBSS_PARAMS:
645 break;
646 case WLAN_EID_EXT_SUPP_RATES:
647 cie->ie_xrates = frm;
648 break;
649 case WLAN_EID_ERP_INFO:
650 if (frm[1] != 1)
651 return -EINVAL;
652
653 cie->ie_erp = frm[2];
654 break;
655 case WLAN_EID_RSN:
656 cie->ie_rsn = frm;
657 break;
658 case WLAN_EID_HT_CAPABILITY:
659 cie->ie_htcap = frm;
660 break;
661 case WLAN_EID_HT_INFORMATION:
662 cie->ie_htop = frm;
663 break;
664 case WLAN_EID_VENDOR_SPECIFIC:
665 if (frm[1] > 3 && frm[2] == 0x00 && frm[3] == 0x50 &&
666 frm[4] == 0xf2) {
667 /* OUT Type (00:50:F2) */
668
669 if (frm[5] == WPA_OUI_TYPE) {
670 /* WPA OUT */
671 cie->ie_wpa = frm;
672 } else if (frm[5] == WMM_OUI_TYPE) {
673 /* WMM OUT */
674 cie->ie_wmm = frm;
675 } else if (frm[5] == WSC_OUT_TYPE) {
676 /* WSC OUT */
677 cie->ie_wsc = frm;
678 }
679
680 } else if (frm[1] > 3 && frm[2] == 0x00
681 && frm[3] == 0x03 && frm[4] == 0x7f
682 && frm[5] == ATH_OUI_TYPE) {
683 /* Atheros OUI (00:03:7f) */
684 cie->ie_ath = frm;
685 }
686 break;
687 default:
688 break;
689 }
690 frm += frm[1] + 2;
691 }
692
693 if ((cie->ie_rates == NULL)
694 || (cie->ie_rates[1] > ATH6KL_RATE_MAXSIZE))
695 return -EINVAL;
696
697 if ((cie->ie_ssid == NULL)
698 || (cie->ie_ssid[1] > IEEE80211_MAX_SSID_LEN))
699 return -EINVAL;
700
701 return 0;
702}
703
704static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len) 903static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
705{ 904{
706 struct bss *bss = NULL; 905 struct wmi_bss_info_hdr2 *bih;
707 struct wmi_bss_info_hdr *bih; 906 u8 *buf;
708 u8 cached_ssid_len = 0; 907 struct ieee80211_channel *channel;
709 u8 cached_ssid[IEEE80211_MAX_SSID_LEN] = { 0 }; 908 struct ath6kl *ar = wmi->parent_dev;
710 u8 beacon_ssid_len = 0; 909 struct ieee80211_mgmt *mgmt;
711 u8 *buf, *ie_ssid; 910 struct cfg80211_bss *bss;
712 u8 *ni_buf;
713 int buf_len;
714
715 int ret;
716 911
717 if (len <= sizeof(struct wmi_bss_info_hdr)) 912 if (len <= sizeof(struct wmi_bss_info_hdr2))
718 return -EINVAL; 913 return -EINVAL;
719 914
720 bih = (struct wmi_bss_info_hdr *) datap; 915 bih = (struct wmi_bss_info_hdr2 *) datap;
721 bss = wlan_find_node(&wmi->parent_dev->scan_table, bih->bssid); 916 buf = datap + sizeof(struct wmi_bss_info_hdr2);
722 917 len -= sizeof(struct wmi_bss_info_hdr2);
723 if (a_sle16_to_cpu(bih->rssi) > 0) {
724 if (bss == NULL)
725 return 0;
726 else
727 bih->rssi = a_cpu_to_sle16(bss->ni_rssi);
728 }
729
730 buf = datap + sizeof(struct wmi_bss_info_hdr);
731 len -= sizeof(struct wmi_bss_info_hdr);
732 918
733 ath6kl_dbg(ATH6KL_DBG_WMI, 919 ath6kl_dbg(ATH6KL_DBG_WMI,
734 "bss info evt - ch %u, rssi %02x, bssid \"%pM\"\n", 920 "bss info evt - ch %u, snr %d, rssi %d, bssid \"%pM\" "
735 bih->ch, a_sle16_to_cpu(bih->rssi), bih->bssid); 921 "frame_type=%d\n",
736 922 bih->ch, bih->snr, bih->snr - 95, bih->bssid,
737 if (bss != NULL) { 923 bih->frame_type);
738 /* 924
739 * Free up the node. We are about to allocate a new node. 925 if (bih->frame_type != BEACON_FTYPE &&
740 * In case of hidden AP, beacon will not have ssid, 926 bih->frame_type != PROBERESP_FTYPE)
741 * but a directed probe response will have it, 927 return 0; /* Only update BSS table for now */
742 * so cache the probe-resp-ssid if already present. 928
743 */ 929 if (bih->frame_type == BEACON_FTYPE &&
744 if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE)) { 930 test_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag)) {
745 ie_ssid = bss->ni_cie.ie_ssid; 931 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
746 if (ie_ssid && (ie_ssid[1] <= IEEE80211_MAX_SSID_LEN) && 932 ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
747 (ie_ssid[2] != 0)) {
748 cached_ssid_len = ie_ssid[1];
749 memcpy(cached_ssid, ie_ssid + 2,
750 cached_ssid_len);
751 }
752 }
753
754 /*
755 * Use the current average rssi of associated AP base on
756 * assumption
757 * 1. Most os with GUI will update RSSI by
758 * ath6kl_wmi_get_stats_cmd() periodically.
759 * 2. ath6kl_wmi_get_stats_cmd(..) will be called when calling
760 * ath6kl_wmi_startscan_cmd(...)
761 * The average value of RSSI give end-user better feeling for
762 * instance value of scan result. It also sync up RSSI info
763 * in GUI between scan result and RSSI signal icon.
764 */
765 if (memcmp(wmi->parent_dev->bssid, bih->bssid, ETH_ALEN) == 0) {
766 bih->rssi = a_cpu_to_sle16(bss->ni_rssi);
767 bih->snr = bss->ni_snr;
768 }
769
770 wlan_node_reclaim(&wmi->parent_dev->scan_table, bss);
771 } 933 }
772 934
773 /* 935 channel = ieee80211_get_channel(ar->wdev->wiphy, le16_to_cpu(bih->ch));
774 * beacon/probe response frame format 936 if (channel == NULL)
775 * [8] time stamp
776 * [2] beacon interval
777 * [2] capability information
778 * [tlv] ssid
779 */
780 beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
781
782 /*
783 * If ssid is cached for this hidden AP, then change
784 * buffer len accordingly.
785 */
786 if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE) &&
787 (cached_ssid_len != 0) &&
788 (beacon_ssid_len == 0 || (cached_ssid_len > beacon_ssid_len &&
789 buf[SSID_IE_LEN_INDEX + 1] == 0))) {
790
791 len += (cached_ssid_len - beacon_ssid_len);
792 }
793
794 bss = wlan_node_alloc(len);
795 if (!bss)
796 return -ENOMEM;
797
798 bss->ni_snr = bih->snr;
799 bss->ni_rssi = a_sle16_to_cpu(bih->rssi);
800
801 if (WARN_ON(!bss->ni_buf))
802 return -EINVAL; 937 return -EINVAL;
803 938
804 /* 939 if (len < 8 + 2 + 2)
805 * In case of hidden AP, beacon will not have ssid,
806 * but a directed probe response will have it,
807 * so place the cached-ssid(probe-resp) in the bss info.
808 */
809 if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE) &&
810 (cached_ssid_len != 0) &&
811 (beacon_ssid_len == 0 || (beacon_ssid_len &&
812 buf[SSID_IE_LEN_INDEX + 1] == 0))) {
813 ni_buf = bss->ni_buf;
814 buf_len = len;
815
816 /*
817 * Copy the first 14 bytes:
818 * time-stamp(8), beacon-interval(2),
819 * cap-info(2), ssid-id(1), ssid-len(1).
820 */
821 memcpy(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
822
823 ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
824 ni_buf += (SSID_IE_LEN_INDEX + 1);
825
826 buf += (SSID_IE_LEN_INDEX + 1);
827 buf_len -= (SSID_IE_LEN_INDEX + 1);
828
829 memcpy(ni_buf, cached_ssid, cached_ssid_len);
830 ni_buf += cached_ssid_len;
831
832 buf += beacon_ssid_len;
833 buf_len -= beacon_ssid_len;
834
835 if (cached_ssid_len > beacon_ssid_len)
836 buf_len -= (cached_ssid_len - beacon_ssid_len);
837
838 memcpy(ni_buf, buf, buf_len);
839 } else
840 memcpy(bss->ni_buf, buf, len);
841
842 bss->ni_framelen = len;
843
844 ret = ath6kl_wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie);
845 if (ret) {
846 wlan_node_free(bss);
847 return -EINVAL; 940 return -EINVAL;
941
942 if (bih->frame_type == BEACON_FTYPE && test_bit(CONNECTED, &ar->flag) &&
943 memcmp(bih->bssid, ar->bssid, ETH_ALEN) == 0) {
944 const u8 *tim;
945 tim = cfg80211_find_ie(WLAN_EID_TIM, buf + 8 + 2 + 2,
946 len - 8 - 2 - 2);
947 if (tim && tim[1] >= 2) {
948 ar->assoc_bss_dtim_period = tim[3];
949 set_bit(DTIM_PERIOD_AVAIL, &ar->flag);
950 }
848 } 951 }
849 952
850 /* 953 /*
851 * Update the frequency in ie_chan, overwriting of channel number 954 * In theory, use of cfg80211_inform_bss() would be more natural here
852 * which is done in ath6kl_wlan_parse_beacon 955 * since we do not have the full frame. However, at least for now,
956 * cfg80211 can only distinguish Beacon and Probe Response frames from
957 * each other when using cfg80211_inform_bss_frame(), so let's build a
958 * fake IEEE 802.11 header to be able to take benefit of this.
853 */ 959 */
854 bss->ni_cie.ie_chan = le16_to_cpu(bih->ch); 960 mgmt = kmalloc(24 + len, GFP_ATOMIC);
855 wlan_setup_node(&wmi->parent_dev->scan_table, bss, bih->bssid); 961 if (mgmt == NULL)
856
857 return 0;
858}
859
860static int ath6kl_wmi_opt_frame_event_rx(struct wmi *wmi, u8 *datap, int len)
861{
862 struct bss *bss;
863 struct wmi_opt_rx_info_hdr *bih;
864 u8 *buf;
865
866 if (len <= sizeof(struct wmi_opt_rx_info_hdr))
867 return -EINVAL; 962 return -EINVAL;
868 963
869 bih = (struct wmi_opt_rx_info_hdr *) datap; 964 if (bih->frame_type == BEACON_FTYPE) {
870 buf = datap + sizeof(struct wmi_opt_rx_info_hdr); 965 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
871 len -= sizeof(struct wmi_opt_rx_info_hdr); 966 IEEE80211_STYPE_BEACON);
872 967 memset(mgmt->da, 0xff, ETH_ALEN);
873 ath6kl_dbg(ATH6KL_DBG_WMI, "opt frame event %2.2x:%2.2x\n", 968 } else {
874 bih->bssid[4], bih->bssid[5]); 969 struct net_device *dev = ar->net_dev;
875 970
876 bss = wlan_find_node(&wmi->parent_dev->scan_table, bih->bssid); 971 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
877 if (bss != NULL) { 972 IEEE80211_STYPE_PROBE_RESP);
878 /* Free up the node. We are about to allocate a new node. */ 973 memcpy(mgmt->da, dev->dev_addr, ETH_ALEN);
879 wlan_node_reclaim(&wmi->parent_dev->scan_table, bss);
880 } 974 }
881 975 mgmt->duration = cpu_to_le16(0);
882 bss = wlan_node_alloc(len); 976 memcpy(mgmt->sa, bih->bssid, ETH_ALEN);
883 if (!bss) 977 memcpy(mgmt->bssid, bih->bssid, ETH_ALEN);
978 mgmt->seq_ctrl = cpu_to_le16(0);
979
980 memcpy(&mgmt->u.beacon, buf, len);
981
982 bss = cfg80211_inform_bss_frame(ar->wdev->wiphy, channel, mgmt,
983 24 + len, (bih->snr - 95) * 100,
984 GFP_ATOMIC);
985 kfree(mgmt);
986 if (bss == NULL)
884 return -ENOMEM; 987 return -ENOMEM;
885 988 cfg80211_put_bss(bss);
886 bss->ni_snr = bih->snr;
887 bss->ni_cie.ie_chan = le16_to_cpu(bih->ch);
888
889 if (WARN_ON(!bss->ni_buf))
890 return -EINVAL;
891
892 memcpy(bss->ni_buf, buf, len);
893 wlan_setup_node(&wmi->parent_dev->scan_table, bss, bih->bssid);
894 989
895 return 0; 990 return 0;
896} 991}
@@ -949,6 +1044,13 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len)
949 return 0; 1044 return 0;
950} 1045}
951 1046
1047static int ath6kl_wmi_tcmd_test_report_rx(struct wmi *wmi, u8 *datap, int len)
1048{
1049 ath6kl_tm_rx_report_event(wmi->parent_dev, datap, len);
1050
1051 return 0;
1052}
1053
952static int ath6kl_wmi_ratemask_reply_rx(struct wmi *wmi, u8 *datap, int len) 1054static int ath6kl_wmi_ratemask_reply_rx(struct wmi *wmi, u8 *datap, int len)
953{ 1055{
954 if (len < sizeof(struct wmi_fix_rates_reply)) 1056 if (len < sizeof(struct wmi_fix_rates_reply))
@@ -998,15 +1100,41 @@ static int ath6kl_wmi_scan_complete_rx(struct wmi *wmi, u8 *datap, int len)
998 1100
999 ev = (struct wmi_scan_complete_event *) datap; 1101 ev = (struct wmi_scan_complete_event *) datap;
1000 1102
1001 if (a_sle32_to_cpu(ev->status) == 0)
1002 wlan_refresh_inactive_nodes(wmi->parent_dev);
1003
1004 ath6kl_scan_complete_evt(wmi->parent_dev, a_sle32_to_cpu(ev->status)); 1103 ath6kl_scan_complete_evt(wmi->parent_dev, a_sle32_to_cpu(ev->status));
1005 wmi->is_probe_ssid = false; 1104 wmi->is_probe_ssid = false;
1006 1105
1007 return 0; 1106 return 0;
1008} 1107}
1009 1108
1109static int ath6kl_wmi_neighbor_report_event_rx(struct wmi *wmi, u8 *datap,
1110 int len)
1111{
1112 struct wmi_neighbor_report_event *ev;
1113 u8 i;
1114
1115 if (len < sizeof(*ev))
1116 return -EINVAL;
1117 ev = (struct wmi_neighbor_report_event *) datap;
1118 if (sizeof(*ev) + ev->num_neighbors * sizeof(struct wmi_neighbor_info)
1119 > len) {
1120 ath6kl_dbg(ATH6KL_DBG_WMI, "truncated neighbor event "
1121 "(num=%d len=%d)\n", ev->num_neighbors, len);
1122 return -EINVAL;
1123 }
1124 for (i = 0; i < ev->num_neighbors; i++) {
1125 ath6kl_dbg(ATH6KL_DBG_WMI, "neighbor %d/%d - %pM 0x%x\n",
1126 i + 1, ev->num_neighbors, ev->neighbor[i].bssid,
1127 ev->neighbor[i].bss_flags);
1128 cfg80211_pmksa_candidate_notify(wmi->parent_dev->net_dev, i,
1129 ev->neighbor[i].bssid,
1130 !!(ev->neighbor[i].bss_flags &
1131 WMI_PREAUTH_CAPABLE_BSS),
1132 GFP_ATOMIC);
1133 }
1134
1135 return 0;
1136}
1137
1010/* 1138/*
1011 * Target is reporting a programming error. This is for 1139 * Target is reporting a programming error. This is for
1012 * developer aid only. Target only checks a few common violations 1140 * developer aid only. Target only checks a few common violations
@@ -1410,6 +1538,11 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,
1410 if (WARN_ON(skb == NULL)) 1538 if (WARN_ON(skb == NULL))
1411 return -EINVAL; 1539 return -EINVAL;
1412 1540
1541 ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n",
1542 cmd_id, skb->len, sync_flag);
1543 ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi tx ",
1544 skb->data, skb->len);
1545
1413 if (sync_flag >= END_WMIFLAG) { 1546 if (sync_flag >= END_WMIFLAG) {
1414 dev_kfree_skb(skb); 1547 dev_kfree_skb(skb);
1415 return -EINVAL; 1548 return -EINVAL;
@@ -1468,6 +1601,13 @@ int ath6kl_wmi_connect_cmd(struct wmi *wmi, enum network_type nw_type,
1468 struct wmi_connect_cmd *cc; 1601 struct wmi_connect_cmd *cc;
1469 int ret; 1602 int ret;
1470 1603
1604 ath6kl_dbg(ATH6KL_DBG_WMI,
1605 "wmi connect bssid %pM freq %d flags 0x%x ssid_len %d "
1606 "type %d dot11_auth %d auth %d pairwise %d group %d\n",
1607 bssid, channel, ctrl_flags, ssid_len, nw_type,
1608 dot11_auth_mode, auth_mode, pairwise_crypto, group_crypto);
1609 ath6kl_dbg_dump(ATH6KL_DBG_WMI, NULL, "ssid ", ssid, ssid_len);
1610
1471 wmi->traffic_class = 100; 1611 wmi->traffic_class = 100;
1472 1612
1473 if ((pairwise_crypto == NONE_CRYPT) && (group_crypto != NONE_CRYPT)) 1613 if ((pairwise_crypto == NONE_CRYPT) && (group_crypto != NONE_CRYPT))
@@ -1513,6 +1653,9 @@ int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 *bssid, u16 channel)
1513 struct wmi_reconnect_cmd *cc; 1653 struct wmi_reconnect_cmd *cc;
1514 int ret; 1654 int ret;
1515 1655
1656 ath6kl_dbg(ATH6KL_DBG_WMI, "wmi reconnect bssid %pM freq %d\n",
1657 bssid, channel);
1658
1516 wmi->traffic_class = 100; 1659 wmi->traffic_class = 100;
1517 1660
1518 skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_reconnect_cmd)); 1661 skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_reconnect_cmd));
@@ -1535,6 +1678,8 @@ int ath6kl_wmi_disconnect_cmd(struct wmi *wmi)
1535{ 1678{
1536 int ret; 1679 int ret;
1537 1680
1681 ath6kl_dbg(ATH6KL_DBG_WMI, "wmi disconnect\n");
1682
1538 wmi->traffic_class = 100; 1683 wmi->traffic_class = 100;
1539 1684
1540 /* Disconnect command does not need to do a SYNC before. */ 1685 /* Disconnect command does not need to do a SYNC before. */
@@ -1551,7 +1696,7 @@ int ath6kl_wmi_startscan_cmd(struct wmi *wmi, enum wmi_scan_type scan_type,
1551 struct sk_buff *skb; 1696 struct sk_buff *skb;
1552 struct wmi_start_scan_cmd *sc; 1697 struct wmi_start_scan_cmd *sc;
1553 s8 size; 1698 s8 size;
1554 int ret; 1699 int i, ret;
1555 1700
1556 size = sizeof(struct wmi_start_scan_cmd); 1701 size = sizeof(struct wmi_start_scan_cmd);
1557 1702
@@ -1576,8 +1721,8 @@ int ath6kl_wmi_startscan_cmd(struct wmi *wmi, enum wmi_scan_type scan_type,
1576 sc->force_scan_intvl = cpu_to_le32(force_scan_interval); 1721 sc->force_scan_intvl = cpu_to_le32(force_scan_interval);
1577 sc->num_ch = num_chan; 1722 sc->num_ch = num_chan;
1578 1723
1579 if (num_chan) 1724 for (i = 0; i < num_chan; i++)
1580 memcpy(sc->ch_list, ch_list, num_chan * sizeof(u16)); 1725 sc->ch_list[i] = cpu_to_le16(ch_list[i]);
1581 1726
1582 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_START_SCAN_CMDID, 1727 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_START_SCAN_CMDID,
1583 NO_SYNC_WMIFLAG); 1728 NO_SYNC_WMIFLAG);
@@ -1770,6 +1915,10 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,
1770 struct wmi_add_cipher_key_cmd *cmd; 1915 struct wmi_add_cipher_key_cmd *cmd;
1771 int ret; 1916 int ret;
1772 1917
1918 ath6kl_dbg(ATH6KL_DBG_WMI, "addkey cmd: key_index=%u key_type=%d "
1919 "key_usage=%d key_len=%d key_op_ctrl=%d\n",
1920 key_index, key_type, key_usage, key_len, key_op_ctrl);
1921
1773 if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) || 1922 if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) ||
1774 (key_material == NULL)) 1923 (key_material == NULL))
1775 return -EINVAL; 1924 return -EINVAL;
@@ -2211,6 +2360,25 @@ int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source)
2211 return ret; 2360 return ret;
2212} 2361}
2213 2362
2363int ath6kl_wmi_config_debug_module_cmd(struct wmi *wmi, u32 valid, u32 config)
2364{
2365 struct ath6kl_wmix_dbglog_cfg_module_cmd *cmd;
2366 struct sk_buff *skb;
2367 int ret;
2368
2369 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
2370 if (!skb)
2371 return -ENOMEM;
2372
2373 cmd = (struct ath6kl_wmix_dbglog_cfg_module_cmd *) skb->data;
2374 cmd->valid = cpu_to_le32(valid);
2375 cmd->config = cpu_to_le32(config);
2376
2377 ret = ath6kl_wmi_cmd_send_xtnd(wmi, skb, WMIX_DBGLOG_CFG_MODULE_CMDID,
2378 NO_SYNC_WMIFLAG);
2379 return ret;
2380}
2381
2214int ath6kl_wmi_get_stats_cmd(struct wmi *wmi) 2382int ath6kl_wmi_get_stats_cmd(struct wmi *wmi)
2215{ 2383{
2216 return ath6kl_wmi_simple_cmd(wmi, WMI_GET_STATISTICS_CMDID); 2384 return ath6kl_wmi_simple_cmd(wmi, WMI_GET_STATISTICS_CMDID);
@@ -2316,49 +2484,29 @@ int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl)
2316 return ret; 2484 return ret;
2317} 2485}
2318 2486
2319s32 ath6kl_wmi_get_rate(s8 rate_index) 2487int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len)
2320{ 2488{
2321 if (rate_index == RATE_AUTO) 2489 struct sk_buff *skb;
2322 return 0; 2490 int ret;
2323 2491
2324 return wmi_rate_tbl[(u32) rate_index][0]; 2492 skb = ath6kl_wmi_get_new_buf(len);
2325} 2493 if (!skb)
2494 return -ENOMEM;
2326 2495
2327void ath6kl_wmi_node_return(struct wmi *wmi, struct bss *bss) 2496 memcpy(skb->data, buf, len);
2328{
2329 if (bss)
2330 wlan_node_return(&wmi->parent_dev->scan_table, bss);
2331}
2332 2497
2333struct bss *ath6kl_wmi_find_ssid_node(struct wmi *wmi, u8 * ssid, 2498 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_TEST_CMDID, NO_SYNC_WMIFLAG);
2334 u32 ssid_len, bool is_wpa2,
2335 bool match_ssid)
2336{
2337 struct bss *node = NULL;
2338 2499
2339 node = wlan_find_ssid_node(&wmi->parent_dev->scan_table, ssid, 2500 return ret;
2340 ssid_len, is_wpa2, match_ssid);
2341 return node;
2342} 2501}
2343 2502
2344struct bss *ath6kl_wmi_find_node(struct wmi *wmi, const u8 * mac_addr)
2345{
2346 struct bss *ni = NULL;
2347
2348 ni = wlan_find_node(&wmi->parent_dev->scan_table, mac_addr);
2349
2350 return ni;
2351}
2352 2503
2353void ath6kl_wmi_node_free(struct wmi *wmi, const u8 * mac_addr) 2504s32 ath6kl_wmi_get_rate(s8 rate_index)
2354{ 2505{
2355 struct bss *ni = NULL; 2506 if (rate_index == RATE_AUTO)
2356 2507 return 0;
2357 ni = wlan_find_node(&wmi->parent_dev->scan_table, mac_addr);
2358 if (ni != NULL)
2359 wlan_node_reclaim(&wmi->parent_dev->scan_table, ni);
2360 2508
2361 return; 2509 return wmi_rate_tbl[(u32) rate_index][0];
2362} 2510}
2363 2511
2364static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap, 2512static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
@@ -2400,6 +2548,47 @@ static int ath6kl_wmi_delba_req_event_rx(struct wmi *wmi, u8 *datap, int len)
2400} 2548}
2401 2549
2402/* AP mode functions */ 2550/* AP mode functions */
2551
2552int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, struct wmi_connect_cmd *p)
2553{
2554 struct sk_buff *skb;
2555 struct wmi_connect_cmd *cm;
2556 int res;
2557
2558 skb = ath6kl_wmi_get_new_buf(sizeof(*cm));
2559 if (!skb)
2560 return -ENOMEM;
2561
2562 cm = (struct wmi_connect_cmd *) skb->data;
2563 memcpy(cm, p, sizeof(*cm));
2564
2565 res = ath6kl_wmi_cmd_send(wmip, skb, WMI_AP_CONFIG_COMMIT_CMDID,
2566 NO_SYNC_WMIFLAG);
2567 ath6kl_dbg(ATH6KL_DBG_WMI, "%s: nw_type=%u auth_mode=%u ch=%u "
2568 "ctrl_flags=0x%x-> res=%d\n",
2569 __func__, p->nw_type, p->auth_mode, le16_to_cpu(p->ch),
2570 le32_to_cpu(p->ctrl_flags), res);
2571 return res;
2572}
2573
2574int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 cmd, const u8 *mac, u16 reason)
2575{
2576 struct sk_buff *skb;
2577 struct wmi_ap_set_mlme_cmd *cm;
2578
2579 skb = ath6kl_wmi_get_new_buf(sizeof(*cm));
2580 if (!skb)
2581 return -ENOMEM;
2582
2583 cm = (struct wmi_ap_set_mlme_cmd *) skb->data;
2584 memcpy(cm->mac, mac, ETH_ALEN);
2585 cm->reason = cpu_to_le16(reason);
2586 cm->cmd = cmd;
2587
2588 return ath6kl_wmi_cmd_send(wmip, skb, WMI_AP_SET_MLME_CMDID,
2589 NO_SYNC_WMIFLAG);
2590}
2591
2403static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len) 2592static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len)
2404{ 2593{
2405 struct wmi_pspoll_event *ev; 2594 struct wmi_pspoll_event *ev;
@@ -2433,6 +2622,7 @@ int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag)
2433 2622
2434 cmd = (struct wmi_ap_set_pvb_cmd *) skb->data; 2623 cmd = (struct wmi_ap_set_pvb_cmd *) skb->data;
2435 cmd->aid = cpu_to_le16(aid); 2624 cmd->aid = cpu_to_le16(aid);
2625 cmd->rsvd = cpu_to_le16(0);
2436 cmd->flag = cpu_to_le32(flag); 2626 cmd->flag = cpu_to_le32(flag);
2437 2627
2438 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_AP_SET_PVB_CMDID, 2628 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_AP_SET_PVB_CMDID,
@@ -2464,6 +2654,160 @@ int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_ver,
2464 return ret; 2654 return ret;
2465} 2655}
2466 2656
2657int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 mgmt_frm_type, const u8 *ie,
2658 u8 ie_len)
2659{
2660 struct sk_buff *skb;
2661 struct wmi_set_appie_cmd *p;
2662
2663 skb = ath6kl_wmi_get_new_buf(sizeof(*p) + ie_len);
2664 if (!skb)
2665 return -ENOMEM;
2666
2667 ath6kl_dbg(ATH6KL_DBG_WMI, "set_appie_cmd: mgmt_frm_type=%u "
2668 "ie_len=%u\n", mgmt_frm_type, ie_len);
2669 p = (struct wmi_set_appie_cmd *) skb->data;
2670 p->mgmt_frm_type = mgmt_frm_type;
2671 p->ie_len = ie_len;
2672 memcpy(p->ie_info, ie, ie_len);
2673 return ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_APPIE_CMDID,
2674 NO_SYNC_WMIFLAG);
2675}
2676
2677int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable)
2678{
2679 struct sk_buff *skb;
2680 struct wmi_disable_11b_rates_cmd *cmd;
2681
2682 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
2683 if (!skb)
2684 return -ENOMEM;
2685
2686 ath6kl_dbg(ATH6KL_DBG_WMI, "disable_11b_rates_cmd: disable=%u\n",
2687 disable);
2688 cmd = (struct wmi_disable_11b_rates_cmd *) skb->data;
2689 cmd->disable = disable ? 1 : 0;
2690
2691 return ath6kl_wmi_cmd_send(wmi, skb, WMI_DISABLE_11B_RATES_CMDID,
2692 NO_SYNC_WMIFLAG);
2693}
2694
2695int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u32 freq, u32 dur)
2696{
2697 struct sk_buff *skb;
2698 struct wmi_remain_on_chnl_cmd *p;
2699
2700 skb = ath6kl_wmi_get_new_buf(sizeof(*p));
2701 if (!skb)
2702 return -ENOMEM;
2703
2704 ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl_cmd: freq=%u dur=%u\n",
2705 freq, dur);
2706 p = (struct wmi_remain_on_chnl_cmd *) skb->data;
2707 p->freq = cpu_to_le32(freq);
2708 p->duration = cpu_to_le32(dur);
2709 return ath6kl_wmi_cmd_send(wmi, skb, WMI_REMAIN_ON_CHNL_CMDID,
2710 NO_SYNC_WMIFLAG);
2711}
2712
2713int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u32 id, u32 freq, u32 wait,
2714 const u8 *data, u16 data_len)
2715{
2716 struct sk_buff *skb;
2717 struct wmi_send_action_cmd *p;
2718 u8 *buf;
2719
2720 if (wait)
2721 return -EINVAL; /* Offload for wait not supported */
2722
2723 buf = kmalloc(data_len, GFP_KERNEL);
2724 if (!buf)
2725 return -ENOMEM;
2726
2727 skb = ath6kl_wmi_get_new_buf(sizeof(*p) + data_len);
2728 if (!skb) {
2729 kfree(buf);
2730 return -ENOMEM;
2731 }
2732
2733 kfree(wmi->last_mgmt_tx_frame);
2734 wmi->last_mgmt_tx_frame = buf;
2735 wmi->last_mgmt_tx_frame_len = data_len;
2736
2737 ath6kl_dbg(ATH6KL_DBG_WMI, "send_action_cmd: id=%u freq=%u wait=%u "
2738 "len=%u\n", id, freq, wait, data_len);
2739 p = (struct wmi_send_action_cmd *) skb->data;
2740 p->id = cpu_to_le32(id);
2741 p->freq = cpu_to_le32(freq);
2742 p->wait = cpu_to_le32(wait);
2743 p->len = cpu_to_le16(data_len);
2744 memcpy(p->data, data, data_len);
2745 return ath6kl_wmi_cmd_send(wmi, skb, WMI_SEND_ACTION_CMDID,
2746 NO_SYNC_WMIFLAG);
2747}
2748
2749int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u32 freq,
2750 const u8 *dst,
2751 const u8 *data, u16 data_len)
2752{
2753 struct sk_buff *skb;
2754 struct wmi_p2p_probe_response_cmd *p;
2755
2756 skb = ath6kl_wmi_get_new_buf(sizeof(*p) + data_len);
2757 if (!skb)
2758 return -ENOMEM;
2759
2760 ath6kl_dbg(ATH6KL_DBG_WMI, "send_probe_response_cmd: freq=%u dst=%pM "
2761 "len=%u\n", freq, dst, data_len);
2762 p = (struct wmi_p2p_probe_response_cmd *) skb->data;
2763 p->freq = cpu_to_le32(freq);
2764 memcpy(p->destination_addr, dst, ETH_ALEN);
2765 p->len = cpu_to_le16(data_len);
2766 memcpy(p->data, data, data_len);
2767 return ath6kl_wmi_cmd_send(wmi, skb, WMI_SEND_PROBE_RESPONSE_CMDID,
2768 NO_SYNC_WMIFLAG);
2769}
2770
2771int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, bool enable)
2772{
2773 struct sk_buff *skb;
2774 struct wmi_probe_req_report_cmd *p;
2775
2776 skb = ath6kl_wmi_get_new_buf(sizeof(*p));
2777 if (!skb)
2778 return -ENOMEM;
2779
2780 ath6kl_dbg(ATH6KL_DBG_WMI, "probe_report_req_cmd: enable=%u\n",
2781 enable);
2782 p = (struct wmi_probe_req_report_cmd *) skb->data;
2783 p->enable = enable ? 1 : 0;
2784 return ath6kl_wmi_cmd_send(wmi, skb, WMI_PROBE_REQ_REPORT_CMDID,
2785 NO_SYNC_WMIFLAG);
2786}
2787
2788int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u32 info_req_flags)
2789{
2790 struct sk_buff *skb;
2791 struct wmi_get_p2p_info *p;
2792
2793 skb = ath6kl_wmi_get_new_buf(sizeof(*p));
2794 if (!skb)
2795 return -ENOMEM;
2796
2797 ath6kl_dbg(ATH6KL_DBG_WMI, "info_req_cmd: flags=%x\n",
2798 info_req_flags);
2799 p = (struct wmi_get_p2p_info *) skb->data;
2800 p->info_req_flags = cpu_to_le32(info_req_flags);
2801 return ath6kl_wmi_cmd_send(wmi, skb, WMI_GET_P2P_INFO_CMDID,
2802 NO_SYNC_WMIFLAG);
2803}
2804
2805int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi)
2806{
2807 ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl_cmd\n");
2808 return ath6kl_wmi_simple_cmd(wmi, WMI_CANCEL_REMAIN_ON_CHNL_CMDID);
2809}
2810
2467static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb) 2811static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
2468{ 2812{
2469 struct wmix_cmd_hdr *cmd; 2813 struct wmix_cmd_hdr *cmd;
@@ -2488,11 +2832,14 @@ static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
2488 2832
2489 switch (id) { 2833 switch (id) {
2490 case WMIX_HB_CHALLENGE_RESP_EVENTID: 2834 case WMIX_HB_CHALLENGE_RESP_EVENTID:
2835 ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event hb challenge resp\n");
2491 break; 2836 break;
2492 case WMIX_DBGLOG_EVENTID: 2837 case WMIX_DBGLOG_EVENTID:
2838 ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event dbglog len %d\n", len);
2839 ath6kl_debug_fwlog_event(wmi->parent_dev, datap, len);
2493 break; 2840 break;
2494 default: 2841 default:
2495 ath6kl_err("unknown cmd id 0x%x\n", id); 2842 ath6kl_warn("unknown cmd id 0x%x\n", id);
2496 wmi->stat.cmd_id_err++; 2843 wmi->stat.cmd_id_err++;
2497 ret = -EINVAL; 2844 ret = -EINVAL;
2498 break; 2845 break;
@@ -2528,8 +2875,9 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
2528 datap = skb->data; 2875 datap = skb->data;
2529 len = skb->len; 2876 len = skb->len;
2530 2877
2531 ath6kl_dbg(ATH6KL_DBG_WMI, "%s: wmi id: %d\n", __func__, id); 2878 ath6kl_dbg(ATH6KL_DBG_WMI, "wmi rx id %d len %d\n", id, len);
2532 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "msg payload ", datap, len); 2879 ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi rx ",
2880 datap, len);
2533 2881
2534 switch (id) { 2882 switch (id) {
2535 case WMI_GET_BITRATE_CMDID: 2883 case WMI_GET_BITRATE_CMDID:
@@ -2566,11 +2914,11 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
2566 break; 2914 break;
2567 case WMI_BSSINFO_EVENTID: 2915 case WMI_BSSINFO_EVENTID:
2568 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n"); 2916 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n");
2569 ath6kl_wmi_convert_bssinfo_hdr2_to_hdr(skb, datap); 2917 ret = ath6kl_wmi_bssinfo_event_rx(wmi, datap, len);
2570 ret = ath6kl_wmi_bssinfo_event_rx(wmi, skb->data, skb->len);
2571 break; 2918 break;
2572 case WMI_REGDOMAIN_EVENTID: 2919 case WMI_REGDOMAIN_EVENTID:
2573 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n"); 2920 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n");
2921 ath6kl_wmi_regdomain_event(wmi, datap, len);
2574 break; 2922 break;
2575 case WMI_PSTREAM_TIMEOUT_EVENTID: 2923 case WMI_PSTREAM_TIMEOUT_EVENTID:
2576 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSTREAM_TIMEOUT_EVENTID\n"); 2924 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSTREAM_TIMEOUT_EVENTID\n");
@@ -2578,6 +2926,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
2578 break; 2926 break;
2579 case WMI_NEIGHBOR_REPORT_EVENTID: 2927 case WMI_NEIGHBOR_REPORT_EVENTID:
2580 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n"); 2928 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n");
2929 ret = ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len);
2581 break; 2930 break;
2582 case WMI_SCAN_COMPLETE_EVENTID: 2931 case WMI_SCAN_COMPLETE_EVENTID:
2583 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n"); 2932 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n");
@@ -2600,7 +2949,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
2600 break; 2949 break;
2601 case WMI_OPT_RX_FRAME_EVENTID: 2950 case WMI_OPT_RX_FRAME_EVENTID:
2602 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_OPT_RX_FRAME_EVENTID\n"); 2951 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_OPT_RX_FRAME_EVENTID\n");
2603 ret = ath6kl_wmi_opt_frame_event_rx(wmi, datap, len); 2952 /* this event has been deprecated */
2604 break; 2953 break;
2605 case WMI_REPORT_ROAM_TBL_EVENTID: 2954 case WMI_REPORT_ROAM_TBL_EVENTID:
2606 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_TBL_EVENTID\n"); 2955 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_TBL_EVENTID\n");
@@ -2619,6 +2968,10 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
2619 case WMI_REPORT_ROAM_DATA_EVENTID: 2968 case WMI_REPORT_ROAM_DATA_EVENTID:
2620 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_DATA_EVENTID\n"); 2969 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_DATA_EVENTID\n");
2621 break; 2970 break;
2971 case WMI_TEST_EVENTID:
2972 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TEST_EVENTID\n");
2973 ret = ath6kl_wmi_tcmd_test_report_rx(wmi, datap, len);
2974 break;
2622 case WMI_GET_FIXRATES_CMDID: 2975 case WMI_GET_FIXRATES_CMDID:
2623 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n"); 2976 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n");
2624 ret = ath6kl_wmi_ratemask_reply_rx(wmi, datap, len); 2977 ret = ath6kl_wmi_ratemask_reply_rx(wmi, datap, len);
@@ -2683,6 +3036,36 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
2683 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n"); 3036 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n");
2684 ret = ath6kl_wmi_tx_complete_event_rx(datap, len); 3037 ret = ath6kl_wmi_tx_complete_event_rx(datap, len);
2685 break; 3038 break;
3039 case WMI_REMAIN_ON_CHNL_EVENTID:
3040 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n");
3041 ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len);
3042 break;
3043 case WMI_CANCEL_REMAIN_ON_CHNL_EVENTID:
3044 ath6kl_dbg(ATH6KL_DBG_WMI,
3045 "WMI_CANCEL_REMAIN_ON_CHNL_EVENTID\n");
3046 ret = ath6kl_wmi_cancel_remain_on_chnl_event_rx(wmi, datap,
3047 len);
3048 break;
3049 case WMI_TX_STATUS_EVENTID:
3050 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_STATUS_EVENTID\n");
3051 ret = ath6kl_wmi_tx_status_event_rx(wmi, datap, len);
3052 break;
3053 case WMI_RX_PROBE_REQ_EVENTID:
3054 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_PROBE_REQ_EVENTID\n");
3055 ret = ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len);
3056 break;
3057 case WMI_P2P_CAPABILITIES_EVENTID:
3058 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_CAPABILITIES_EVENTID\n");
3059 ret = ath6kl_wmi_p2p_capabilities_event_rx(datap, len);
3060 break;
3061 case WMI_RX_ACTION_EVENTID:
3062 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n");
3063 ret = ath6kl_wmi_rx_action_event_rx(wmi, datap, len);
3064 break;
3065 case WMI_P2P_INFO_EVENTID:
3066 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_INFO_EVENTID\n");
3067 ret = ath6kl_wmi_p2p_info_event_rx(datap, len);
3068 break;
2686 default: 3069 default:
2687 ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", id); 3070 ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", id);
2688 wmi->stat.cmd_id_err++; 3071 wmi->stat.cmd_id_err++;
@@ -2739,5 +3122,6 @@ void ath6kl_wmi_shutdown(struct wmi *wmi)
2739 if (!wmi) 3122 if (!wmi)
2740 return; 3123 return;
2741 3124
3125 kfree(wmi->last_mgmt_tx_frame);
2742 kfree(wmi); 3126 kfree(wmi);
2743} 3127}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index fe3ddce64087..f8e644d54aa7 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -129,6 +129,9 @@ struct wmi {
129 u8 ht_allowed[A_NUM_BANDS]; 129 u8 ht_allowed[A_NUM_BANDS];
130 u8 traffic_class; 130 u8 traffic_class;
131 bool is_probe_ssid; 131 bool is_probe_ssid;
132
133 u8 *last_mgmt_tx_frame;
134 size_t last_mgmt_tx_frame_len;
132}; 135};
133 136
134struct host_app_area { 137struct host_app_area {
@@ -490,17 +493,61 @@ enum wmi_cmd_id {
490 WMI_SET_PASSPHRASE_CMDID, 493 WMI_SET_PASSPHRASE_CMDID,
491 WMI_SEND_ASSOC_RES_CMDID, 494 WMI_SEND_ASSOC_RES_CMDID,
492 WMI_SET_ASSOC_REQ_RELAY_CMDID, 495 WMI_SET_ASSOC_REQ_RELAY_CMDID,
493 WMI_GET_RFKILL_MODE_CMDID,
494 496
495 /* ACS command, consists of sub-commands */ 497 /* ACS command, consists of sub-commands */
496 WMI_ACS_CTRL_CMDID, 498 WMI_ACS_CTRL_CMDID,
499 WMI_SET_EXCESS_TX_RETRY_THRES_CMDID,
500 WMI_SET_TBD_TIME_CMDID, /*added for wmiconfig command for TBD */
501
502 /* Pktlog cmds */
503 WMI_PKTLOG_ENABLE_CMDID,
504 WMI_PKTLOG_DISABLE_CMDID,
505
506 /* More P2P Cmds */
507 WMI_P2P_GO_NEG_REQ_RSP_CMDID,
508 WMI_P2P_GRP_INIT_CMDID,
509 WMI_P2P_GRP_FORMATION_DONE_CMDID,
510 WMI_P2P_INVITE_CMDID,
511 WMI_P2P_INVITE_REQ_RSP_CMDID,
512 WMI_P2P_PROV_DISC_REQ_CMDID,
513 WMI_P2P_SET_CMDID,
514
515 WMI_GET_RFKILL_MODE_CMDID,
516 WMI_SET_RFKILL_MODE_CMDID,
517 WMI_AP_SET_APSD_CMDID,
518 WMI_AP_APSD_BUFFERED_TRAFFIC_CMDID,
497 519
520 WMI_P2P_SDPD_TX_CMDID, /* F05C */
521 WMI_P2P_STOP_SDPD_CMDID,
522 WMI_P2P_CANCEL_CMDID,
498 /* Ultra low power store / recall commands */ 523 /* Ultra low power store / recall commands */
499 WMI_STORERECALL_CONFIGURE_CMDID, 524 WMI_STORERECALL_CONFIGURE_CMDID,
500 WMI_STORERECALL_RECALL_CMDID, 525 WMI_STORERECALL_RECALL_CMDID,
501 WMI_STORERECALL_HOST_READY_CMDID, 526 WMI_STORERECALL_HOST_READY_CMDID,
502 WMI_FORCE_TARGET_ASSERT_CMDID, 527 WMI_FORCE_TARGET_ASSERT_CMDID,
503 WMI_SET_EXCESS_TX_RETRY_THRES_CMDID, 528
529 WMI_SET_PROBED_SSID_EX_CMDID,
530 WMI_SET_NETWORK_LIST_OFFLOAD_CMDID,
531 WMI_SET_ARP_NS_OFFLOAD_CMDID,
532 WMI_ADD_WOW_EXT_PATTERN_CMDID,
533 WMI_GTK_OFFLOAD_OP_CMDID,
534 WMI_REMAIN_ON_CHNL_CMDID,
535 WMI_CANCEL_REMAIN_ON_CHNL_CMDID,
536 WMI_SEND_ACTION_CMDID,
537 WMI_PROBE_REQ_REPORT_CMDID,
538 WMI_DISABLE_11B_RATES_CMDID,
539 WMI_SEND_PROBE_RESPONSE_CMDID,
540 WMI_GET_P2P_INFO_CMDID,
541 WMI_AP_JOIN_BSS_CMDID,
542};
543
544enum wmi_mgmt_frame_type {
545 WMI_FRAME_BEACON = 0,
546 WMI_FRAME_PROBE_REQ,
547 WMI_FRAME_PROBE_RESP,
548 WMI_FRAME_ASSOC_REQ,
549 WMI_FRAME_ASSOC_RESP,
550 WMI_NUM_MGMT_FRAME
504}; 551};
505 552
506/* WMI_CONNECT_CMDID */ 553/* WMI_CONNECT_CMDID */
@@ -519,11 +566,6 @@ enum dot11_auth_mode {
519 LEAP_AUTH = 0x04, 566 LEAP_AUTH = 0x04,
520}; 567};
521 568
522enum {
523 AUTH_IDLE,
524 AUTH_OPEN_IN_PROGRESS,
525};
526
527enum auth_mode { 569enum auth_mode {
528 NONE_AUTH = 0x01, 570 NONE_AUTH = 0x01,
529 WPA_AUTH = 0x02, 571 WPA_AUTH = 0x02,
@@ -1179,15 +1221,26 @@ enum wmi_event_id {
1179 WMI_WAC_START_WPS_EVENTID, 1221 WMI_WAC_START_WPS_EVENTID,
1180 WMI_WAC_CTRL_REQ_REPLY_EVENTID, 1222 WMI_WAC_CTRL_REQ_REPLY_EVENTID,
1181 1223
1224 WMI_REPORT_WMM_PARAMS_EVENTID,
1225 WMI_WAC_REJECT_WPS_EVENTID,
1226
1227 /* More P2P Events */
1228 WMI_P2P_GO_NEG_REQ_EVENTID,
1229 WMI_P2P_INVITE_REQ_EVENTID,
1230 WMI_P2P_INVITE_RCVD_RESULT_EVENTID,
1231 WMI_P2P_INVITE_SENT_RESULT_EVENTID,
1232 WMI_P2P_PROV_DISC_RESP_EVENTID,
1233 WMI_P2P_PROV_DISC_REQ_EVENTID,
1234
1182 /* RFKILL Events */ 1235 /* RFKILL Events */
1183 WMI_RFKILL_STATE_CHANGE_EVENTID, 1236 WMI_RFKILL_STATE_CHANGE_EVENTID,
1184 WMI_RFKILL_GET_MODE_CMD_EVENTID, 1237 WMI_RFKILL_GET_MODE_CMD_EVENTID,
1185 WMI_THIN_RESERVED_START_EVENTID = 0x8000,
1186 1238
1187 /* 1239 WMI_P2P_START_SDPD_EVENTID,
1188 * Events in this range are reserved for thinmode 1240 WMI_P2P_SDPD_RX_EVENTID,
1189 * See wmi_thin.h for actual definitions 1241
1190 */ 1242 WMI_THIN_RESERVED_START_EVENTID = 0x8000,
1243 /* Events in this range are reserved for thinmode */
1191 WMI_THIN_RESERVED_END_EVENTID = 0x8fff, 1244 WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
1192 1245
1193 WMI_SET_CHANNEL_EVENTID, 1246 WMI_SET_CHANNEL_EVENTID,
@@ -1195,7 +1248,17 @@ enum wmi_event_id {
1195 1248
1196 /* Generic ACS event */ 1249 /* Generic ACS event */
1197 WMI_ACS_EVENTID, 1250 WMI_ACS_EVENTID,
1198 WMI_REPORT_WMM_PARAMS_EVENTID 1251 WMI_STORERECALL_STORE_EVENTID,
1252 WMI_WOW_EXT_WAKE_EVENTID,
1253 WMI_GTK_OFFLOAD_STATUS_EVENTID,
1254 WMI_NETWORK_LIST_OFFLOAD_EVENTID,
1255 WMI_REMAIN_ON_CHNL_EVENTID,
1256 WMI_CANCEL_REMAIN_ON_CHNL_EVENTID,
1257 WMI_TX_STATUS_EVENTID,
1258 WMI_RX_PROBE_REQ_EVENTID,
1259 WMI_P2P_CAPABILITIES_EVENTID,
1260 WMI_RX_ACTION_EVENTID,
1261 WMI_P2P_INFO_EVENTID,
1199}; 1262};
1200 1263
1201struct wmi_ready_event_2 { 1264struct wmi_ready_event_2 {
@@ -1207,11 +1270,30 @@ struct wmi_ready_event_2 {
1207 1270
1208/* Connect Event */ 1271/* Connect Event */
1209struct wmi_connect_event { 1272struct wmi_connect_event {
1210 __le16 ch; 1273 union {
1211 u8 bssid[ETH_ALEN]; 1274 struct {
1212 __le16 listen_intvl; 1275 __le16 ch;
1213 __le16 beacon_intvl; 1276 u8 bssid[ETH_ALEN];
1214 __le32 nw_type; 1277 __le16 listen_intvl;
1278 __le16 beacon_intvl;
1279 __le32 nw_type;
1280 } sta;
1281 struct {
1282 u8 phymode;
1283 u8 aid;
1284 u8 mac_addr[ETH_ALEN];
1285 u8 auth;
1286 u8 keymgmt;
1287 __le16 cipher;
1288 u8 apsd_info;
1289 u8 unused[3];
1290 } ap_sta;
1291 struct {
1292 __le16 ch;
1293 u8 bssid[ETH_ALEN];
1294 u8 unused[8];
1295 } ap_bss;
1296 } u;
1215 u8 beacon_ie_len; 1297 u8 beacon_ie_len;
1216 u8 assoc_req_len; 1298 u8 assoc_req_len;
1217 u8 assoc_resp_len; 1299 u8 assoc_resp_len;
@@ -1238,6 +1320,12 @@ enum wmi_disconnect_reason {
1238 IBSS_MERGE = 0xe, 1320 IBSS_MERGE = 0xe,
1239}; 1321};
1240 1322
1323#define ATH6KL_COUNTRY_RD_SHIFT 16
1324
1325struct ath6kl_wmi_regdomain {
1326 __le32 reg_code;
1327};
1328
1241struct wmi_disconnect_event { 1329struct wmi_disconnect_event {
1242 /* reason code, see 802.11 spec. */ 1330 /* reason code, see 802.11 spec. */
1243 __le16 proto_reason_status; 1331 __le16 proto_reason_status;
@@ -1265,33 +1353,54 @@ enum wmi_bi_ftype {
1265 PROBEREQ_FTYPE, 1353 PROBEREQ_FTYPE,
1266}; 1354};
1267 1355
1268struct wmi_bss_info_hdr { 1356#define DEF_LRSSI_SCAN_PERIOD 5
1269 __le16 ch; 1357#define DEF_LRSSI_ROAM_THRESHOLD 20
1358#define DEF_LRSSI_ROAM_FLOOR 60
1359#define DEF_SCAN_FOR_ROAM_INTVL 2
1270 1360
1271 /* see, enum wmi_bi_ftype */ 1361enum wmi_roam_ctrl {
1272 u8 frame_type; 1362 WMI_FORCE_ROAM = 1,
1363 WMI_SET_ROAM_MODE,
1364 WMI_SET_HOST_BIAS,
1365 WMI_SET_LRSSI_SCAN_PARAMS,
1366};
1273 1367
1274 u8 snr; 1368struct bss_bias {
1275 a_sle16 rssi;
1276 u8 bssid[ETH_ALEN]; 1369 u8 bssid[ETH_ALEN];
1277 __le32 ie_mask; 1370 u8 bias;
1278} __packed; 1371} __packed;
1279 1372
1280/* 1373struct bss_bias_info {
1281 * BSS INFO HDR version 2.0 1374 u8 num_bss;
1282 * With 6 bytes HTC header and 6 bytes of WMI header 1375 struct bss_bias bss_bias[1];
1283 * WMI_BSS_INFO_HDR cannot be accommodated in the removed 802.11 management 1376} __packed;
1284 * header space. 1377
1285 * - Reduce the ie_mask to 2 bytes as only two bit flags are used 1378struct low_rssi_scan_params {
1286 * - Remove rssi and compute it on the host. rssi = snr - 95 1379 __le16 lrssi_scan_period;
1287 */ 1380 a_sle16 lrssi_scan_threshold;
1381 a_sle16 lrssi_roam_threshold;
1382 u8 roam_rssi_floor;
1383 u8 reserved[1];
1384} __packed;
1385
1386struct roam_ctrl_cmd {
1387 union {
1388 u8 bssid[ETH_ALEN];
1389 u8 roam_mode;
1390 struct bss_bias_info bss;
1391 struct low_rssi_scan_params params;
1392 } __packed info;
1393 u8 roam_ctrl;
1394} __packed;
1395
1396/* BSS INFO HDR version 2.0 */
1288struct wmi_bss_info_hdr2 { 1397struct wmi_bss_info_hdr2 {
1289 __le16 ch; 1398 __le16 ch; /* frequency in MHz */
1290 1399
1291 /* see, enum wmi_bi_ftype */ 1400 /* see, enum wmi_bi_ftype */
1292 u8 frame_type; 1401 u8 frame_type;
1293 1402
1294 u8 snr; 1403 u8 snr; /* note: rssi = snr - 95 dBm */
1295 u8 bssid[ETH_ALEN]; 1404 u8 bssid[ETH_ALEN];
1296 __le16 ie_mask; 1405 __le16 ie_mask;
1297} __packed; 1406} __packed;
@@ -1330,6 +1439,16 @@ enum wmi_bss_flags {
1330 WMI_PMKID_VALID_BSS = 0x02, 1439 WMI_PMKID_VALID_BSS = 0x02,
1331}; 1440};
1332 1441
1442struct wmi_neighbor_info {
1443 u8 bssid[ETH_ALEN];
1444 u8 bss_flags; /* enum wmi_bss_flags */
1445} __packed;
1446
1447struct wmi_neighbor_report_event {
1448 u8 num_neighbors;
1449 struct wmi_neighbor_info neighbor[0];
1450} __packed;
1451
1333/* TKIP MIC Error Event */ 1452/* TKIP MIC Error Event */
1334struct wmi_tkip_micerr_event { 1453struct wmi_tkip_micerr_event {
1335 u8 key_id; 1454 u8 key_id;
@@ -1642,6 +1761,12 @@ struct wmi_get_keepalive_cmd {
1642 u8 keep_alive_intvl; 1761 u8 keep_alive_intvl;
1643} __packed; 1762} __packed;
1644 1763
1764struct wmi_set_appie_cmd {
1765 u8 mgmt_frm_type; /* enum wmi_mgmt_frame_type */
1766 u8 ie_len;
1767 u8 ie_info[0];
1768} __packed;
1769
1645/* Notify the WSC registration status to the target */ 1770/* Notify the WSC registration status to the target */
1646#define WSC_REG_ACTIVE 1 1771#define WSC_REG_ACTIVE 1
1647#define WSC_REG_INACTIVE 0 1772#define WSC_REG_INACTIVE 0
@@ -1789,8 +1914,26 @@ struct wmi_tx_complete_event {
1789 1914
1790/* Used with WMI_AP_SET_NUM_STA_CMDID */ 1915/* Used with WMI_AP_SET_NUM_STA_CMDID */
1791 1916
1917/*
1918 * Used with WMI_AP_SET_MLME_CMDID
1919 */
1920
1921/* MLME Commands */
1922#define WMI_AP_MLME_ASSOC 1 /* associate station */
1923#define WMI_AP_DISASSOC 2 /* disassociate station */
1924#define WMI_AP_DEAUTH 3 /* deauthenticate station */
1925#define WMI_AP_MLME_AUTHORIZE 4 /* authorize station */
1926#define WMI_AP_MLME_UNAUTHORIZE 5 /* unauthorize station */
1927
1928struct wmi_ap_set_mlme_cmd {
1929 u8 mac[ETH_ALEN];
1930 __le16 reason; /* 802.11 reason code */
1931 u8 cmd; /* operation to perform (WMI_AP_*) */
1932} __packed;
1933
1792struct wmi_ap_set_pvb_cmd { 1934struct wmi_ap_set_pvb_cmd {
1793 __le32 flag; 1935 __le32 flag;
1936 __le16 rsvd;
1794 __le16 aid; 1937 __le16 aid;
1795} __packed; 1938} __packed;
1796 1939
@@ -1840,6 +1983,100 @@ struct wmi_ap_mode_stat {
1840 1983
1841/* End of AP mode definitions */ 1984/* End of AP mode definitions */
1842 1985
1986struct wmi_remain_on_chnl_cmd {
1987 __le32 freq;
1988 __le32 duration;
1989} __packed;
1990
1991struct wmi_send_action_cmd {
1992 __le32 id;
1993 __le32 freq;
1994 __le32 wait;
1995 __le16 len;
1996 u8 data[0];
1997} __packed;
1998
1999struct wmi_tx_status_event {
2000 __le32 id;
2001 u8 ack_status;
2002} __packed;
2003
2004struct wmi_probe_req_report_cmd {
2005 u8 enable;
2006} __packed;
2007
2008struct wmi_disable_11b_rates_cmd {
2009 u8 disable;
2010} __packed;
2011
2012struct wmi_set_appie_extended_cmd {
2013 u8 role_id;
2014 u8 mgmt_frm_type;
2015 u8 ie_len;
2016 u8 ie_info[0];
2017} __packed;
2018
2019struct wmi_remain_on_chnl_event {
2020 __le32 freq;
2021 __le32 duration;
2022} __packed;
2023
2024struct wmi_cancel_remain_on_chnl_event {
2025 __le32 freq;
2026 __le32 duration;
2027 u8 status;
2028} __packed;
2029
2030struct wmi_rx_action_event {
2031 __le32 freq;
2032 __le16 len;
2033 u8 data[0];
2034} __packed;
2035
2036struct wmi_p2p_capabilities_event {
2037 __le16 len;
2038 u8 data[0];
2039} __packed;
2040
2041struct wmi_p2p_rx_probe_req_event {
2042 __le32 freq;
2043 __le16 len;
2044 u8 data[0];
2045} __packed;
2046
2047#define P2P_FLAG_CAPABILITIES_REQ (0x00000001)
2048#define P2P_FLAG_MACADDR_REQ (0x00000002)
2049#define P2P_FLAG_HMODEL_REQ (0x00000002)
2050
2051struct wmi_get_p2p_info {
2052 __le32 info_req_flags;
2053} __packed;
2054
2055struct wmi_p2p_info_event {
2056 __le32 info_req_flags;
2057 __le16 len;
2058 u8 data[0];
2059} __packed;
2060
2061struct wmi_p2p_capabilities {
2062 u8 go_power_save;
2063} __packed;
2064
2065struct wmi_p2p_macaddr {
2066 u8 mac_addr[ETH_ALEN];
2067} __packed;
2068
2069struct wmi_p2p_hmodel {
2070 u8 p2p_model;
2071} __packed;
2072
2073struct wmi_p2p_probe_response_cmd {
2074 __le32 freq;
2075 u8 destination_addr[ETH_ALEN];
2076 __le16 len;
2077 u8 data[0];
2078} __packed;
2079
1843/* Extended WMI (WMIX) 2080/* Extended WMI (WMIX)
1844 * 2081 *
1845 * Extended WMIX commands are encapsulated in a WMI message with 2082 * Extended WMIX commands are encapsulated in a WMI message with
@@ -1898,6 +2135,11 @@ struct wmix_hb_challenge_resp_cmd {
1898 __le32 source; 2135 __le32 source;
1899} __packed; 2136} __packed;
1900 2137
2138struct ath6kl_wmix_dbglog_cfg_module_cmd {
2139 __le32 valid;
2140 __le32 config;
2141} __packed;
2142
1901/* End of Extended WMI (WMIX) */ 2143/* End of Extended WMI (WMIX) */
1902 2144
1903enum wmi_sync_flag { 2145enum wmi_sync_flag {
@@ -1925,14 +2167,11 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
1925 2167
1926int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb); 2168int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
1927int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb); 2169int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb);
1928int ath6kl_wmi_data_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
1929int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb, 2170int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb,
1930 u32 layer2_priority, bool wmm_enabled, 2171 u32 layer2_priority, bool wmm_enabled,
1931 u8 *ac); 2172 u8 *ac);
1932 2173
1933int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb); 2174int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb);
1934struct bss *ath6kl_wmi_find_node(struct wmi *wmi, const u8 *mac_addr);
1935void ath6kl_wmi_node_free(struct wmi *wmi, const u8 *mac_addr);
1936 2175
1937int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb, 2176int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,
1938 enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag); 2177 enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag);
@@ -1978,6 +2217,7 @@ int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status,
1978 u8 preamble_policy); 2217 u8 preamble_policy);
1979 2218
1980int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source); 2219int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source);
2220int ath6kl_wmi_config_debug_module_cmd(struct wmi *wmi, u32 valid, u32 config);
1981 2221
1982int ath6kl_wmi_get_stats_cmd(struct wmi *wmi); 2222int ath6kl_wmi_get_stats_cmd(struct wmi *wmi);
1983int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index, 2223int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,
@@ -1995,23 +2235,47 @@ int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi);
1995 2235
1996int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg); 2236int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg);
1997int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl); 2237int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl);
2238int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);
1998 2239
1999s32 ath6kl_wmi_get_rate(s8 rate_index); 2240s32 ath6kl_wmi_get_rate(s8 rate_index);
2000 2241
2001int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd); 2242int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd);
2243int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
2002 2244
2003struct bss *ath6kl_wmi_find_ssid_node(struct wmi *wmi, u8 *ssid, 2245/* AP mode */
2004 u32 ssid_len, bool is_wpa2, 2246int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, struct wmi_connect_cmd *p);
2005 bool match_ssid);
2006 2247
2007void ath6kl_wmi_node_return(struct wmi *wmi, struct bss *bss); 2248int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 cmd, const u8 *mac, u16 reason);
2008 2249
2009/* AP mode */
2010int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag); 2250int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag);
2011 2251
2012int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_version, 2252int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_version,
2013 bool rx_dot11_hdr, bool defrag_on_host); 2253 bool rx_dot11_hdr, bool defrag_on_host);
2014 2254
2255int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 mgmt_frm_type, const u8 *ie,
2256 u8 ie_len);
2257
2258/* P2P */
2259int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable);
2260
2261int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u32 freq, u32 dur);
2262
2263int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u32 id, u32 freq, u32 wait,
2264 const u8 *data, u16 data_len);
2265
2266int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u32 freq,
2267 const u8 *dst,
2268 const u8 *data, u16 data_len);
2269
2270int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, bool enable);
2271
2272int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u32 info_req_flags);
2273
2274int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi);
2275
2276int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 mgmt_frm_type, const u8 *ie,
2277 u8 ie_len);
2278
2015void *ath6kl_wmi_init(struct ath6kl *devt); 2279void *ath6kl_wmi_init(struct ath6kl *devt);
2016void ath6kl_wmi_shutdown(struct wmi *wmi); 2280void ath6kl_wmi_shutdown(struct wmi *wmi);
2017 2281