Subject: [PATCH V2 00/31] ath6kl Add multiple vif support

This patch set adds basic infrastructure for multiple
virtual interface. As configuring the firmware with more than one
vif causes random target assert, the number of supported vifs is
restricted to 1 for now. I would like to thank Vivek Natarajan
([email protected]) for his inital work in this area and
Arthi Thiruvengadam ([email protected]) for finding some
critical bugs.

Vasanth

V2 -- Rebased to top of ath6kl.git not Kalle's 9-patch series
- Fold patches from 32 to 34 into the original patches (kalle's comment)

Vasanthakumar Thiagarajan (31):
ath6kl: Pass ath6kl structure to ath6kl_init() instead of net_device
ath6kl: Keep wiphy reference in ath6kl structure
ath6kl: Refactor wiphy dev and net dev init functions
ath6kl: Cleanup fw interface type setting
ath6kl: Define an initial vif structure and use it
ath6kl: Define interface specific states
ath6kl: Move ssid and crypto information to vif structure
ath6kl: Move nw_type to vif structure
ath6kl: Move bssid information to vif structure
ath6kl: Move channel information to vif structure
ath6kl: Move key information to vif structure
ath6kl: Move aggregation information to vif structure
ath6kl: Move disconnect timer to vif structure
ath6kl: Move scan_req info and sme_state to vif
ath6kl: Move few more vif specific information to struct ath6kl_vif
ath6kl: Make net and target stats vif specific
ath6kl: Maintain firmware interface index in struct ath6kl_vif
ath6kl: Take vif information from wmi event
ath6kl: Remove net_device from ath6kl
ath6kl: Cleanup parameters in ath6kl_init_control_info() and
ath6kl_init_profile_info()
ath6kl: Refactor ath6kl_destroy()
ath6kl: Use interface index from wmi data headr
ath6kl: Store hw mac address in struct ath6kl
ath6kl: Introduce spinlock to protect vif specific information
ath6kl: Maintain virtual interface in a list
ath6kl: Use the other variant of netdev (un)register APIs
ath6kl: Configure inteface information at init time
ath6kl: Implement add_virtual_intf() and del_virtual_intf()
ath6kl: Add a modparam to enable multi normal interface support
ath6kl: Initialize target wlan values for every vif
ath6kl: Use appropriate wdev from vif

drivers/net/wireless/ath/ath6kl/cfg80211.c | 981 ++++++++++++++++++----------
drivers/net/wireless/ath/ath6kl/cfg80211.h | 16 +-
drivers/net/wireless/ath/ath6kl/common.h | 2 +-
drivers/net/wireless/ath/ath6kl/core.h | 161 +++--
drivers/net/wireless/ath/ath6kl/debug.c | 38 +-
drivers/net/wireless/ath/ath6kl/init.c | 434 ++++++-------
drivers/net/wireless/ath/ath6kl/main.c | 366 +++++------
drivers/net/wireless/ath/ath6kl/sdio.c | 12 +-
drivers/net/wireless/ath/ath6kl/target.h | 3 +
drivers/net/wireless/ath/ath6kl/txrx.c | 198 ++++--
drivers/net/wireless/ath/ath6kl/wmi.c | 426 +++++++-----
drivers/net/wireless/ath/ath6kl/wmi.h | 122 +++--
12 files changed, 1622 insertions(+), 1137 deletions(-)



Subject: [PATCH V2 13/31] ath6kl: Move disconnect timer to vif structure

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 9 ++++-----
drivers/net/wireless/ath/ath6kl/core.h | 2 +-
drivers/net/wireless/ath/ath6kl/main.c | 4 ++--
3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 5959c84..d55c396 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -479,7 +479,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
((vif->auth_mode == WPA_PSK_AUTH)
|| (vif->auth_mode == WPA2_PSK_AUTH))) {
- mod_timer(&ar->disconnect_timer,
+ mod_timer(&vif->disconnect_timer,
jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
}

@@ -897,7 +897,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
if (((vif->auth_mode == WPA_PSK_AUTH)
|| (vif->auth_mode == WPA2_PSK_AUTH))
&& (key_usage & GROUP_USAGE))
- del_timer(&ar->disconnect_timer);
+ del_timer(&vif->disconnect_timer);

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
@@ -2061,16 +2061,15 @@ int ath6kl_register_ieee80211_hw(struct ath6kl *ar)

static int ath6kl_init_if_data(struct ath6kl_vif *vif)
{
- struct ath6kl *ar = vif->ar;
-
vif->aggr_cntxt = aggr_init(vif->ndev);
if (!vif->aggr_cntxt) {
ath6kl_err("failed to initialize aggr\n");
return -ENOMEM;
}

- setup_timer(&ar->disconnect_timer, disconnect_timer_handler,
+ setup_timer(&vif->disconnect_timer, disconnect_timer_handler,
(unsigned long) vif->ndev);
+ set_bit(WMM_ENABLED, &vif->flags);

return 0;
}
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index f15dd6d..5403116 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -416,6 +416,7 @@ struct ath6kl_vif {
struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1];
struct aggr_info *aggr_cntxt;
+ struct timer_list disconnect_timer;
};

/* Flag info */
@@ -477,7 +478,6 @@ struct ath6kl {
struct wmi_ap_mode_stat ap_stats;
u8 ap_country_code[3];
struct list_head amsdu_rx_buffer_queue;
- struct timer_list disconnect_timer;
u8 rx_meta_ver;
struct wireless_dev *wdev;
struct cfg80211_scan_request *scan_req;
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 0bdb73c..d292e17 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -445,7 +445,7 @@ void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
if (!keep_profile)
ath6kl_init_profile_info(ar);

- del_timer(&ar->disconnect_timer);
+ del_timer(&vif->disconnect_timer);

clear_bit(WMI_READY, &ar->flag);
ath6kl_wmi_shutdown(ar->wmi);
@@ -1396,7 +1396,7 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,

aggr_reset_state(vif->aggr_cntxt);

- del_timer(&ar->disconnect_timer);
+ del_timer(&vif->disconnect_timer);

ath6kl_dbg(ATH6KL_DBG_WLAN_CONNECT,
"disconnect reason is %d\n", reason);
--
1.7.0.4


Subject: [PATCH V2 18/31] ath6kl: Take vif information from wmi event

Interface index is passed in wmi command header from target.
Use this index to get the appropriate vif.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 105 +++++++---------
drivers/net/wireless/ath/ath6kl/cfg80211.h | 8 +-
drivers/net/wireless/ath/ath6kl/core.h | 24 ++--
drivers/net/wireless/ath/ath6kl/debug.c | 9 +-
drivers/net/wireless/ath/ath6kl/main.c | 121 ++++++++----------
drivers/net/wireless/ath/ath6kl/txrx.c | 12 +-
drivers/net/wireless/ath/ath6kl/wmi.c | 193 ++++++++++++++++------------
drivers/net/wireless/ath/ath6kl/wmi.h | 16 ++-
8 files changed, 249 insertions(+), 239 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index c8c5712..e870c9c 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -123,12 +123,9 @@ static struct ieee80211_supported_band ath6kl_band_5ghz = {

#define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */

-static int ath6kl_set_wpa_version(struct ath6kl *ar,
+static int ath6kl_set_wpa_version(struct ath6kl_vif *vif,
enum nl80211_wpa_versions wpa_version)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
-
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);

if (!wpa_version) {
@@ -145,12 +142,9 @@ static int ath6kl_set_wpa_version(struct ath6kl *ar,
return 0;
}

-static int ath6kl_set_auth_type(struct ath6kl *ar,
+static int ath6kl_set_auth_type(struct ath6kl_vif *vif,
enum nl80211_auth_type auth_type)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
-
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);

switch (auth_type) {
@@ -176,11 +170,8 @@ static int ath6kl_set_auth_type(struct ath6kl *ar,
return 0;
}

-static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast)
+static int ath6kl_set_cipher(struct ath6kl_vif *vif, u32 cipher, bool ucast)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
-
u8 *ar_cipher = ucast ? &vif->prwise_crypto : &vif->grp_crypto;
u8 *ar_cipher_len = ucast ? &vif->prwise_crypto_len :
&vif->grp_crypto_len;
@@ -218,11 +209,8 @@ static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast)
return 0;
}

-static void ath6kl_set_key_mgmt(struct ath6kl *ar, u32 key_mgmt)
+static void ath6kl_set_key_mgmt(struct ath6kl_vif *vif, u32 key_mgmt)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
-
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);

if (key_mgmt == WLAN_AKM_SUITE_PSK) {
@@ -376,7 +364,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
return 0;
} else if (vif->ssid_len == sme->ssid_len &&
!memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
- ath6kl_disconnect(ar, vif->fw_vif_idx);
+ ath6kl_disconnect(vif);
}

memset(vif->ssid, 0, sizeof(vif->ssid));
@@ -390,23 +378,23 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));

- ath6kl_set_wpa_version(ar, sme->crypto.wpa_versions);
+ ath6kl_set_wpa_version(vif, sme->crypto.wpa_versions);

- status = ath6kl_set_auth_type(ar, sme->auth_type);
+ status = ath6kl_set_auth_type(vif, sme->auth_type);
if (status) {
up(&ar->sem);
return status;
}

if (sme->crypto.n_ciphers_pairwise)
- ath6kl_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
+ ath6kl_set_cipher(vif, sme->crypto.ciphers_pairwise[0], true);
else
- ath6kl_set_cipher(ar, 0, true);
+ ath6kl_set_cipher(vif, 0, true);

- ath6kl_set_cipher(ar, sme->crypto.cipher_group, false);
+ ath6kl_set_cipher(vif, sme->crypto.cipher_group, false);

if (sme->crypto.n_akm_suites)
- ath6kl_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
+ ath6kl_set_key_mgmt(vif, sme->crypto.akm_suites[0]);

if ((sme->key_len) &&
(vif->auth_mode == NONE_AUTH) &&
@@ -438,7 +426,8 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,

if (!ar->usr_bss_filter) {
clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
- if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) {
+ if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
+ ALL_BSS_FILTER, 0) != 0) {
ath6kl_err("couldn't set bss filtering\n");
up(&ar->sem);
return -EIO;
@@ -491,12 +480,11 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
return 0;
}

-static int ath6kl_add_bss_if_needed(struct ath6kl *ar, const u8 *bssid,
+static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, const u8 *bssid,
struct ieee80211_channel *chan,
const u8 *beacon_ie, size_t beacon_ie_len)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;
struct cfg80211_bss *bss;
u8 *ie;

@@ -540,7 +528,7 @@ static int ath6kl_add_bss_if_needed(struct ath6kl *ar, const u8 *bssid,
return 0;
}

-void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
+void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
u8 *bssid, u16 listen_intvl,
u16 beacon_intvl,
enum network_type nw_type,
@@ -548,8 +536,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
u8 assoc_resp_len, u8 *assoc_info)
{
struct ieee80211_channel *chan;
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;

/* capinfo + listen interval */
u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
@@ -592,11 +579,11 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,


if (nw_type & ADHOC_NETWORK) {
- cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
+ cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
return;
}

- if (ath6kl_add_bss_if_needed(ar, bssid, chan, assoc_info,
+ if (ath6kl_add_bss_if_needed(vif, bssid, chan, assoc_info,
beacon_ie_len) < 0) {
ath6kl_err("could not add cfg80211 bss entry for "
"connect/roamed notification\n");
@@ -606,13 +593,13 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
if (vif->sme_state == SME_CONNECTING) {
/* inform connect result to cfg80211 */
vif->sme_state = SME_CONNECTED;
- cfg80211_connect_result(ar->net_dev, bssid,
+ cfg80211_connect_result(vif->ndev, bssid,
assoc_req_ie, assoc_req_len,
assoc_resp_ie, assoc_resp_len,
WLAN_STATUS_SUCCESS, GFP_KERNEL);
} else if (vif->sme_state == SME_CONNECTED) {
/* inform roam event to cfg80211 */
- cfg80211_roamed(ar->net_dev, chan, bssid,
+ cfg80211_roamed(vif->ndev, chan, bssid,
assoc_req_ie, assoc_req_len,
assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
}
@@ -641,7 +628,7 @@ static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
}

vif->reconnect_flag = 0;
- ath6kl_disconnect(ar, vif->fw_vif_idx);
+ ath6kl_disconnect(vif);
memset(vif->ssid, 0, sizeof(vif->ssid));
vif->ssid_len = 0;

@@ -655,12 +642,11 @@ static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
return 0;
}

-void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
+void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
u8 *bssid, u8 assoc_resp_len,
u8 *assoc_info, u16 proto_reason)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;

if (vif->scan_req) {
cfg80211_scan_done(vif->scan_req, true);
@@ -674,7 +660,7 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
return;
}
memset(bssid, 0, ETH_ALEN);
- cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
+ cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
return;
}

@@ -704,13 +690,13 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
clear_bit(CONNECT_PEND, &vif->flags);

if (vif->sme_state == SME_CONNECTING) {
- cfg80211_connect_result(ar->net_dev,
+ cfg80211_connect_result(vif->ndev,
bssid, NULL, 0,
NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
} else if (vif->sme_state == SME_CONNECTED) {
- cfg80211_disconnected(ar->net_dev, reason,
+ cfg80211_disconnected(vif->ndev, reason,
NULL, 0, GFP_KERNEL);
}

@@ -733,7 +719,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
if (!ar->usr_bss_filter) {
clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
ret = ath6kl_wmi_bssfilter_cmd(
- ar->wmi,
+ ar->wmi, vif->fw_vif_idx,
(test_bit(CONNECTED, &vif->flags) ?
ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
if (ret) {
@@ -804,10 +790,9 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
return ret;
}

-void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)
+void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, int status)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;
int i;

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status %d\n", __func__, status);
@@ -852,7 +837,8 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
if (params->key_len != WMI_KRK_LEN)
return -EINVAL;
- return ath6kl_wmi_add_krk_cmd(ar->wmi, params->key);
+ return ath6kl_wmi_add_krk_cmd(ar->wmi, vif->fw_vif_idx,
+ params->key);
}

if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
@@ -1079,16 +1065,13 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
return 0;
}

-void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid,
+void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
bool ismcast)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
-
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);

- cfg80211_michael_mic_failure(ar->net_dev, vif->bssid,
+ cfg80211_michael_mic_failure(vif->ndev, vif->bssid,
(ismcast ? NL80211_KEYTYPE_GROUP :
NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
GFP_KERNEL);
@@ -1282,18 +1265,18 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
memcpy(vif->req_bssid, ibss_param->bssid,
sizeof(vif->req_bssid));

- ath6kl_set_wpa_version(ar, 0);
+ ath6kl_set_wpa_version(vif, 0);

- status = ath6kl_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
+ status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM);
if (status)
return status;

if (ibss_param->privacy) {
- ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
- ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
+ ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true);
+ ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false);
} else {
- ath6kl_set_cipher(ar, 0, true);
- ath6kl_set_cipher(ar, 0, false);
+ ath6kl_set_cipher(vif, 0, true);
+ ath6kl_set_cipher(vif, 0, false);
}

vif->nw_type = vif->next_mode;
@@ -1329,7 +1312,7 @@ static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
if (!ath6kl_cfg80211_ready(ar))
return -EIO;

- ath6kl_disconnect(ar, vif->fw_vif_idx);
+ ath6kl_disconnect(vif);
memset(vif->ssid, 0, sizeof(vif->ssid));
vif->ssid_len = 0;

@@ -1720,9 +1703,9 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
}
if (p.prwise_crypto_type == 0) {
p.prwise_crypto_type = NONE_CRYPT;
- ath6kl_set_cipher(ar, 0, true);
+ ath6kl_set_cipher(vif, 0, true);
} else if (info->crypto.n_ciphers_pairwise == 1)
- ath6kl_set_cipher(ar, info->crypto.ciphers_pairwise[0], true);
+ ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);

switch (info->crypto.cipher_group) {
case WLAN_CIPHER_SUITE_WEP40:
@@ -1739,7 +1722,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
p.grp_crypto_type = NONE_CRYPT;
break;
}
- ath6kl_set_cipher(ar, info->crypto.cipher_group, false);
+ ath6kl_set_cipher(vif, info->crypto.cipher_group, false);

p.nw_type = AP_NETWORK;
vif->nw_type = vif->next_mode;
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h
index 033e742..66042f2 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.h
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h
@@ -24,20 +24,20 @@ int ath6kl_register_ieee80211_hw(struct ath6kl *ar);
struct ath6kl *ath6kl_core_alloc(struct device *dev);
void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar);

-void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status);
+void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, int status);

-void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
+void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
u8 *bssid, u16 listen_intvl,
u16 beacon_intvl,
enum network_type nw_type,
u8 beacon_ie_len, u8 assoc_req_len,
u8 assoc_resp_len, u8 *assoc_info);

-void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
+void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
u8 *bssid, u8 assoc_resp_len,
u8 *assoc_info, u16 proto_reason);

-void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid,
+void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
bool ismcast);

#endif /* ATH6KL_CFG80211_H */
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index f21d777..3fb8898 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -628,32 +628,32 @@ struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid);
void ath6kl_ready_event(void *devt, u8 * datap, u32 sw_ver, u32 abi_ver);
int ath6kl_control_tx(void *devt, struct sk_buff *skb,
enum htc_endpoint_id eid);
-void ath6kl_connect_event(struct ath6kl *ar, u16 channel,
+void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel,
u8 *bssid, u16 listen_int,
u16 beacon_int, enum network_type net_type,
u8 beacon_ie_len, u8 assoc_req_len,
u8 assoc_resp_len, u8 *assoc_info);
-void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel);
-void ath6kl_connect_ap_mode_sta(struct ath6kl *ar, u16 aid, u8 *mac_addr,
+void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel);
+void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
u8 keymgmt, u8 ucipher, u8 auth,
u8 assoc_req_len, u8 *assoc_info);
-void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason,
+void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason,
u8 *bssid, u8 assoc_resp_len,
u8 *assoc_info, u16 prot_reason_status);
-void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast);
+void ath6kl_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid, bool ismcast);
void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr);
-void ath6kl_scan_complete_evt(struct ath6kl *ar, int status);
-void ath6kl_tgt_stats_event(struct ath6kl *ar, u8 *ptr, u32 len);
+void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status);
+void ath6kl_tgt_stats_event(struct ath6kl_vif *vif, u8 *ptr, u32 len);
void ath6kl_indicate_tx_activity(void *devt, u8 traffic_class, bool active);
enum htc_endpoint_id ath6kl_ac2_endpoint_id(void *devt, u8 ac);

-void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid);
+void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid);

-void ath6kl_dtimexpiry_event(struct ath6kl *ar);
-void ath6kl_disconnect(struct ath6kl *ar, u8 if_idx);
+void ath6kl_dtimexpiry_event(struct ath6kl_vif *vif);
+void ath6kl_disconnect(struct ath6kl_vif *vif);
void ath6kl_deep_sleep_enable(struct ath6kl *ar);
-void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid);
-void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no,
+void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid);
+void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no,
u8 win_sz);
void ath6kl_wakeup_event(void *dev);
void ath6kl_target_failure(struct ath6kl *ar);
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 870e9b1..54faa6b 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -1249,6 +1249,8 @@ static ssize_t ath6kl_create_qos_write(struct file *file,
{

struct ath6kl *ar = file->private_data;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
char buf[100];
ssize_t len;
char *sptr, *token;
@@ -1403,7 +1405,7 @@ static ssize_t ath6kl_create_qos_write(struct file *file,
return -EINVAL;
pstream.medium_time = cpu_to_le32(val32);

- ath6kl_wmi_create_pstream_cmd(ar->wmi, &pstream);
+ ath6kl_wmi_create_pstream_cmd(ar->wmi, vif->fw_vif_idx, &pstream);

return count;
}
@@ -1421,6 +1423,8 @@ static ssize_t ath6kl_delete_qos_write(struct file *file,
{

struct ath6kl *ar = file->private_data;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
char buf[100];
ssize_t len;
char *sptr, *token;
@@ -1445,7 +1449,8 @@ static ssize_t ath6kl_delete_qos_write(struct file *file,
if (kstrtou8(token, 0, &tsid))
return -EINVAL;

- ath6kl_wmi_delete_pstream_cmd(ar->wmi, traffic_class, tsid);
+ ath6kl_wmi_delete_pstream_cmd(ar->wmi, vif->fw_vif_idx,
+ traffic_class, tsid);

return count;
}
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 9929901..19b64ae 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -441,7 +441,7 @@ void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
if (test_bit(WMI_READY, &ar->flag)) {
discon_issued = (test_bit(CONNECTED, &vif->flags) ||
test_bit(CONNECT_PEND, &vif->flags));
- ath6kl_disconnect(ar, vif->fw_vif_idx);
+ ath6kl_disconnect(vif);
if (!keep_profile)
ath6kl_init_profile_info(ar);

@@ -462,7 +462,7 @@ void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
* are collected.
*/
if (discon_issued)
- ath6kl_disconnect_event(ar, DISCONNECT_CMD,
+ ath6kl_disconnect_event(vif, DISCONNECT_CMD,
(vif->nw_type & AP_NETWORK) ?
bcast_mac : vif->bssid,
0, NULL, 0);
@@ -498,10 +498,8 @@ void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
ath6kl_reset_device(ar, ar->target_type, true, true);
}

-static void ath6kl_install_static_wep_keys(struct ath6kl *ar)
+static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
u8 index;
u8 keyusage;

@@ -511,7 +509,7 @@ static void ath6kl_install_static_wep_keys(struct ath6kl *ar)
if (index == vif->def_txkey_index)
keyusage |= TX_USAGE;

- ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
+ ath6kl_wmi_addkey_cmd(vif->ar->wmi, vif->fw_vif_idx,
index,
WEP_CRYPT,
keyusage,
@@ -524,13 +522,12 @@ static void ath6kl_install_static_wep_keys(struct ath6kl *ar)
}
}

-void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel)
+void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)
{
+ struct ath6kl *ar = vif->ar;
struct ath6kl_req_key *ik;
int res;
u8 key_rsc[ATH6KL_KEY_SEQ_LEN];
- /* TODO: Pass vif instead of taking it from ar */
- struct ath6kl_vif *vif = ar->vif;

ik = &ar->ap_mode_bkey;

@@ -539,7 +536,7 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel)
switch (vif->auth_mode) {
case NONE_AUTH:
if (vif->prwise_crypto == WEP_CRYPT)
- ath6kl_install_static_wep_keys(ar);
+ ath6kl_install_static_wep_keys(vif);
break;
case WPA_PSK_AUTH:
case WPA2_PSK_AUTH:
@@ -561,15 +558,16 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel)
break;
}

- ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
+ ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0);
set_bit(CONNECTED, &vif->flags);
- netif_carrier_on(ar->net_dev);
+ netif_carrier_on(vif->ndev);
}

-void ath6kl_connect_ap_mode_sta(struct ath6kl *ar, u16 aid, u8 *mac_addr,
+void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
u8 keymgmt, u8 ucipher, u8 auth,
u8 assoc_req_len, u8 *assoc_info)
{
+ struct ath6kl *ar = vif->ar;
u8 *ies = NULL, *wpa_ie = NULL, *pos;
size_t ies_len = 0;
struct station_info sinfo;
@@ -624,9 +622,9 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl *ar, u16 aid, u8 *mac_addr,
sinfo.assoc_req_ies_len = ies_len;
sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;

- cfg80211_new_sta(ar->net_dev, mac_addr, &sinfo, GFP_KERNEL);
+ cfg80211_new_sta(vif->ndev, mac_addr, &sinfo, GFP_KERNEL);

- netif_wake_queue(ar->net_dev);
+ netif_wake_queue(vif->ndev);
}

/* Functions for Tx credit handling */
@@ -916,17 +914,14 @@ void disconnect_timer_handler(unsigned long ptr)
struct ath6kl_vif *vif = netdev_priv(dev);

ath6kl_init_profile_info(vif->ar);
- ath6kl_disconnect(vif->ar, vif->fw_vif_idx);
+ ath6kl_disconnect(vif);
}

-void ath6kl_disconnect(struct ath6kl *ar, u8 if_idx)
+void ath6kl_disconnect(struct ath6kl_vif *vif)
{
- /* TODO: Pass vif instead of taking it from ar */
- struct ath6kl_vif *vif = ar->vif;
-
if (test_bit(CONNECTED, &vif->flags) ||
test_bit(CONNECT_PEND, &vif->flags)) {
- ath6kl_wmi_disconnect_cmd(ar->wmi, if_idx);
+ ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
/*
* Disconnect command is issued, clear the connect pending
* flag. The connected flag will be cleared in
@@ -971,7 +966,7 @@ void ath6kl_deep_sleep_enable(struct ath6kl *ar)
printk(KERN_WARNING "ath6kl: failed to disable scan "
"during suspend\n");

- ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED);
+ ath6kl_cfg80211_scan_complete_event(vif, -ECANCELED);

/* save the current power mode before enabling power save */
ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
@@ -1027,31 +1022,30 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
test_bit(TESTMODE, &ar->flag) ? " testmode" : "");
}

-void ath6kl_scan_complete_evt(struct ath6kl *ar, int status)
+void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status)
{
- /* TODO: Pass vif instead of taking it from ar */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;

- ath6kl_cfg80211_scan_complete_event(ar, status);
+ ath6kl_cfg80211_scan_complete_event(vif, status);

if (!ar->usr_bss_filter) {
clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
- ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
+ ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
+ NONE_BSS_FILTER, 0);
}

ath6kl_dbg(ATH6KL_DBG_WLAN_SCAN, "scan complete: %d\n", status);
}

-void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
+void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
u16 listen_int, u16 beacon_int,
enum network_type net_type, u8 beacon_ie_len,
u8 assoc_req_len, u8 assoc_resp_len,
u8 *assoc_info)
{
- /* TODO: findout vif instead of taking it from ar */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;

- ath6kl_cfg80211_connect_event(ar, channel, bssid,
+ ath6kl_cfg80211_connect_event(vif, channel, bssid,
listen_int, beacon_int,
net_type, beacon_ie_len,
assoc_req_len, assoc_resp_len,
@@ -1065,13 +1059,13 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
ar->listen_intvl_t,
ar->listen_intvl_b);

- netif_wake_queue(ar->net_dev);
+ netif_wake_queue(vif->ndev);

/* Update connect & link status atomically */
spin_lock_bh(&ar->lock);
set_bit(CONNECTED, &vif->flags);
clear_bit(CONNECT_PEND, &vif->flags);
- netif_carrier_on(ar->net_dev);
+ netif_carrier_on(vif->ndev);
spin_unlock_bh(&ar->lock);

aggr_reset_state(vif->aggr_cntxt);
@@ -1085,16 +1079,17 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,

if (!ar->usr_bss_filter) {
set_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
- ath6kl_wmi_bssfilter_cmd(ar->wmi, CURRENT_BSS_FILTER, 0);
+ ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
+ CURRENT_BSS_FILTER, 0);
}
}

-void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast)
+void ath6kl_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid, bool ismcast)
{
struct ath6kl_sta *sta;
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;
u8 tsc[6];
+
/*
* For AP case, keyid will have aid of STA which sent pkt with
* MIC error. Use this aid to get MAC & send it to hostapd.
@@ -1108,20 +1103,19 @@ void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast)
"ap tkip mic error received from aid=%d\n", keyid);

memset(tsc, 0, sizeof(tsc)); /* FIX: get correct TSC */
- cfg80211_michael_mic_failure(ar->net_dev, sta->mac,
+ cfg80211_michael_mic_failure(vif->ndev, sta->mac,
NL80211_KEYTYPE_PAIRWISE, keyid,
tsc, GFP_KERNEL);
} else
- ath6kl_cfg80211_tkip_micerr_event(ar, keyid, ismcast);
+ ath6kl_cfg80211_tkip_micerr_event(vif, keyid, ismcast);

}

-static void ath6kl_update_target_stats(struct ath6kl *ar, u8 *ptr, u32 len)
+static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
{
struct wmi_target_stats *tgt_stats =
(struct wmi_target_stats *) ptr;
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;
struct target_stats *stats = &vif->target_stats;
struct tkip_ccmp_stats *ccmp_stats;
u8 ac;
@@ -1229,13 +1223,12 @@ static void ath6kl_add_le32(__le32 *var, __le32 val)
*var = cpu_to_le32(le32_to_cpu(*var) + le32_to_cpu(val));
}

-void ath6kl_tgt_stats_event(struct ath6kl *ar, u8 *ptr, u32 len)
+void ath6kl_tgt_stats_event(struct ath6kl_vif *vif, u8 *ptr, u32 len)
{
struct wmi_ap_mode_stat *p = (struct wmi_ap_mode_stat *) ptr;
+ struct ath6kl *ar = vif->ar;
struct wmi_ap_mode_stat *ap = &ar->ap_stats;
struct wmi_per_sta_stat *st_ap, *st_p;
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
u8 ac;

if (vif->nw_type == AP_NETWORK) {
@@ -1257,7 +1250,7 @@ void ath6kl_tgt_stats_event(struct ath6kl *ar, u8 *ptr, u32 len)
}

} else {
- ath6kl_update_target_stats(ar, ptr, len);
+ ath6kl_update_target_stats(vif, ptr, len);
}
}

@@ -1276,13 +1269,12 @@ void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr)
wake_up(&ar->event_wq);
}

-void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid)
+void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid)
{
struct ath6kl_sta *conn;
struct sk_buff *skb;
bool psq_empty = false;
- /* TODO: Pass vif instead of taking it from ar */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;

conn = ath6kl_find_sta_by_aid(ar, aid);

@@ -1305,7 +1297,7 @@ void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid)
spin_unlock_bh(&conn->psq_lock);

conn->sta_flags |= STA_PS_POLLED;
- ath6kl_data_tx(skb, ar->net_dev);
+ ath6kl_data_tx(skb, vif->ndev);
conn->sta_flags &= ~STA_PS_POLLED;

spin_lock_bh(&conn->psq_lock);
@@ -1316,12 +1308,11 @@ void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid)
ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, conn->aid, 0);
}

-void ath6kl_dtimexpiry_event(struct ath6kl *ar)
+void ath6kl_dtimexpiry_event(struct ath6kl_vif *vif)
{
bool mcastq_empty = false;
struct sk_buff *skb;
- /* TODO: Pass vif instead of taking it from ar */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;

/*
* If there are no associated STAs, ignore the DTIM expiry event.
@@ -1349,7 +1340,7 @@ void ath6kl_dtimexpiry_event(struct ath6kl *ar)
while ((skb = skb_dequeue(&ar->mcastpsq)) != NULL) {
spin_unlock_bh(&ar->mcastpsq_lock);

- ath6kl_data_tx(skb, ar->net_dev);
+ ath6kl_data_tx(skb, vif->ndev);

spin_lock_bh(&ar->mcastpsq_lock);
}
@@ -1361,12 +1352,11 @@ void ath6kl_dtimexpiry_event(struct ath6kl *ar)
ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, MCAST_AID, 0);
}

-void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
+void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
u8 assoc_resp_len, u8 *assoc_info,
u16 prot_reason_status)
{
- /* TODO: Findout vif instead of taking it from ar */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;

if (vif->nw_type == AP_NETWORK) {
if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))
@@ -1386,17 +1376,17 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,

if (!is_broadcast_ether_addr(bssid)) {
/* send event to application */
- cfg80211_del_sta(ar->net_dev, bssid, GFP_KERNEL);
+ cfg80211_del_sta(vif->ndev, bssid, GFP_KERNEL);
}

- if (memcmp(ar->net_dev->dev_addr, bssid, ETH_ALEN) == 0) {
+ if (memcmp(vif->ndev->dev_addr, bssid, ETH_ALEN) == 0) {
memset(vif->wep_key_list, 0, sizeof(vif->wep_key_list));
clear_bit(CONNECTED, &vif->flags);
}
return;
}

- ath6kl_cfg80211_disconnect_event(ar, reason, bssid,
+ ath6kl_cfg80211_disconnect_event(vif, reason, bssid,
assoc_resp_len, assoc_info,
prot_reason_status);

@@ -1414,7 +1404,8 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
*/
if (reason == DISCONNECT_CMD) {
if (!ar->usr_bss_filter && test_bit(WMI_READY, &ar->flag))
- ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
+ ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
+ NONE_BSS_FILTER, 0);
} else {
set_bit(CONNECT_PEND, &vif->flags);
if (((reason == ASSOC_FAILED) &&
@@ -1429,7 +1420,7 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
/* update connect & link status atomically */
spin_lock_bh(&ar->lock);
clear_bit(CONNECTED, &vif->flags);
- netif_carrier_off(ar->net_dev);
+ netif_carrier_off(vif->ndev);
spin_unlock_bh(&ar->lock);

if ((reason != CSERV_DISCONNECT) || (vif->reconnect_flag != 1))
@@ -1438,7 +1429,7 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
if (reason != CSERV_DISCONNECT)
ar->user_key_ctrl = 0;

- netif_stop_queue(ar->net_dev);
+ netif_stop_queue(vif->ndev);
memset(vif->bssid, 0, sizeof(vif->bssid));
vif->bss_ch = 0;

@@ -1472,7 +1463,7 @@ static int ath6kl_close(struct net_device *dev)

netif_stop_queue(dev);

- ath6kl_disconnect(ar, vif->fw_vif_idx);
+ ath6kl_disconnect(vif);

if (test_bit(WMI_READY, &ar->flag)) {
if (ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0xFFFF,
@@ -1482,7 +1473,7 @@ static int ath6kl_close(struct net_device *dev)
clear_bit(WLAN_ENABLED, &vif->flags);
}

- ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED);
+ ath6kl_cfg80211_scan_complete_event(vif, -ECANCELED);

return 0;
}
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index c54f1a9..50ff9a4 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -287,7 +287,8 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
chk_adhoc_ps_mapping = true;
else {
/* get the stream mapping */
- ret = ath6kl_wmi_implicit_create_pstream(ar->wmi, skb,
+ ret = ath6kl_wmi_implicit_create_pstream(ar->wmi,
+ vif->fw_vif_idx, skb,
0, test_bit(WMM_ENABLED, &vif->flags), &ac);
if (ret)
goto fail_tx;
@@ -1354,10 +1355,9 @@ static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
memset(stats, 0, sizeof(struct rxtid_stats));
}

-void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no, u8 win_sz)
+void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no,
+ u8 win_sz)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
struct aggr_info *p_aggr = vif->aggr_cntxt;
struct rxtid *rxtid;
struct rxtid_stats *stats;
@@ -1425,10 +1425,8 @@ struct aggr_info *aggr_init(struct net_device *dev)
return p_aggr;
}

-void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid)
+void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
struct aggr_info *p_aggr = vif->aggr_cntxt;
struct rxtid *rxtid;

diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index a4ad7cb..ed092b7 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -21,7 +21,7 @@
#include "../regd.h"
#include "../regd_common.h"

-static int ath6kl_wmi_sync_point(struct wmi *wmi);
+static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx);

static const s32 wmi_rate_tbl[][2] = {
/* {W/O SGI, with SGI} */
@@ -81,6 +81,14 @@ enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi)
return wmi->ep_id;
}

+static struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx)
+{
+ if (WARN_ON(if_idx > (MAX_NUM_VIF - 1)))
+ return NULL;
+
+ return ar->vif;
+}
+
/* Performs DIX to 802.3 encapsulation for transmit packets.
* Assumes the entire DIX header is contigous and that there is
* enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
@@ -216,7 +224,8 @@ static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
return ip_pri;
}

-int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb,
+int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx,
+ struct sk_buff *skb,
u32 layer2_priority, bool wmm_enabled,
u8 *ac)
{
@@ -289,7 +298,7 @@ int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb,
cpu_to_le32(WMI_IMPLICIT_PSTREAM_INACTIVITY_INT);
/* Implicit streams are created with TSID 0xFF */
cmd.tsid = WMI_IMPLICIT_PSTREAM;
- ath6kl_wmi_create_pstream_cmd(wmi, &cmd);
+ ath6kl_wmi_create_pstream_cmd(wmi, if_idx, &cmd);
}

*ac = traffic_class;
@@ -415,7 +424,7 @@ static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len)
}

static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap,
- int len)
+ int len, struct ath6kl_vif *vif)
{
struct wmi_remain_on_chnl_event *ev;
u32 freq;
@@ -437,14 +446,15 @@ static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap,
"(freq=%u)\n", freq);
return -EINVAL;
}
- cfg80211_ready_on_channel(ar->net_dev, 1, chan, NL80211_CHAN_NO_HT,
+ cfg80211_ready_on_channel(vif->ndev, 1, chan, NL80211_CHAN_NO_HT,
dur, GFP_ATOMIC);

return 0;
}

static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi,
- u8 *datap, int len)
+ u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
struct wmi_cancel_remain_on_chnl_event *ev;
u32 freq;
@@ -466,17 +476,17 @@ static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi,
"channel (freq=%u)\n", freq);
return -EINVAL;
}
- cfg80211_remain_on_channel_expired(ar->net_dev, 1, chan,
+ cfg80211_remain_on_channel_expired(vif->ndev, 1, chan,
NL80211_CHAN_NO_HT, GFP_ATOMIC);

return 0;
}

-static int ath6kl_wmi_tx_status_event_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_tx_status_event_rx(struct wmi *wmi, u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
struct wmi_tx_status_event *ev;
u32 id;
- struct ath6kl *ar = wmi->parent_dev;

if (len < sizeof(*ev))
return -EINVAL;
@@ -486,7 +496,7 @@ static int ath6kl_wmi_tx_status_event_rx(struct wmi *wmi, u8 *datap, int len)
ath6kl_dbg(ATH6KL_DBG_WMI, "tx_status: id=%x ack_status=%u\n",
id, ev->ack_status);
if (wmi->last_mgmt_tx_frame) {
- cfg80211_mgmt_tx_status(ar->net_dev, id,
+ cfg80211_mgmt_tx_status(vif->ndev, id,
wmi->last_mgmt_tx_frame,
wmi->last_mgmt_tx_frame_len,
!!ev->ack_status, GFP_ATOMIC);
@@ -498,14 +508,12 @@ static int ath6kl_wmi_tx_status_event_rx(struct wmi *wmi, u8 *datap, int len)
return 0;
}

-static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
struct wmi_p2p_rx_probe_req_event *ev;
u32 freq;
u16 dlen;
- struct ath6kl *ar = wmi->parent_dev;
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;

if (len < sizeof(*ev))
return -EINVAL;
@@ -523,7 +531,7 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len)
dlen, freq, vif->probe_req_report);

if (vif->probe_req_report || vif->nw_type == AP_NETWORK)
- cfg80211_rx_mgmt(ar->net_dev, freq, ev->data, dlen, GFP_ATOMIC);
+ cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC);

return 0;
}
@@ -543,12 +551,12 @@ static int ath6kl_wmi_p2p_capabilities_event_rx(u8 *datap, int len)
return 0;
}

-static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
struct wmi_rx_action_event *ev;
u32 freq;
u16 dlen;
- struct ath6kl *ar = wmi->parent_dev;

if (len < sizeof(*ev))
return -EINVAL;
@@ -562,7 +570,7 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len)
return -EINVAL;
}
ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq);
- cfg80211_rx_mgmt(ar->net_dev, freq, ev->data, dlen, GFP_ATOMIC);
+ cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC);

return 0;
}
@@ -726,13 +734,11 @@ int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode)
NO_SYNC_WMIFLAG);
}

-static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
struct wmi_connect_event *ev;
u8 *pie, *peie;
- struct ath6kl *ar = wmi->parent_dev;
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;

if (len < sizeof(struct wmi_connect_event))
return -EINVAL;
@@ -741,14 +747,14 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len)

if (vif->nw_type == AP_NETWORK) {
/* AP mode start/STA connected event */
- struct net_device *dev = ar->net_dev;
+ struct net_device *dev = vif->ndev;
if (memcmp(dev->dev_addr, ev->u.ap_bss.bssid, ETH_ALEN) == 0) {
ath6kl_dbg(ATH6KL_DBG_WMI, "%s: freq %d bssid %pM "
"(AP started)\n",
__func__, le16_to_cpu(ev->u.ap_bss.ch),
ev->u.ap_bss.bssid);
ath6kl_connect_ap_mode_bss(
- ar, le16_to_cpu(ev->u.ap_bss.ch));
+ vif, le16_to_cpu(ev->u.ap_bss.ch));
} else {
ath6kl_dbg(ATH6KL_DBG_WMI, "%s: aid %u mac_addr %pM "
"auth=%u keymgmt=%u cipher=%u apsd_info=%u "
@@ -760,7 +766,7 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len)
le16_to_cpu(ev->u.ap_sta.cipher),
ev->u.ap_sta.apsd_info);
ath6kl_connect_ap_mode_sta(
- ar, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr,
+ vif, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr,
ev->u.ap_sta.keymgmt,
le16_to_cpu(ev->u.ap_sta.cipher),
ev->u.ap_sta.auth, ev->assoc_req_len,
@@ -805,7 +811,7 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len)
pie += pie[1] + 2;
}

- ath6kl_connect_event(wmi->parent_dev, le16_to_cpu(ev->u.sta.ch),
+ ath6kl_connect_event(vif, le16_to_cpu(ev->u.sta.ch),
ev->u.sta.bssid,
le16_to_cpu(ev->u.sta.listen_intvl),
le16_to_cpu(ev->u.sta.beacon_intvl),
@@ -891,7 +897,8 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
}
}

-static int ath6kl_wmi_disconnect_event_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_disconnect_event_rx(struct wmi *wmi, u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
struct wmi_disconnect_event *ev;
wmi->traffic_class = 100;
@@ -908,7 +915,7 @@ static int ath6kl_wmi_disconnect_event_rx(struct wmi *wmi, u8 *datap, int len)

wmi->is_wmm_enabled = false;

- ath6kl_disconnect_event(wmi->parent_dev, ev->disconn_reason,
+ ath6kl_disconnect_event(vif, ev->disconn_reason,
ev->bssid, ev->assoc_resp_len, ev->assoc_info,
le16_to_cpu(ev->proto_reason_status));

@@ -934,7 +941,8 @@ static int ath6kl_wmi_peer_node_event_rx(struct wmi *wmi, u8 *datap, int len)
return 0;
}

-static int ath6kl_wmi_tkip_micerr_event_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_tkip_micerr_event_rx(struct wmi *wmi, u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
struct wmi_tkip_micerr_event *ev;

@@ -943,12 +951,13 @@ static int ath6kl_wmi_tkip_micerr_event_rx(struct wmi *wmi, u8 *datap, int len)

ev = (struct wmi_tkip_micerr_event *) datap;

- ath6kl_tkip_micerr_event(wmi->parent_dev, ev->key_id, ev->is_mcast);
+ ath6kl_tkip_micerr_event(vif, ev->key_id, ev->is_mcast);

return 0;
}

-static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
struct wmi_bss_info_hdr2 *bih;
u8 *buf;
@@ -956,8 +965,6 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
struct ath6kl *ar = wmi->parent_dev;
struct ieee80211_mgmt *mgmt;
struct cfg80211_bss *bss;
- /*TODO: Findout vif properly */
- struct ath6kl_vif *vif = ar->vif;

if (len <= sizeof(struct wmi_bss_info_hdr2))
return -EINVAL;
@@ -979,7 +986,8 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
if (bih->frame_type == BEACON_FTYPE &&
test_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags)) {
clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
- ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
+ ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
+ NONE_BSS_FILTER, 0);
}

channel = ieee80211_get_channel(ar->wiphy, le16_to_cpu(bih->ch));
@@ -1016,7 +1024,7 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
IEEE80211_STYPE_BEACON);
memset(mgmt->da, 0xff, ETH_ALEN);
} else {
- struct net_device *dev = ar->net_dev;
+ struct net_device *dev = vif->ndev;

mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_PROBE_RESP);
@@ -1144,20 +1152,21 @@ static int ath6kl_wmi_keepalive_reply_rx(struct wmi *wmi, u8 *datap, int len)
return 0;
}

-static int ath6kl_wmi_scan_complete_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_scan_complete_rx(struct wmi *wmi, u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
struct wmi_scan_complete_event *ev;

ev = (struct wmi_scan_complete_event *) datap;

- ath6kl_scan_complete_evt(wmi->parent_dev, a_sle32_to_cpu(ev->status));
+ ath6kl_scan_complete_evt(vif, a_sle32_to_cpu(ev->status));
wmi->is_probe_ssid = false;

return 0;
}

static int ath6kl_wmi_neighbor_report_event_rx(struct wmi *wmi, u8 *datap,
- int len)
+ int len, struct ath6kl_vif *vif)
{
struct wmi_neighbor_report_event *ev;
u8 i;
@@ -1175,7 +1184,7 @@ static int ath6kl_wmi_neighbor_report_event_rx(struct wmi *wmi, u8 *datap,
ath6kl_dbg(ATH6KL_DBG_WMI, "neighbor %d/%d - %pM 0x%x\n",
i + 1, ev->num_neighbors, ev->neighbor[i].bssid,
ev->neighbor[i].bss_flags);
- cfg80211_pmksa_candidate_notify(wmi->parent_dev->net_dev, i,
+ cfg80211_pmksa_candidate_notify(vif->ndev, i,
ev->neighbor[i].bssid,
!!(ev->neighbor[i].bss_flags &
WMI_PREAUTH_CAPABLE_BSS),
@@ -1216,9 +1225,10 @@ static int ath6kl_wmi_error_event_rx(struct wmi *wmi, u8 *datap, int len)
return 0;
}

-static int ath6kl_wmi_stats_event_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_stats_event_rx(struct wmi *wmi, u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
- ath6kl_tgt_stats_event(wmi->parent_dev, datap, len);
+ ath6kl_tgt_stats_event(vif, datap, len);

return 0;
}
@@ -1372,7 +1382,8 @@ static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap,
return 0;
}

-static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
struct wmi_cac_event *reply;
struct ieee80211_tspec_ie *ts;
@@ -1393,7 +1404,8 @@ static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len)
tsid = (tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) &
IEEE80211_WMM_IE_TSPEC_TID_MASK;

- ath6kl_wmi_delete_pstream_cmd(wmi, reply->ac, tsid);
+ ath6kl_wmi_delete_pstream_cmd(wmi, vif->fw_vif_idx,
+ reply->ac, tsid);
} else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
/*
* Following assumes that there is only one outstanding
@@ -1408,7 +1420,8 @@ static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len)
break;
}
if (index < (sizeof(active_tsids) * 8))
- ath6kl_wmi_delete_pstream_cmd(wmi, reply->ac, index);
+ ath6kl_wmi_delete_pstream_cmd(wmi, vif->fw_vif_idx,
+ reply->ac, index);
}

/*
@@ -1605,7 +1618,7 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb,
* Make sure all data currently queued is transmitted before
* the cmd execution. Establish a new sync point.
*/
- ath6kl_wmi_sync_point(wmi);
+ ath6kl_wmi_sync_point(wmi, if_idx);
}

skb_push(skb, sizeof(struct wmi_cmd_hdr));
@@ -1634,7 +1647,7 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb,
* Make sure all new data queued waits for the command to
* execute. Establish a new sync point.
*/
- ath6kl_wmi_sync_point(wmi);
+ ath6kl_wmi_sync_point(wmi, if_idx);
}

return 0;
@@ -1816,7 +1829,7 @@ int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx,
return ret;
}

-int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 filter, u32 ie_mask)
+int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 if_idx, u8 filter, u32 ie_mask)
{
struct sk_buff *skb;
struct wmi_bss_filter_cmd *cmd;
@@ -1833,7 +1846,7 @@ int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 filter, u32 ie_mask)
cmd->bss_filter = filter;
cmd->ie_mask = cpu_to_le32(ie_mask);

- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_BSS_FILTER_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_BSS_FILTER_CMDID,
NO_SYNC_WMIFLAG);
return ret;
}
@@ -2010,7 +2023,7 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index,
return ret;
}

-int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 *krk)
+int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, u8 *krk)
{
struct sk_buff *skb;
struct wmi_add_krk_cmd *cmd;
@@ -2023,7 +2036,7 @@ int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 *krk)
cmd = (struct wmi_add_krk_cmd *) skb->data;
memcpy(cmd->krk, krk, WMI_KRK_LEN);

- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_ADD_KRK_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_ADD_KRK_CMDID,
NO_SYNC_WMIFLAG);

return ret;
@@ -2104,7 +2117,7 @@ static int ath6kl_wmi_data_sync_send(struct wmi *wmi, struct sk_buff *skb,
return ret;
}

-static int ath6kl_wmi_sync_point(struct wmi *wmi)
+static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
{
struct sk_buff *skb;
struct wmi_sync_cmd *cmd;
@@ -2160,7 +2173,7 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi)
* Send sync cmd followed by sync data messages on all
* endpoints being used
*/
- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SYNCHRONIZE_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SYNCHRONIZE_CMDID,
NO_SYNC_WMIFLAG);

if (ret)
@@ -2202,7 +2215,7 @@ free_skb:
return ret;
}

-int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi,
+int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi, u8 if_idx,
struct wmi_create_pstream_cmd *params)
{
struct sk_buff *skb;
@@ -2291,12 +2304,13 @@ int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi,
ath6kl_indicate_tx_activity(wmi->parent_dev,
params->traffic_class, true);

- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_CREATE_PSTREAM_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_CREATE_PSTREAM_CMDID,
NO_SYNC_WMIFLAG);
return ret;
}

-int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 traffic_class, u8 tsid)
+int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 if_idx, u8 traffic_class,
+ u8 tsid)
{
struct sk_buff *skb;
struct wmi_delete_pstream_cmd *cmd;
@@ -2332,7 +2346,7 @@ int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 traffic_class, u8 tsid)
"sending delete_pstream_cmd: traffic class: %d tsid=%d\n",
traffic_class, tsid);

- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_DELETE_PSTREAM_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_DELETE_PSTREAM_CMDID,
SYNC_BEFORE_WMIFLAG);

spin_lock_bh(&wmi->lock);
@@ -2598,21 +2612,23 @@ static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
return 0;
}

-static int ath6kl_wmi_addba_req_event_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_addba_req_event_rx(struct wmi *wmi, u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
struct wmi_addba_req_event *cmd = (struct wmi_addba_req_event *) datap;

- aggr_recv_addba_req_evt(wmi->parent_dev, cmd->tid,
+ aggr_recv_addba_req_evt(vif, cmd->tid,
le16_to_cpu(cmd->st_seq_no), cmd->win_sz);

return 0;
}

-static int ath6kl_wmi_delba_req_event_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_delba_req_event_rx(struct wmi *wmi, u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
struct wmi_delba_event *cmd = (struct wmi_delba_event *) datap;

- aggr_recv_delba_req_evt(wmi->parent_dev, cmd->tid);
+ aggr_recv_delba_req_evt(vif, cmd->tid);

return 0;
}
@@ -2661,7 +2677,8 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac,
NO_SYNC_WMIFLAG);
}

-static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
struct wmi_pspoll_event *ev;

@@ -2670,14 +2687,15 @@ static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len)

ev = (struct wmi_pspoll_event *) datap;

- ath6kl_pspoll_event(wmi->parent_dev, le16_to_cpu(ev->aid));
+ ath6kl_pspoll_event(vif, le16_to_cpu(ev->aid));

return 0;
}

-static int ath6kl_wmi_dtimexpiry_event_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_dtimexpiry_event_rx(struct wmi *wmi, u8 *datap, int len,
+ struct ath6kl_vif *vif)
{
- ath6kl_dtimexpiry_event(wmi->parent_dev);
+ ath6kl_dtimexpiry_event(vif);

return 0;
}
@@ -2930,8 +2948,10 @@ static int ath6kl_wmi_roam_tbl_event_rx(struct wmi *wmi, u8 *datap, int len)
int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
{
struct wmi_cmd_hdr *cmd;
+ struct ath6kl_vif *vif;
u32 len;
u16 id;
+ u8 if_idx;
u8 *datap;
int ret = 0;

@@ -2946,6 +2966,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)

cmd = (struct wmi_cmd_hdr *) skb->data;
id = le16_to_cpu(cmd->cmd_id);
+ if_idx = le16_to_cpu(cmd->info1) & WMI_CMD_HDR_IF_ID_MASK;

skb_pull(skb, sizeof(struct wmi_cmd_hdr));

@@ -2956,6 +2977,15 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi rx ",
datap, len);

+ vif = ath6kl_get_vif_by_index(wmi->parent_dev, if_idx);
+ if (!vif) {
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "Wmi event for unavailable vif, vif_index:%d\n",
+ if_idx);
+ dev_kfree_skb(skb);
+ return -EINVAL;
+ }
+
switch (id) {
case WMI_GET_BITRATE_CMDID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_BITRATE_CMDID\n");
@@ -2975,11 +3005,11 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
break;
case WMI_CONNECT_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n");
- ret = ath6kl_wmi_connect_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_connect_event_rx(wmi, datap, len, vif);
break;
case WMI_DISCONNECT_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n");
- ret = ath6kl_wmi_disconnect_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_disconnect_event_rx(wmi, datap, len, vif);
break;
case WMI_PEER_NODE_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PEER_NODE_EVENTID\n");
@@ -2987,11 +3017,11 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
break;
case WMI_TKIP_MICERR_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n");
- ret = ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len, vif);
break;
case WMI_BSSINFO_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n");
- ret = ath6kl_wmi_bssinfo_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_bssinfo_event_rx(wmi, datap, len, vif);
break;
case WMI_REGDOMAIN_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n");
@@ -3003,11 +3033,12 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
break;
case WMI_NEIGHBOR_REPORT_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n");
- ret = ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len,
+ vif);
break;
case WMI_SCAN_COMPLETE_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n");
- ret = ath6kl_wmi_scan_complete_rx(wmi, datap, len);
+ ret = ath6kl_wmi_scan_complete_rx(wmi, datap, len, vif);
break;
case WMI_CMDERROR_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CMDERROR_EVENTID\n");
@@ -3015,7 +3046,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
break;
case WMI_REPORT_STATISTICS_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n");
- ret = ath6kl_wmi_stats_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_stats_event_rx(wmi, datap, len, vif);
break;
case WMI_RSSI_THRESHOLD_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RSSI_THRESHOLD_EVENTID\n");
@@ -3038,7 +3069,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
break;
case WMI_CAC_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n");
- ret = ath6kl_wmi_cac_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_cac_event_rx(wmi, datap, len, vif);
break;
case WMI_CHANNEL_CHANGE_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CHANNEL_CHANGE_EVENTID\n");
@@ -3082,25 +3113,25 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
break;
case WMI_PSPOLL_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n");
- ret = ath6kl_wmi_pspoll_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_pspoll_event_rx(wmi, datap, len, vif);
break;
case WMI_DTIMEXPIRY_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n");
- ret = ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len, vif);
break;
case WMI_SET_PARAMS_REPLY_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_PARAMS_REPLY_EVENTID\n");
break;
case WMI_ADDBA_REQ_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n");
- ret = ath6kl_wmi_addba_req_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_addba_req_event_rx(wmi, datap, len, vif);
break;
case WMI_ADDBA_RESP_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_RESP_EVENTID\n");
break;
case WMI_DELBA_REQ_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n");
- ret = ath6kl_wmi_delba_req_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_delba_req_event_rx(wmi, datap, len, vif);
break;
case WMI_REPORT_BTCOEX_CONFIG_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI,
@@ -3116,21 +3147,21 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
break;
case WMI_REMAIN_ON_CHNL_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n");
- ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif);
break;
case WMI_CANCEL_REMAIN_ON_CHNL_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI,
"WMI_CANCEL_REMAIN_ON_CHNL_EVENTID\n");
ret = ath6kl_wmi_cancel_remain_on_chnl_event_rx(wmi, datap,
- len);
+ len, vif);
break;
case WMI_TX_STATUS_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_STATUS_EVENTID\n");
- ret = ath6kl_wmi_tx_status_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_tx_status_event_rx(wmi, datap, len, vif);
break;
case WMI_RX_PROBE_REQ_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_PROBE_REQ_EVENTID\n");
- ret = ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len, vif);
break;
case WMI_P2P_CAPABILITIES_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_CAPABILITIES_EVENTID\n");
@@ -3138,7 +3169,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
break;
case WMI_RX_ACTION_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n");
- ret = ath6kl_wmi_rx_action_event_rx(wmi, datap, len);
+ ret = ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif);
break;
case WMI_P2P_INFO_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_INFO_EVENTID\n");
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 83bf46c..d2c9510 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -2171,9 +2171,9 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,

int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb);
-int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb,
- u32 layer2_priority, bool wmm_enabled,
- u8 *ac);
+int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx,
+ struct sk_buff *skb, u32 layer2_priority,
+ bool wmm_enabled, u8 *ac);

int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb);

@@ -2204,7 +2204,8 @@ int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx, u16 fg_start_sec,
u16 pas_chdw_msec, u8 short_scan_ratio,
u8 scan_ctrl_flag, u32 max_dfsch_act_time,
u16 maxact_scan_per_ssid);
-int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 filter, u32 ie_mask);
+int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 if_idx, u8 filter,
+ u32 ie_mask);
int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag,
u8 ssid_len, u8 *ssid);
int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx,
@@ -2216,9 +2217,10 @@ int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u16 idle_period,
u16 tx_wakup_policy, u16 num_tx_to_wakeup,
u16 ps_fail_event_policy);
int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 timeout);
-int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi,
+int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi, u8 if_idx,
struct wmi_create_pstream_cmd *pstream);
-int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 traffic_class, u8 tsid);
+int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 if_idx, u8 traffic_class,
+ u8 tsid);

int ath6kl_wmi_set_rts_cmd(struct wmi *wmi, u16 threshold);
int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status,
@@ -2234,7 +2236,7 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index,
u8 *key_rsc, u8 *key_material,
u8 key_op_ctrl, u8 *mac_addr,
enum wmi_sync_flag sync_flag);
-int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 *krk);
+int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, u8 *krk);
int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index);
int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, u8 if_idx, const u8 *bssid,
const u8 *pmkid, bool set);
--
1.7.0.4


Subject: [PATCH V2 23/31] ath6kl: Store hw mac address in struct ath6kl

WMI ready event gives the mac address, cache this
mac address in struct ath6kl so that it can be used to
compute the mac address for other vif in case of multi vif.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/core.h | 1 +
drivers/net/wireless/ath/ath6kl/init.c | 12 ++++++++++--
drivers/net/wireless/ath/ath6kl/main.c | 5 ++---
3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 466f6e1..747e5a7 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -492,6 +492,7 @@ struct ath6kl {
struct wireless_dev *wdev;
enum wlan_low_pwr_state wlan_pwr_state;
struct wmi_scan_params_cmd sc_params;
+ u8 mac_addr[ETH_ALEN];
#define AR_MCAST_FILTER_MAC_ADDR_SIZE 4
struct {
void *rx_report;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index c5170c3..bafb30d 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1503,8 +1503,16 @@ static int ath6kl_init(struct ath6kl *ar)
ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;

status = ath6kl_target_config_wlan_params(ar);
- if (!status)
- goto ath6kl_init_done;
+ if (status)
+ goto err_htc_stop;
+
+ /*
+ * Set mac address which is received in ready event
+ * FIXME: Move to ath6kl_interface_add()
+ */
+ memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
+
+ return status;

err_htc_stop:
ath6kl_htc_stop(ar->htc_target);
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index cc3e3c8..6bf9402 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -923,11 +923,10 @@ static const char *get_hw_id_string(u32 id)
void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
{
struct ath6kl *ar = devt;
- struct net_device *dev = ar->vif->ndev;

- memcpy(dev->dev_addr, datap, ETH_ALEN);
+ memcpy(ar->mac_addr, datap, ETH_ALEN);
ath6kl_dbg(ATH6KL_DBG_TRC, "%s: mac addr = %pM\n",
- __func__, dev->dev_addr);
+ __func__, ar->mac_addr);

ar->version.wlan_ver = sw_ver;
ar->version.abi_ver = abi_ver;
--
1.7.0.4


2011-10-26 08:25:03

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH V2 00/31] ath6kl Add multiple vif support

On 10/25/2011 05:03 PM, Vasanthakumar Thiagarajan wrote:
> This patch set adds basic infrastructure for multiple
> virtual interface. As configuring the firmware with more than one
> vif causes random target assert, the number of supported vifs is
> restricted to 1 for now. I would like to thank Vivek Natarajan
> ([email protected]) for his inital work in this area and
> Arthi Thiruvengadam ([email protected]) for finding some
> critical bugs.

Thanks, app patches applied. But please do take a look at the lockdep
warning I saw.

Kalle

Subject: [PATCH V2 16/31] ath6kl: Make net and target stats vif specific

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 20 ++++++++++----------
drivers/net/wireless/ath/ath6kl/core.h | 6 +++---
drivers/net/wireless/ath/ath6kl/debug.c | 8 +++++---
drivers/net/wireless/ath/ath6kl/main.c | 12 +++++++-----
drivers/net/wireless/ath/ath6kl/txrx.c | 20 ++++++++++----------
5 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index fa206be..55e4c92 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1414,7 +1414,7 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
if (down_interruptible(&ar->sem))
return -EBUSY;

- set_bit(STATS_UPDATE_PEND, &ar->flag);
+ set_bit(STATS_UPDATE_PEND, &vif->flags);

ret = ath6kl_wmi_get_stats_cmd(ar->wmi);

@@ -1425,7 +1425,7 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,

left = wait_event_interruptible_timeout(ar->event_wq,
!test_bit(STATS_UPDATE_PEND,
- &ar->flag),
+ &vif->flags),
WMI_TIMEOUT);

up(&ar->sem);
@@ -1435,24 +1435,24 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
else if (left < 0)
return left;

- if (ar->target_stats.rx_byte) {
- sinfo->rx_bytes = ar->target_stats.rx_byte;
+ if (vif->target_stats.rx_byte) {
+ sinfo->rx_bytes = vif->target_stats.rx_byte;
sinfo->filled |= STATION_INFO_RX_BYTES;
- sinfo->rx_packets = ar->target_stats.rx_pkt;
+ sinfo->rx_packets = vif->target_stats.rx_pkt;
sinfo->filled |= STATION_INFO_RX_PACKETS;
}

- if (ar->target_stats.tx_byte) {
- sinfo->tx_bytes = ar->target_stats.tx_byte;
+ if (vif->target_stats.tx_byte) {
+ sinfo->tx_bytes = vif->target_stats.tx_byte;
sinfo->filled |= STATION_INFO_TX_BYTES;
- sinfo->tx_packets = ar->target_stats.tx_pkt;
+ sinfo->tx_packets = vif->target_stats.tx_pkt;
sinfo->filled |= STATION_INFO_TX_PACKETS;
}

- sinfo->signal = ar->target_stats.cs_rssi;
+ sinfo->signal = vif->target_stats.cs_rssi;
sinfo->filled |= STATION_INFO_SIGNAL;

- rate = ar->target_stats.tx_ucast_rate;
+ rate = vif->target_stats.tx_ucast_rate;

if (is_rate_legacy(rate)) {
sinfo->txrate.legacy = rate / 100;
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index ba780eb..41d6ae0 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -391,6 +391,7 @@ enum ath6kl_vif_state {
CLEAR_BSSFILTER_ON_BEACON,
DTIM_PERIOD_AVAIL,
WLAN_ENABLED,
+ STATS_UPDATE_PEND,
};

struct ath6kl_vif {
@@ -425,6 +426,8 @@ struct ath6kl_vif {
u16 next_chan;
u16 assoc_bss_beacon_int;
u8 assoc_bss_dtim_period;
+ struct net_device_stats net_stats;
+ struct target_stats target_stats;
};

/* Flag info */
@@ -435,7 +438,6 @@ enum ath6kl_dev_state {
TESTMODE,
DESTROY_IN_PROGRESS,
SKIP_SCAN,
- STATS_UPDATE_PEND,
ROAM_TBL_PEND,
};

@@ -459,8 +461,6 @@ struct ath6kl {
struct ath6kl_version version;
u32 target_type;
u8 tx_pwr;
- struct net_device_stats net_stats;
- struct target_stats target_stats;
struct ath6kl_node_mapping node_map[MAX_NODE_NUM];
u8 ibss_ps_enable;
u8 node_num;
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index f067c7b..9a89b42 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -397,7 +397,9 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath6kl *ar = file->private_data;
- struct target_stats *tgt_stats = &ar->target_stats;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
+ struct target_stats *tgt_stats = &vif->target_stats;
char *buf;
unsigned int len = 0, buf_len = 1500;
int i;
@@ -413,7 +415,7 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
return -EBUSY;
}

- set_bit(STATS_UPDATE_PEND, &ar->flag);
+ set_bit(STATS_UPDATE_PEND, &vif->flags);

if (ath6kl_wmi_get_stats_cmd(ar->wmi)) {
up(&ar->sem);
@@ -423,7 +425,7 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,

left = wait_event_interruptible_timeout(ar->event_wq,
!test_bit(STATS_UPDATE_PEND,
- &ar->flag), WMI_TIMEOUT);
+ &vif->flags), WMI_TIMEOUT);

up(&ar->sem);

diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index b91ac7e..fff1f4a 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -1119,7 +1119,9 @@ static void ath6kl_update_target_stats(struct ath6kl *ar, u8 *ptr, u32 len)
{
struct wmi_target_stats *tgt_stats =
(struct wmi_target_stats *) ptr;
- struct target_stats *stats = &ar->target_stats;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
+ struct target_stats *stats = &vif->target_stats;
struct tkip_ccmp_stats *ccmp_stats;
u8 ac;

@@ -1215,8 +1217,8 @@ static void ath6kl_update_target_stats(struct ath6kl *ar, u8 *ptr, u32 len)
stats->wow_evt_discarded +=
le16_to_cpu(tgt_stats->wow_stats.wow_evt_discarded);

- if (test_bit(STATS_UPDATE_PEND, &ar->flag)) {
- clear_bit(STATS_UPDATE_PEND, &ar->flag);
+ if (test_bit(STATS_UPDATE_PEND, &vif->flags)) {
+ clear_bit(STATS_UPDATE_PEND, &vif->flags);
wake_up(&ar->event_wq);
}
}
@@ -1483,9 +1485,9 @@ static int ath6kl_close(struct net_device *dev)

static struct net_device_stats *ath6kl_get_stats(struct net_device *dev)
{
- struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);

- return &ar->net_stats;
+ return &vif->net_stats;
}

static struct net_device_ops ath6kl_netdev_ops = {
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index ba1678e..cada197 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -357,8 +357,8 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
fail_tx:
dev_kfree_skb(skb);

- ar->net_stats.tx_dropped++;
- ar->net_stats.tx_aborted_errors++;
+ vif->net_stats.tx_dropped++;
+ vif->net_stats.tx_aborted_errors++;

return 0;
}
@@ -583,7 +583,7 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue)
/* a packet was flushed */
flushing = true;

- ar->net_stats.tx_errors++;
+ vif->net_stats.tx_errors++;

if (status != -ENOSPC)
ath6kl_err("tx error, status: 0x%x\n", status);
@@ -598,8 +598,8 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue)
eid, "OK");

flushing = false;
- ar->net_stats.tx_packets++;
- ar->net_stats.tx_bytes += skb->len;
+ vif->net_stats.tx_packets++;
+ vif->net_stats.tx_bytes += skb->len;
}

ath6kl_tx_clear_node_map(ar, eid, map_no);
@@ -1061,7 +1061,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
packet->act_len, status);

if (status || !(skb->data + HTC_HDR_LENGTH)) {
- ar->net_stats.rx_errors++;
+ vif->net_stats.rx_errors++;
dev_kfree_skb(skb);
return;
}
@@ -1072,8 +1072,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
*/
spin_lock_bh(&ar->lock);

- ar->net_stats.rx_packets++;
- ar->net_stats.rx_bytes += packet->act_len;
+ vif->net_stats.rx_packets++;
+ vif->net_stats.rx_bytes += packet->act_len;

spin_unlock_bh(&ar->lock);

@@ -1111,8 +1111,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
((packet->act_len < min_hdr_len) ||
(packet->act_len > WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH))) {
ath6kl_info("frame len is too short or too long\n");
- ar->net_stats.rx_errors++;
- ar->net_stats.rx_length_errors++;
+ vif->net_stats.rx_errors++;
+ vif->net_stats.rx_length_errors++;
dev_kfree_skb(skb);
return;
}
--
1.7.0.4


Subject: [PATCH V2 22/31] ath6kl: Use interface index from wmi data headr

Interface index is passed in wmi data header as well, use it
to get the corresponding vif structure.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/core.h | 2 +-
drivers/net/wireless/ath/ath6kl/main.c | 5 +--
drivers/net/wireless/ath/ath6kl/txrx.c | 56 ++++++++++++++++++++++++--------
drivers/net/wireless/ath/ath6kl/wmi.c | 16 ++++----
drivers/net/wireless/ath/ath6kl/wmi.h | 21 +++++++++++-
5 files changed, 73 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 498b626..466f6e1 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -618,7 +618,7 @@ struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target,
void aggr_module_destroy(struct aggr_info *aggr_info);
void aggr_reset_state(struct aggr_info *aggr_info);

-struct ath6kl_sta *ath6kl_find_sta(struct ath6kl *ar, u8 * node_addr);
+struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 * node_addr);
struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid);

void ath6kl_ready_event(void *devt, u8 * datap, u32 sw_ver, u32 abi_ver);
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index a10002d..cc3e3c8 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -20,10 +20,9 @@
#include "target.h"
#include "debug.h"

-struct ath6kl_sta *ath6kl_find_sta(struct ath6kl *ar, u8 *node_addr)
+struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;
struct ath6kl_sta *conn = NULL;
u8 i, max_conn;

diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 7e2d601..e4a6d8f 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -77,14 +77,13 @@ static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev,
return ar->node_map[ep_map].ep_id;
}

-static bool ath6kl_powersave_ap(struct ath6kl *ar, struct sk_buff *skb,
+static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb,
bool *more_data)
{
struct ethhdr *datap = (struct ethhdr *) skb->data;
struct ath6kl_sta *conn = NULL;
bool ps_queued = false, is_psq_empty = false;
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;

if (is_multicast_ether_addr(datap->h_dest)) {
u8 ctr = 0;
@@ -134,7 +133,7 @@ static bool ath6kl_powersave_ap(struct ath6kl *ar, struct sk_buff *skb,
}
}
} else {
- conn = ath6kl_find_sta(ar, datap->h_dest);
+ conn = ath6kl_find_sta(vif, datap->h_dest);
if (!conn) {
dev_kfree_skb(skb);

@@ -261,7 +260,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)

/* AP mode Power saving processing */
if (vif->nw_type == AP_NETWORK) {
- if (ath6kl_powersave_ap(ar, skb, &more_data))
+ if (ath6kl_powersave_ap(vif, skb, &more_data))
return 0;
}

@@ -277,7 +276,8 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
}

if (ath6kl_wmi_data_hdr_add(ar->wmi, skb, DATA_MSGTYPE,
- more_data, 0, 0, NULL)) {
+ more_data, 0, 0, NULL,
+ vif->fw_vif_idx)) {
ath6kl_err("wmi_data_hdr_add failed\n");
goto fail_tx;
}
@@ -534,6 +534,7 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue)
enum htc_endpoint_id eid;
bool wake_event = false;
bool flushing = false;
+ u8 if_idx;
/* TODO: Findout vif */
struct ath6kl_vif *vif = ar->vif;

@@ -581,6 +582,20 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue)
wake_event = true;
}

+ if (eid == ar->ctrl_ep) {
+ if_idx = wmi_cmd_hdr_get_if_idx(
+ (struct wmi_cmd_hdr *) skb->data);
+ } else {
+ if_idx = wmi_data_hdr_get_if_idx(
+ (struct wmi_data_hdr *) skb->data);
+ }
+
+ vif = ath6kl_get_vif_by_index(ar, if_idx);
+ if (!vif) {
+ ath6kl_free_cookie(ar, ath6kl_cookie);
+ continue;
+ }
+
if (status) {
if (status == -ECANCELED)
/* a packet was flushed */
@@ -1053,10 +1068,9 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
struct ath6kl_sta *conn = NULL;
struct sk_buff *skb1 = NULL;
struct ethhdr *datap = NULL;
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl_vif *vif;
u16 seq_no, offset;
- u8 tid;
+ u8 tid, if_idx;

ath6kl_dbg(ATH6KL_DBG_WLAN_RX,
"%s: ar=0x%p eid=%d, skb=0x%p, data=0x%p, len=0x%x status:%d",
@@ -1064,7 +1078,23 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
packet->act_len, status);

if (status || !(skb->data + HTC_HDR_LENGTH)) {
- vif->net_stats.rx_errors++;
+ dev_kfree_skb(skb);
+ return;
+ }
+
+ skb_put(skb, packet->act_len + HTC_HDR_LENGTH);
+ skb_pull(skb, HTC_HDR_LENGTH);
+
+ if (ept == ar->ctrl_ep) {
+ if_idx =
+ wmi_cmd_hdr_get_if_idx((struct wmi_cmd_hdr *) skb->data);
+ } else {
+ if_idx =
+ wmi_data_hdr_get_if_idx((struct wmi_data_hdr *) skb->data);
+ }
+
+ vif = ath6kl_get_vif_by_index(ar, if_idx);
+ if (!vif) {
dev_kfree_skb(skb);
return;
}
@@ -1080,8 +1110,6 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)

spin_unlock_bh(&ar->lock);

- skb_put(skb, packet->act_len + HTC_HDR_LENGTH);
- skb_pull(skb, HTC_HDR_LENGTH);

ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ",
skb->data, skb->len);
@@ -1143,7 +1171,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
}

datap = (struct ethhdr *) (skb->data + offset);
- conn = ath6kl_find_sta(ar, datap->h_source);
+ conn = ath6kl_find_sta(vif, datap->h_source);

if (!conn) {
dev_kfree_skb(skb);
@@ -1250,7 +1278,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
* frame to it on the air else send the
* frame up the stack.
*/
- conn = ath6kl_find_sta(ar, datap->h_dest);
+ conn = ath6kl_find_sta(vif, datap->h_dest);

if (conn && ar->intra_bss) {
skb1 = skb;
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index ed092b7..ed95c2a 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -81,7 +81,7 @@ enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi)
return wmi->ep_id;
}

-static struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx)
+struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx)
{
if (WARN_ON(if_idx > (MAX_NUM_VIF - 1)))
return NULL;
@@ -170,12 +170,12 @@ static int ath6kl_wmi_meta_add(struct wmi *wmi, struct sk_buff *skb,
int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
u8 msg_type, bool more_data,
enum wmi_data_hdr_data_type data_type,
- u8 meta_ver, void *tx_meta_info)
+ u8 meta_ver, void *tx_meta_info, u8 if_idx)
{
struct wmi_data_hdr *data_hdr;
int ret;

- if (WARN_ON(skb == NULL))
+ if (WARN_ON(skb == NULL || (if_idx > MAX_NUM_VIF - 1)))
return -EINVAL;

if (tx_meta_info) {
@@ -197,7 +197,7 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT;

data_hdr->info2 = cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT);
- data_hdr->info3 = 0;
+ data_hdr->info3 = cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK);

return 0;
}
@@ -1631,7 +1631,7 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb,
/* Only for OPT_TX_CMD, use BE endpoint. */
if (cmd_id == WMI_OPT_TX_FRAME_CMDID) {
ret = ath6kl_wmi_data_hdr_add(wmi, skb, OPT_MSGTYPE,
- false, false, 0, NULL);
+ false, false, 0, NULL, if_idx);
if (ret) {
dev_kfree_skb(skb);
return ret;
@@ -2098,7 +2098,7 @@ int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, u8 if_idx, const u8 *bssid,
}

static int ath6kl_wmi_data_sync_send(struct wmi *wmi, struct sk_buff *skb,
- enum htc_endpoint_id ep_id)
+ enum htc_endpoint_id ep_id, u8 if_idx)
{
struct wmi_data_hdr *data_hdr;
int ret;
@@ -2110,7 +2110,7 @@ static int ath6kl_wmi_data_sync_send(struct wmi *wmi, struct sk_buff *skb,

data_hdr = (struct wmi_data_hdr *) skb->data;
data_hdr->info = SYNC_MSGTYPE << WMI_DATA_HDR_MSG_TYPE_SHIFT;
- data_hdr->info3 = 0;
+ data_hdr->info3 = cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK);

ret = ath6kl_control_tx(wmi->parent_dev, skb, ep_id);

@@ -2192,7 +2192,7 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
traffic_class);
ret =
ath6kl_wmi_data_sync_send(wmi, data_sync_bufs[index].skb,
- ep_id);
+ ep_id, if_idx);

if (ret)
break;
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index d2c9510..621189b 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -173,6 +173,8 @@ enum wmi_data_hdr_data_type {
#define WMI_DATA_HDR_META_MASK 0x7
#define WMI_DATA_HDR_META_SHIFT 13

+#define WMI_DATA_HDR_IF_IDX_MASK 0xF
+
struct wmi_data_hdr {
s8 rssi;

@@ -197,6 +199,12 @@ struct wmi_data_hdr {
* b15:b13 - META_DATA_VERSION 0 - 7
*/
__le16 info2;
+
+ /*
+ * usage of info3, 16-bit:
+ * b3:b0 - Interface index
+ * b15:b4 - Reserved
+ */
__le16 info3;
} __packed;

@@ -239,6 +247,11 @@ static inline u8 wmi_data_hdr_get_meta(struct wmi_data_hdr *dhdr)
WMI_DATA_HDR_META_MASK;
}

+static inline u8 wmi_data_hdr_get_if_idx(struct wmi_data_hdr *dhdr)
+{
+ return le16_to_cpu(dhdr->info3) & WMI_DATA_HDR_IF_IDX_MASK;
+}
+
/* Tx meta version definitions */
#define WMI_MAX_TX_META_SZ 12
#define WMI_META_VERSION_1 0x01
@@ -303,6 +316,11 @@ struct wmi_cmd_hdr {
__le16 reserved;
} __packed;

+static inline u8 wmi_cmd_hdr_get_if_idx(struct wmi_cmd_hdr *chdr)
+{
+ return le16_to_cpu(chdr->info1) & WMI_CMD_HDR_IF_ID_MASK;
+}
+
/* List of WMI commands */
enum wmi_cmd_id {
WMI_CONNECT_CMDID = 0x0001,
@@ -2167,7 +2185,7 @@ int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb);
int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
u8 msg_type, bool more_data,
enum wmi_data_hdr_data_type data_type,
- u8 meta_ver, void *tx_meta_info);
+ u8 meta_ver, void *tx_meta_info, u8 if_idx);

int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb);
@@ -2292,6 +2310,7 @@ int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx);
int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
const u8 *ie, u8 ie_len);

+struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx);
void *ath6kl_wmi_init(struct ath6kl *devt);
void ath6kl_wmi_shutdown(struct wmi *wmi);

--
1.7.0.4


Subject: [PATCH V2 06/31] ath6kl: Define interface specific states

Currently ar->flag maintains interface stats. Move interface
specific states from ar->flag to vif->flags.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 66 ++++++++++++++++++----------
drivers/net/wireless/ath/ath6kl/core.h | 41 ++++++++++-------
drivers/net/wireless/ath/ath6kl/init.c | 3 +-
drivers/net/wireless/ath/ath6kl/main.c | 64 ++++++++++++++++++---------
drivers/net/wireless/ath/ath6kl/txrx.c | 23 ++++++---
drivers/net/wireless/ath/ath6kl/wmi.c | 12 +++--
6 files changed, 133 insertions(+), 76 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index e663d60..fed31cf 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -231,12 +231,14 @@ static void ath6kl_set_key_mgmt(struct ath6kl *ar, u32 key_mgmt)

static bool ath6kl_cfg80211_ready(struct ath6kl *ar)
{
+ struct ath6kl_vif *vif = ar->vif;
+
if (!test_bit(WMI_READY, &ar->flag)) {
ath6kl_err("wmi is not ready\n");
return false;
}

- if (!test_bit(WLAN_ENABLED, &ar->flag)) {
+ if (!test_bit(WLAN_ENABLED, &vif->flags)) {
ath6kl_err("wlan disabled\n");
return false;
}
@@ -295,6 +297,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme)
{
struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);
int status;

ar->sme_state = SME_CONNECTING;
@@ -345,7 +348,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
return status;
}

- if (test_bit(CONNECTED, &ar->flag) &&
+ if (test_bit(CONNECTED, &vif->flags) &&
ar->ssid_len == sme->ssid_len &&
!memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
ar->reconnect_flag = true;
@@ -420,7 +423,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
}

if (!ar->usr_bss_filter) {
- clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
+ clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) {
ath6kl_err("couldn't set bss filtering\n");
up(&ar->sem);
@@ -469,7 +472,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
}

ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
- set_bit(CONNECT_PEND, &ar->flag);
+ set_bit(CONNECT_PEND, &vif->flags);

return 0;
}
@@ -529,6 +532,8 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
u8 assoc_resp_len, u8 *assoc_info)
{
struct ieee80211_channel *chan;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;

/* capinfo + listen interval */
u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
@@ -548,7 +553,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
* a Beacon frame from the AP is seen.
*/
ar->assoc_bss_beacon_int = beacon_intvl;
- clear_bit(DTIM_PERIOD_AVAIL, &ar->flag);
+ clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);

if (nw_type & ADHOC_NETWORK) {
if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
@@ -637,6 +642,9 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
u8 *bssid, u8 assoc_resp_len,
u8 *assoc_info, u16 proto_reason)
{
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
+
if (ar->scan_req) {
cfg80211_scan_done(ar->scan_req, true);
ar->scan_req = NULL;
@@ -676,7 +684,7 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
return;
}

- clear_bit(CONNECT_PEND, &ar->flag);
+ clear_bit(CONNECT_PEND, &vif->flags);

if (ar->sme_state == SME_CONNECTING) {
cfg80211_connect_result(ar->net_dev,
@@ -696,6 +704,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_scan_request *request)
{
struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+ struct ath6kl_vif *vif = netdev_priv(ndev);
s8 n_channels = 0;
u16 *channels = NULL;
int ret = 0;
@@ -705,10 +714,10 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
return -EIO;

if (!ar->usr_bss_filter) {
- clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
+ clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
ret = ath6kl_wmi_bssfilter_cmd(
ar->wmi,
- (test_bit(CONNECTED, &ar->flag) ?
+ (test_bit(CONNECTED, &vif->flags) ?
ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
if (ret) {
ath6kl_err("couldn't set bss filtering\n");
@@ -761,7 +770,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
channels[i] = request->channels[i]->center_freq;
}

- if (test_bit(CONNECTED, &ar->flag))
+ if (test_bit(CONNECTED, &vif->flags))
force_fg_scan = 1;

ret = ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, force_fg_scan,
@@ -810,6 +819,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
struct key_params *params)
{
struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+ struct ath6kl_vif *vif = netdev_priv(ndev);
struct ath6kl_key *key = NULL;
u8 key_usage;
u8 key_type;
@@ -888,7 +898,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
ar->ap_mode_bkey.key_type = key_type;
ar->ap_mode_bkey.key_len = key->key_len;
memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
- if (!test_bit(CONNECTED, &ar->flag)) {
+ if (!test_bit(CONNECTED, &vif->flags)) {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
"key configuration until AP mode has been "
"started\n");
@@ -901,7 +911,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
}

if (ar->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
- !test_bit(CONNECTED, &ar->flag)) {
+ !test_bit(CONNECTED, &vif->flags)) {
/*
* Store the key locally so that it can be re-configured after
* the AP mode has properly started
@@ -995,6 +1005,7 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
bool multicast)
{
struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+ struct ath6kl_vif *vif = netdev_priv(ndev);
struct ath6kl_key *key = NULL;
int status = 0;
u8 key_usage;
@@ -1028,7 +1039,7 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
if (multicast)
key_type = ar->grp_crypto;

- if (ar->next_mode == AP_NETWORK && !test_bit(CONNECTED, &ar->flag))
+ if (ar->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
return 0; /* Delay until AP mode has been started */

status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
@@ -1113,11 +1124,12 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
{
struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
+ struct ath6kl_vif *vif = ar->vif;

if (!ath6kl_cfg80211_ready(ar))
return -EIO;

- if (test_bit(CONNECTED, &ar->flag)) {
+ if (test_bit(CONNECTED, &vif->flags)) {
ar->tx_pwr = 0;

if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi) != 0) {
@@ -1211,6 +1223,7 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
struct cfg80211_ibss_params *ibss_param)
{
struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);
int status;

if (!ath6kl_cfg80211_ready(ar))
@@ -1269,7 +1282,7 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
ar->ssid_len, ar->ssid,
ar->req_bssid, ar->ch_hint,
ar->connect_ctrl_flags);
- set_bit(CONNECT_PEND, &ar->flag);
+ set_bit(CONNECT_PEND, &vif->flags);

return 0;
}
@@ -1362,6 +1375,7 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
u8 *mac, struct station_info *sinfo)
{
struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);
long left;
bool sgi;
s32 rate;
@@ -1444,8 +1458,8 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,

sinfo->filled |= STATION_INFO_TX_BITRATE;

- if (test_bit(CONNECTED, &ar->flag) &&
- test_bit(DTIM_PERIOD_AVAIL, &ar->flag) &&
+ if (test_bit(CONNECTED, &vif->flags) &&
+ test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
ar->nw_type == INFRA_NETWORK) {
sinfo->filled |= STATION_INFO_BSS_PARAM;
sinfo->bss_param.flags = 0;
@@ -1475,7 +1489,9 @@ static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
{
struct ath6kl *ar = ath6kl_priv(netdev);
- if (test_bit(CONNECTED, &ar->flag))
+ struct ath6kl_vif *vif = netdev_priv(netdev);
+
+ if (test_bit(CONNECTED, &vif->flags))
return ath6kl_wmi_setpmkid_cmd(ar->wmi, ar->bssid, NULL, false);
return 0;
}
@@ -1711,14 +1727,15 @@ static int ath6kl_set_beacon(struct wiphy *wiphy, struct net_device *dev,
static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
{
struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);

if (ar->nw_type != AP_NETWORK)
return -EOPNOTSUPP;
- if (!test_bit(CONNECTED, &ar->flag))
+ if (!test_bit(CONNECTED, &vif->flags))
return -ENOTCONN;

ath6kl_wmi_disconnect_cmd(ar->wmi);
- clear_bit(CONNECTED, &ar->flag);
+ clear_bit(CONNECTED, &vif->flags);

return 0;
}
@@ -1813,12 +1830,13 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
const u8 *buf, size_t len, bool no_cck, u64 *cookie)
{
struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);
u32 id;
const struct ieee80211_mgmt *mgmt;

mgmt = (const struct ieee80211_mgmt *) buf;
if (buf + len >= mgmt->u.probe_resp.variable &&
- ar->nw_type == AP_NETWORK && test_bit(CONNECTED, &ar->flag) &&
+ ar->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
ieee80211_is_probe_resp(mgmt->frame_control)) {
/*
* Send Probe Response frame in AP mode using a separate WMI
@@ -2038,9 +2056,9 @@ void ath6kl_deinit_if_data(struct ath6kl_vif *vif)

ar->aggr_cntxt = NULL;

- if (test_bit(NETDEV_REGISTERED, &ar->flag)) {
+ if (test_bit(NETDEV_REGISTERED, &vif->flags)) {
unregister_netdev(vif->ndev);
- clear_bit(NETDEV_REGISTERED, &ar->flag);
+ clear_bit(NETDEV_REGISTERED, &vif->flags);
}

free_netdev(vif->ndev);
@@ -2080,9 +2098,9 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
goto err;

ar->sme_state = SME_DISCONNECTED;
- set_bit(WLAN_ENABLED, &ar->flag);
+ set_bit(WLAN_ENABLED, &vif->flags);
ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
- set_bit(NETDEV_REGISTERED, &ar->flag);
+ set_bit(NETDEV_REGISTERED, &vif->flags);

return ndev;

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 0c1dee0..4777171 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -380,30 +380,37 @@ struct ath6kl_req_key {
u8 key_len;
};

+/* vif flags info */
+enum ath6kl_vif_state {
+ CONNECTED,
+ CONNECT_PEND,
+ WMM_ENABLED,
+ NETQ_STOPPED,
+ DTIM_EXPIRED,
+ NETDEV_REGISTERED,
+ CLEAR_BSSFILTER_ON_BEACON,
+ DTIM_PERIOD_AVAIL,
+ WLAN_ENABLED,
+};
+
struct ath6kl_vif {
struct wireless_dev wdev;
struct net_device *ndev;
struct ath6kl *ar;
+ unsigned long flags;
};

/* Flag info */
-#define WMI_ENABLED 0
-#define WMI_READY 1
-#define CONNECTED 2
-#define STATS_UPDATE_PEND 3
-#define CONNECT_PEND 4
-#define WMM_ENABLED 5
-#define NETQ_STOPPED 6
-#define WMI_CTRL_EP_FULL 7
-#define DTIM_EXPIRED 8
-#define DESTROY_IN_PROGRESS 9
-#define NETDEV_REGISTERED 10
-#define SKIP_SCAN 11
-#define WLAN_ENABLED 12
-#define TESTMODE 13
-#define CLEAR_BSSFILTER_ON_BEACON 14
-#define DTIM_PERIOD_AVAIL 15
-#define ROAM_TBL_PEND 16
+enum ath6kl_dev_state {
+ WMI_ENABLED,
+ WMI_READY,
+ WMI_CTRL_EP_FULL,
+ TESTMODE,
+ DESTROY_IN_PROGRESS,
+ SKIP_SCAN,
+ STATS_UPDATE_PEND,
+ ROAM_TBL_PEND,
+};

struct ath6kl {
struct device *dev;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 246399d..91c2783 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1574,6 +1574,7 @@ err_wq:
void ath6kl_stop_txrx(struct ath6kl *ar)
{
struct net_device *ndev = ar->net_dev;
+ struct ath6kl_vif *vif = ar->vif;

if (!ndev)
return;
@@ -1588,7 +1589,7 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
if (ar->wlan_pwr_state != WLAN_POWER_STATE_CUT_PWR)
ath6kl_stop_endpoint(ndev, false, true);

- clear_bit(WLAN_ENABLED, &ar->flag);
+ clear_bit(WLAN_ENABLED, &vif->flags);
}

/*
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 4470f6e..6a0eaea 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -429,6 +429,7 @@ void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
bool get_dbglogs)
{
struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);
static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
bool discon_issued;

@@ -436,8 +437,8 @@ void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,

/* disable the target and the interrupts associated with it */
if (test_bit(WMI_READY, &ar->flag)) {
- discon_issued = (test_bit(CONNECTED, &ar->flag) ||
- test_bit(CONNECT_PEND, &ar->flag));
+ discon_issued = (test_bit(CONNECTED, &vif->flags) ||
+ test_bit(CONNECT_PEND, &vif->flags));
ath6kl_disconnect(ar);
if (!keep_profile)
ath6kl_init_profile_info(ar);
@@ -524,6 +525,8 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel)
struct ath6kl_req_key *ik;
int res;
u8 key_rsc[ATH6KL_KEY_SEQ_LEN];
+ /* TODO: Pass vif instead of taking it from ar */
+ struct ath6kl_vif *vif = ar->vif;

ik = &ar->ap_mode_bkey;

@@ -555,7 +558,7 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel)
}

ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
- set_bit(CONNECTED, &ar->flag);
+ set_bit(CONNECTED, &vif->flags);
netif_carrier_on(ar->net_dev);
}

@@ -914,20 +917,26 @@ void disconnect_timer_handler(unsigned long ptr)

void ath6kl_disconnect(struct ath6kl *ar)
{
- if (test_bit(CONNECTED, &ar->flag) ||
- test_bit(CONNECT_PEND, &ar->flag)) {
+ /* TODO: Pass vif instead of taking it from ar */
+ struct ath6kl_vif *vif = ar->vif;
+
+ if (test_bit(CONNECTED, &vif->flags) ||
+ test_bit(CONNECT_PEND, &vif->flags)) {
ath6kl_wmi_disconnect_cmd(ar->wmi);
/*
* Disconnect command is issued, clear the connect pending
* flag. The connected flag will be cleared in
* disconnect event notification.
*/
- clear_bit(CONNECT_PEND, &ar->flag);
+ clear_bit(CONNECT_PEND, &vif->flags);
}
}

void ath6kl_deep_sleep_enable(struct ath6kl *ar)
{
+ /* TODO: Pass vif instead of taking it from ar */
+ struct ath6kl_vif *vif = ar->vif;
+
switch (ar->sme_state) {
case SME_CONNECTING:
cfg80211_connect_result(ar->net_dev, ar->bssid, NULL, 0,
@@ -946,8 +955,8 @@ void ath6kl_deep_sleep_enable(struct ath6kl *ar)
break;
}

- if (test_bit(CONNECTED, &ar->flag) ||
- test_bit(CONNECT_PEND, &ar->flag))
+ if (test_bit(CONNECTED, &vif->flags) ||
+ test_bit(CONNECT_PEND, &vif->flags))
ath6kl_wmi_disconnect_cmd(ar->wmi);

ar->sme_state = SME_DISCONNECTED;
@@ -1016,10 +1025,13 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)

void ath6kl_scan_complete_evt(struct ath6kl *ar, int status)
{
+ /* TODO: Pass vif instead of taking it from ar */
+ struct ath6kl_vif *vif = ar->vif;
+
ath6kl_cfg80211_scan_complete_event(ar, status);

if (!ar->usr_bss_filter) {
- clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
+ clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
}

@@ -1032,6 +1044,9 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
u8 assoc_req_len, u8 assoc_resp_len,
u8 *assoc_info)
{
+ /* TODO: findout vif instead of taking it from ar */
+ struct ath6kl_vif *vif = ar->vif;
+
ath6kl_cfg80211_connect_event(ar, channel, bssid,
listen_int, beacon_int,
net_type, beacon_ie_len,
@@ -1049,8 +1064,8 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,

/* Update connect & link status atomically */
spin_lock_bh(&ar->lock);
- set_bit(CONNECTED, &ar->flag);
- clear_bit(CONNECT_PEND, &ar->flag);
+ set_bit(CONNECTED, &vif->flags);
+ clear_bit(CONNECT_PEND, &vif->flags);
netif_carrier_on(ar->net_dev);
spin_unlock_bh(&ar->lock);

@@ -1064,7 +1079,7 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
}

if (!ar->usr_bss_filter) {
- set_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
+ set_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
ath6kl_wmi_bssfilter_cmd(ar->wmi, CURRENT_BSS_FILTER, 0);
}
}
@@ -1292,6 +1307,8 @@ void ath6kl_dtimexpiry_event(struct ath6kl *ar)
{
bool mcastq_empty = false;
struct sk_buff *skb;
+ /* TODO: Pass vif instead of taking it from ar */
+ struct ath6kl_vif *vif = ar->vif;

/*
* If there are no associated STAs, ignore the DTIM expiry event.
@@ -1313,7 +1330,7 @@ void ath6kl_dtimexpiry_event(struct ath6kl *ar)
return;

/* set the STA flag to dtim_expired for the frame to go out */
- set_bit(DTIM_EXPIRED, &ar->flag);
+ set_bit(DTIM_EXPIRED, &vif->flags);

spin_lock_bh(&ar->mcastpsq_lock);
while ((skb = skb_dequeue(&ar->mcastpsq)) != NULL) {
@@ -1325,7 +1342,7 @@ void ath6kl_dtimexpiry_event(struct ath6kl *ar)
}
spin_unlock_bh(&ar->mcastpsq_lock);

- clear_bit(DTIM_EXPIRED, &ar->flag);
+ clear_bit(DTIM_EXPIRED, &vif->flags);

/* clear the LSB of the BitMapCtl field of the TIM IE */
ath6kl_wmi_set_pvb_cmd(ar->wmi, MCAST_AID, 0);
@@ -1335,6 +1352,9 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
u8 assoc_resp_len, u8 *assoc_info,
u16 prot_reason_status)
{
+ /* TODO: Findout vif instead of taking it from ar */
+ struct ath6kl_vif *vif = ar->vif;
+
if (ar->nw_type == AP_NETWORK) {
if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))
return;
@@ -1357,7 +1377,7 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,

if (memcmp(ar->net_dev->dev_addr, bssid, ETH_ALEN) == 0) {
memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
- clear_bit(CONNECTED, &ar->flag);
+ clear_bit(CONNECTED, &vif->flags);
}
return;
}
@@ -1382,19 +1402,19 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
if (!ar->usr_bss_filter && test_bit(WMI_READY, &ar->flag))
ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
} else {
- set_bit(CONNECT_PEND, &ar->flag);
+ set_bit(CONNECT_PEND, &vif->flags);
if (((reason == ASSOC_FAILED) &&
(prot_reason_status == 0x11)) ||
((reason == ASSOC_FAILED) && (prot_reason_status == 0x0)
&& (ar->reconnect_flag == 1))) {
- set_bit(CONNECTED, &ar->flag);
+ set_bit(CONNECTED, &vif->flags);
return;
}
}

/* update connect & link status atomically */
spin_lock_bh(&ar->lock);
- clear_bit(CONNECTED, &ar->flag);
+ clear_bit(CONNECTED, &vif->flags);
netif_carrier_off(ar->net_dev);
spin_unlock_bh(&ar->lock);

@@ -1414,12 +1434,13 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
static int ath6kl_open(struct net_device *dev)
{
struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);

spin_lock_bh(&ar->lock);

- set_bit(WLAN_ENABLED, &ar->flag);
+ set_bit(WLAN_ENABLED, &vif->flags);

- if (test_bit(CONNECTED, &ar->flag)) {
+ if (test_bit(CONNECTED, &vif->flags)) {
netif_carrier_on(dev);
netif_wake_queue(dev);
} else
@@ -1433,6 +1454,7 @@ static int ath6kl_open(struct net_device *dev)
static int ath6kl_close(struct net_device *dev)
{
struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);

netif_stop_queue(dev);

@@ -1443,7 +1465,7 @@ static int ath6kl_close(struct net_device *dev)
0, 0, 0))
return -EIO;

- clear_bit(WLAN_ENABLED, &ar->flag);
+ clear_bit(WLAN_ENABLED, &vif->flags);
}

ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED);
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index a9dff01..d1652bd 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -83,6 +83,8 @@ static bool ath6kl_powersave_ap(struct ath6kl *ar, struct sk_buff *skb,
struct ethhdr *datap = (struct ethhdr *) skb->data;
struct ath6kl_sta *conn = NULL;
bool ps_queued = false, is_psq_empty = false;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;

if (is_multicast_ether_addr(datap->h_dest)) {
u8 ctr = 0;
@@ -100,7 +102,7 @@ static bool ath6kl_powersave_ap(struct ath6kl *ar, struct sk_buff *skb,
* If this transmit is not because of a Dtim Expiry
* q it.
*/
- if (!test_bit(DTIM_EXPIRED, &ar->flag)) {
+ if (!test_bit(DTIM_EXPIRED, &vif->flags)) {
bool is_mcastq_empty = false;

spin_lock_bh(&ar->mcastpsq_lock);
@@ -235,6 +237,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
struct ath6kl *ar = ath6kl_priv(dev);
struct ath6kl_cookie *cookie = NULL;
enum htc_endpoint_id eid = ENDPOINT_UNUSED;
+ struct ath6kl_vif *vif = netdev_priv(dev);
u32 map_no = 0;
u16 htc_tag = ATH6KL_DATA_PKT_TAG;
u8 ac = 99 ; /* initialize to unmapped ac */
@@ -246,7 +249,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
skb, skb->data, skb->len);

/* If target is not associated */
- if (!test_bit(CONNECTED, &ar->flag)) {
+ if (!test_bit(CONNECTED, &vif->flags)) {
dev_kfree_skb(skb);
return 0;
}
@@ -278,12 +281,12 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
}

if ((ar->nw_type == ADHOC_NETWORK) &&
- ar->ibss_ps_enable && test_bit(CONNECTED, &ar->flag))
+ ar->ibss_ps_enable && test_bit(CONNECTED, &vif->flags))
chk_adhoc_ps_mapping = true;
else {
/* get the stream mapping */
ret = ath6kl_wmi_implicit_create_pstream(ar->wmi, skb,
- 0, test_bit(WMM_ENABLED, &ar->flag), &ac);
+ 0, test_bit(WMM_ENABLED, &vif->flags), &ac);
if (ret)
goto fail_tx;
}
@@ -426,6 +429,8 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
struct htc_packet *packet)
{
struct ath6kl *ar = target->dev->ar;
+ /* TODO: Findout vif properly */
+ struct ath6kl_vif *vif = ar->vif;
enum htc_endpoint_id endpoint = packet->endpoint;

if (endpoint == ar->ctrl_ep) {
@@ -468,7 +473,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,

stop_net_queues:
spin_lock_bh(&ar->lock);
- set_bit(NETQ_STOPPED, &ar->flag);
+ set_bit(NETQ_STOPPED, &vif->flags);
spin_unlock_bh(&ar->lock);
netif_stop_queue(ar->net_dev);

@@ -524,6 +529,8 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue)
enum htc_endpoint_id eid;
bool wake_event = false;
bool flushing = false;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;

skb_queue_head_init(&skb_queue);

@@ -597,15 +604,15 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue)

ath6kl_free_cookie(ar, ath6kl_cookie);

- if (test_bit(NETQ_STOPPED, &ar->flag))
- clear_bit(NETQ_STOPPED, &ar->flag);
+ if (test_bit(NETQ_STOPPED, &vif->flags))
+ clear_bit(NETQ_STOPPED, &vif->flags);
}

spin_unlock_bh(&ar->lock);

__skb_queue_purge(&skb_queue);

- if (test_bit(CONNECTED, &ar->flag)) {
+ if (test_bit(CONNECTED, &vif->flags)) {
if (!flushing)
netif_wake_queue(ar->net_dev);
}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 7f4c2c2..a71d773 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -950,6 +950,8 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
struct ath6kl *ar = wmi->parent_dev;
struct ieee80211_mgmt *mgmt;
struct cfg80211_bss *bss;
+ /*TODO: Findout vif properly */
+ struct ath6kl_vif *vif = ar->vif;

if (len <= sizeof(struct wmi_bss_info_hdr2))
return -EINVAL;
@@ -969,8 +971,8 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
return 0; /* Only update BSS table for now */

if (bih->frame_type == BEACON_FTYPE &&
- test_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag)) {
- clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
+ test_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags)) {
+ clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
}

@@ -981,14 +983,14 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
if (len < 8 + 2 + 2)
return -EINVAL;

- if (bih->frame_type == BEACON_FTYPE && test_bit(CONNECTED, &ar->flag) &&
- memcmp(bih->bssid, ar->bssid, ETH_ALEN) == 0) {
+ if (bih->frame_type == BEACON_FTYPE && test_bit(CONNECTED, &vif->flags)
+ && memcmp(bih->bssid, ar->bssid, ETH_ALEN) == 0) {
const u8 *tim;
tim = cfg80211_find_ie(WLAN_EID_TIM, buf + 8 + 2 + 2,
len - 8 - 2 - 2);
if (tim && tim[1] >= 2) {
ar->assoc_bss_dtim_period = tim[3];
- set_bit(DTIM_PERIOD_AVAIL, &ar->flag);
+ set_bit(DTIM_PERIOD_AVAIL, &vif->flags);
}
}

--
1.7.0.4


Subject: [PATCH V2 01/31] ath6kl: Pass ath6kl structure to ath6kl_init() instead of net_device

ar is again taken from private area of net_device in ath6kl_init(), pass
ar directly.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/init.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 1700423..5fd1693 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1461,9 +1461,8 @@ static int ath6kl_init_hw_params(struct ath6kl *ar)
return 0;
}

-static int ath6kl_init(struct net_device *dev)
+static int ath6kl_init(struct ath6kl *ar)
{
- struct ath6kl *ar = ath6kl_priv(dev);
int status = 0;
s32 timeleft;

@@ -1631,7 +1630,7 @@ int ath6kl_core_init(struct ath6kl *ar)
if (ret)
goto err_htc_cleanup;

- ret = ath6kl_init(ar->net_dev);
+ ret = ath6kl_init(ar);
if (ret)
goto err_htc_cleanup;

--
1.7.0.4


Subject: [PATCH V2 24/31] ath6kl: Introduce spinlock to protect vif specific information

Use this spinlock to protect the vif's data instead of
one from ath6kl.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 1 +
drivers/net/wireless/ath/ath6kl/core.h | 2 ++
drivers/net/wireless/ath/ath6kl/main.c | 13 ++++---------
drivers/net/wireless/ath/ath6kl/txrx.c | 8 ++++----
4 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index d42cb3e..5eadcaa 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -2076,6 +2076,7 @@ static int ath6kl_init_if_data(struct ath6kl_vif *vif)
setup_timer(&vif->disconnect_timer, disconnect_timer_handler,
(unsigned long) vif->ndev);
set_bit(WMM_ENABLED, &vif->flags);
+ spin_lock_init(&vif->if_lock);

return 0;
}
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 747e5a7..2c64652 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -400,6 +400,8 @@ struct ath6kl_vif {
struct wireless_dev wdev;
struct net_device *ndev;
struct ath6kl *ar;
+ /* Lock to protect vif specific net_stats and flags */
+ spinlock_t if_lock;
u8 fw_vif_idx;
unsigned long flags;
int ssid_len;
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 6bf9402..ca86ed3 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -989,11 +989,11 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
netif_wake_queue(vif->ndev);

/* Update connect & link status atomically */
- spin_lock_bh(&ar->lock);
+ spin_lock_bh(&vif->if_lock);
set_bit(CONNECTED, &vif->flags);
clear_bit(CONNECT_PEND, &vif->flags);
netif_carrier_on(vif->ndev);
- spin_unlock_bh(&ar->lock);
+ spin_unlock_bh(&vif->if_lock);

aggr_reset_state(vif->aggr_cntxt);
vif->reconnect_flag = 0;
@@ -1345,10 +1345,10 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
}

/* update connect & link status atomically */
- spin_lock_bh(&ar->lock);
+ spin_lock_bh(&vif->if_lock);
clear_bit(CONNECTED, &vif->flags);
netif_carrier_off(vif->ndev);
- spin_unlock_bh(&ar->lock);
+ spin_unlock_bh(&vif->if_lock);

if ((reason != CSERV_DISCONNECT) || (vif->reconnect_flag != 1))
vif->reconnect_flag = 0;
@@ -1365,11 +1365,8 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,

static int ath6kl_open(struct net_device *dev)
{
- struct ath6kl *ar = ath6kl_priv(dev);
struct ath6kl_vif *vif = netdev_priv(dev);

- spin_lock_bh(&ar->lock);
-
set_bit(WLAN_ENABLED, &vif->flags);

if (test_bit(CONNECTED, &vif->flags)) {
@@ -1378,8 +1375,6 @@ static int ath6kl_open(struct net_device *dev)
} else
netif_carrier_off(dev);

- spin_unlock_bh(&ar->lock);
-
return 0;
}

diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index e4a6d8f..ff288da 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -475,9 +475,9 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
return HTC_SEND_FULL_DROP;

stop_net_queues:
- spin_lock_bh(&ar->lock);
+ spin_lock_bh(&vif->if_lock);
set_bit(NETQ_STOPPED, &vif->flags);
- spin_unlock_bh(&ar->lock);
+ spin_unlock_bh(&vif->if_lock);
netif_stop_queue(vif->ndev);

return HTC_SEND_FULL_KEEP;
@@ -1103,12 +1103,12 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
* Take lock to protect buffer counts and adaptive power throughput
* state.
*/
- spin_lock_bh(&ar->lock);
+ spin_lock_bh(&vif->if_lock);

vif->net_stats.rx_packets++;
vif->net_stats.rx_bytes += packet->act_len;

- spin_unlock_bh(&ar->lock);
+ spin_unlock_bh(&vif->if_lock);


ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ",
--
1.7.0.4


Subject: [PATCH V2 08/31] ath6kl: Move nw_type to vif structure

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 42 ++++++++++++++-------------
drivers/net/wireless/ath/ath6kl/core.h | 4 +-
drivers/net/wireless/ath/ath6kl/init.c | 2 +-
drivers/net/wireless/ath/ath6kl/main.c | 20 ++++++++----
drivers/net/wireless/ath/ath6kl/txrx.c | 18 +++++++----
drivers/net/wireless/ath/ath6kl/wmi.c | 8 ++++-
6 files changed, 55 insertions(+), 39 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index f9732f7..5164e65 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -443,7 +443,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
}
}

- ar->nw_type = ar->next_mode;
+ vif->nw_type = vif->next_mode;

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"%s: connect called with authmode %d dot11 auth %d"
@@ -455,7 +455,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
vif->grp_crypto_len, ar->ch_hint);

ar->reconnect_flag = 0;
- status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
+ status = ath6kl_wmi_connect_cmd(ar->wmi, vif->nw_type,
vif->dot11_auth_mode, vif->auth_mode,
vif->prwise_crypto,
vif->prwise_crypto_len,
@@ -665,7 +665,7 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
ar->scan_req = NULL;
}

- if (ar->nw_type & ADHOC_NETWORK) {
+ if (vif->nw_type & ADHOC_NETWORK) {
if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"%s: ath6k not in ibss mode\n", __func__);
@@ -676,7 +676,7 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
return;
}

- if (ar->nw_type & INFRA_NETWORK) {
+ if (vif->nw_type & INFRA_NETWORK) {
if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
@@ -906,7 +906,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,

vif->def_txkey_index = key_index;

- if (ar->nw_type == AP_NETWORK && !pairwise &&
+ if (vif->nw_type == AP_NETWORK && !pairwise &&
(key_type == TKIP_CRYPT || key_type == AES_CRYPT) && params) {
ar->ap_mode_bkey.valid = true;
ar->ap_mode_bkey.key_index = key_index;
@@ -925,7 +925,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
}
}

- if (ar->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
+ if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
!test_bit(CONNECTED, &vif->flags)) {
/*
* Store the key locally so that it can be re-configured after
@@ -1054,7 +1054,7 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
if (multicast)
key_type = vif->grp_crypto;

- if (ar->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
+ if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
return 0; /* Delay until AP mode has been started */

status = ath6kl_wmi_addkey_cmd(ar->wmi, vif->def_txkey_index,
@@ -1201,6 +1201,7 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
{
struct ath6kl *ar = ath6kl_priv(ndev);
struct wireless_dev *wdev = ar->wdev;
+ struct ath6kl_vif *vif = netdev_priv(ndev);

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);

@@ -1209,19 +1210,19 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,

switch (type) {
case NL80211_IFTYPE_STATION:
- ar->next_mode = INFRA_NETWORK;
+ vif->next_mode = INFRA_NETWORK;
break;
case NL80211_IFTYPE_ADHOC:
- ar->next_mode = ADHOC_NETWORK;
+ vif->next_mode = ADHOC_NETWORK;
break;
case NL80211_IFTYPE_AP:
- ar->next_mode = AP_NETWORK;
+ vif->next_mode = AP_NETWORK;
break;
case NL80211_IFTYPE_P2P_CLIENT:
- ar->next_mode = INFRA_NETWORK;
+ vif->next_mode = INFRA_NETWORK;
break;
case NL80211_IFTYPE_P2P_GO:
- ar->next_mode = AP_NETWORK;
+ vif->next_mode = AP_NETWORK;
break;
default:
ath6kl_err("invalid interface type %u\n", type);
@@ -1278,7 +1279,7 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
ath6kl_set_cipher(ar, 0, false);
}

- ar->nw_type = ar->next_mode;
+ vif->nw_type = vif->next_mode;

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"%s: connect called with authmode %d dot11 auth %d"
@@ -1289,7 +1290,7 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
vif->prwise_crypto_len, vif->grp_crypto,
vif->grp_crypto_len, ar->ch_hint);

- status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
+ status = ath6kl_wmi_connect_cmd(ar->wmi, vif->nw_type,
vif->dot11_auth_mode, vif->auth_mode,
vif->prwise_crypto,
vif->prwise_crypto_len,
@@ -1476,7 +1477,7 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,

if (test_bit(CONNECTED, &vif->flags) &&
test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
- ar->nw_type == INFRA_NETWORK) {
+ vif->nw_type == INFRA_NETWORK) {
sinfo->filled |= STATION_INFO_BSS_PARAM;
sinfo->bss_param.flags = 0;
sinfo->bss_param.dtim_period = ar->assoc_bss_dtim_period;
@@ -1604,7 +1605,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
if (!ath6kl_cfg80211_ready(ar))
return -EIO;

- if (ar->next_mode != AP_NETWORK)
+ if (vif->next_mode != AP_NETWORK)
return -EOPNOTSUPP;

if (info->beacon_ies) {
@@ -1715,7 +1716,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
ath6kl_set_cipher(ar, info->crypto.cipher_group, false);

p.nw_type = AP_NETWORK;
- ar->nw_type = ar->next_mode;
+ vif->nw_type = vif->next_mode;

p.ssid_len = vif->ssid_len;
memcpy(p.ssid, vif->ssid, vif->ssid_len);
@@ -1746,7 +1747,7 @@ static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
struct ath6kl *ar = ath6kl_priv(dev);
struct ath6kl_vif *vif = netdev_priv(dev);

- if (ar->nw_type != AP_NETWORK)
+ if (vif->nw_type != AP_NETWORK)
return -EOPNOTSUPP;
if (!test_bit(CONNECTED, &vif->flags))
return -ENOTCONN;
@@ -1761,8 +1762,9 @@ static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
u8 *mac, struct station_parameters *params)
{
struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);

- if (ar->nw_type != AP_NETWORK)
+ if (vif->nw_type != AP_NETWORK)
return -EOPNOTSUPP;

/* Use this only for authorizing/unauthorizing a station */
@@ -1853,7 +1855,7 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,

mgmt = (const struct ieee80211_mgmt *) buf;
if (buf + len >= mgmt->u.probe_resp.variable &&
- ar->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
+ vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
ieee80211_is_probe_resp(mgmt->frame_control)) {
/*
* Send Probe Response frame in AP mode using a separate WMI
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index f401715..714092a 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -407,6 +407,8 @@ struct ath6kl_vif {
u8 grp_crypto;
u8 grp_crypto_len;
u8 def_txkey_index;
+ u8 next_mode;
+ u8 nw_type;
};

/* Flag info */
@@ -435,8 +437,6 @@ struct ath6kl {
struct ath6kl_vif *vif;
spinlock_t lock;
struct semaphore sem;
- u8 next_mode;
- u8 nw_type;
struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
u8 bssid[ETH_ALEN];
u8 req_bssid[ETH_ALEN];
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 1aac79c..e6f4dde 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -91,7 +91,7 @@ void ath6kl_init_profile_info(struct ath6kl *ar)
memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
memset(ar->bssid, 0, sizeof(ar->bssid));
ar->bss_ch = 0;
- ar->nw_type = ar->next_mode = INFRA_NETWORK;
+ vif->nw_type = vif->next_mode = INFRA_NETWORK;
}

static int ath6kl_set_host_app_area(struct ath6kl *ar)
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index a207377..4add0ef 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -22,10 +22,12 @@

struct ath6kl_sta *ath6kl_find_sta(struct ath6kl *ar, u8 *node_addr)
{
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
struct ath6kl_sta *conn = NULL;
u8 i, max_conn;

- max_conn = (ar->nw_type == AP_NETWORK) ? AP_MAX_NUM_STA : 0;
+ max_conn = (vif->nw_type == AP_NETWORK) ? AP_MAX_NUM_STA : 0;

for (i = 0; i < max_conn; i++) {
if (memcmp(node_addr, ar->sta_list[i].mac, ETH_ALEN) == 0) {
@@ -461,7 +463,7 @@ void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
*/
if (discon_issued)
ath6kl_disconnect_event(ar, DISCONNECT_CMD,
- (ar->nw_type & AP_NETWORK) ?
+ (vif->nw_type & AP_NETWORK) ?
bcast_mac : ar->bssid,
0, NULL, 0);

@@ -1058,7 +1060,7 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
memcpy(ar->bssid, bssid, sizeof(ar->bssid));
ar->bss_ch = channel;

- if ((ar->nw_type == INFRA_NETWORK))
+ if ((vif->nw_type == INFRA_NETWORK))
ath6kl_wmi_listeninterval_cmd(ar->wmi, ar->listen_intvl_t,
ar->listen_intvl_b);

@@ -1074,7 +1076,7 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
aggr_reset_state(ar->aggr_cntxt);
ar->reconnect_flag = 0;

- if ((ar->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) {
+ if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) {
memset(ar->node_map, 0, sizeof(ar->node_map));
ar->node_num = 0;
ar->next_ep_id = ENDPOINT_2;
@@ -1089,12 +1091,14 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast)
{
struct ath6kl_sta *sta;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
u8 tsc[6];
/*
* For AP case, keyid will have aid of STA which sent pkt with
* MIC error. Use this aid to get MAC & send it to hostapd.
*/
- if (ar->nw_type == AP_NETWORK) {
+ if (vif->nw_type == AP_NETWORK) {
sta = ath6kl_find_sta_by_aid(ar, (keyid >> 2));
if (!sta)
return;
@@ -1227,9 +1231,11 @@ void ath6kl_tgt_stats_event(struct ath6kl *ar, u8 *ptr, u32 len)
struct wmi_ap_mode_stat *p = (struct wmi_ap_mode_stat *) ptr;
struct wmi_ap_mode_stat *ap = &ar->ap_stats;
struct wmi_per_sta_stat *st_ap, *st_p;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
u8 ac;

- if (ar->nw_type == AP_NETWORK) {
+ if (vif->nw_type == AP_NETWORK) {
if (len < sizeof(*p))
return;

@@ -1357,7 +1363,7 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
/* TODO: Findout vif instead of taking it from ar */
struct ath6kl_vif *vif = ar->vif;

- if (ar->nw_type == AP_NETWORK) {
+ if (vif->nw_type == AP_NETWORK) {
if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))
return;

diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index d1652bd..6b1795c 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -258,7 +258,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
goto fail_tx;

/* AP mode Power saving processing */
- if (ar->nw_type == AP_NETWORK) {
+ if (vif->nw_type == AP_NETWORK) {
if (ath6kl_powersave_ap(ar, skb, &more_data))
return 0;
}
@@ -280,7 +280,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
goto fail_tx;
}

- if ((ar->nw_type == ADHOC_NETWORK) &&
+ if ((vif->nw_type == ADHOC_NETWORK) &&
ar->ibss_ps_enable && test_bit(CONNECTED, &vif->flags))
chk_adhoc_ps_mapping = true;
else {
@@ -450,7 +450,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
if (packet->info.tx.tag == ATH6KL_CONTROL_PKT_TAG)
return HTC_SEND_FULL_KEEP;

- if (ar->nw_type == ADHOC_NETWORK)
+ if (vif->nw_type == ADHOC_NETWORK)
/*
* In adhoc mode, we cannot differentiate traffic
* priorities so there is no need to continue, however we
@@ -484,9 +484,11 @@ stop_net_queues:
static void ath6kl_tx_clear_node_map(struct ath6kl *ar,
enum htc_endpoint_id eid, u32 map_no)
{
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
u32 i;

- if (ar->nw_type != ADHOC_NETWORK)
+ if (vif->nw_type != ADHOC_NETWORK)
return;

if (!ar->ibss_ps_enable)
@@ -1048,6 +1050,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
struct ath6kl_sta *conn = NULL;
struct sk_buff *skb1 = NULL;
struct ethhdr *datap = NULL;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
u16 seq_no, offset;
u8 tid;

@@ -1103,7 +1107,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
* that do not have LLC hdr. They are 16 bytes in size.
* Allow these frames in the AP mode.
*/
- if (ar->nw_type != AP_NETWORK &&
+ if (vif->nw_type != AP_NETWORK &&
((packet->act_len < min_hdr_len) ||
(packet->act_len > WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH))) {
ath6kl_info("frame len is too short or too long\n");
@@ -1114,7 +1118,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
}

/* Get the Power save state of the STA */
- if (ar->nw_type == AP_NETWORK) {
+ if (vif->nw_type == AP_NETWORK) {
meta_type = wmi_data_hdr_get_meta(dhdr);

ps_state = !!((dhdr->info >> WMI_DATA_HDR_PS_SHIFT) &
@@ -1227,7 +1231,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
return;
}

- if (ar->nw_type == AP_NETWORK) {
+ if (vif->nw_type == AP_NETWORK) {
datap = (struct ethhdr *) skb->data;
if (is_multicast_ether_addr(datap->h_dest))
/*
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index a71d773..701d26d 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -504,6 +504,8 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len)
u32 freq;
u16 dlen;
struct ath6kl *ar = wmi->parent_dev;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;

if (len < sizeof(*ev))
return -EINVAL;
@@ -520,7 +522,7 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len)
"probe_req_report=%d\n",
dlen, freq, ar->probe_req_report);

- if (ar->probe_req_report || ar->nw_type == AP_NETWORK)
+ if (ar->probe_req_report || vif->nw_type == AP_NETWORK)
cfg80211_rx_mgmt(ar->net_dev, freq, ev->data, dlen, GFP_ATOMIC);

return 0;
@@ -727,13 +729,15 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len)
struct wmi_connect_event *ev;
u8 *pie, *peie;
struct ath6kl *ar = wmi->parent_dev;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;

if (len < sizeof(struct wmi_connect_event))
return -EINVAL;

ev = (struct wmi_connect_event *) datap;

- if (ar->nw_type == AP_NETWORK) {
+ if (vif->nw_type == AP_NETWORK) {
/* AP mode start/STA connected event */
struct net_device *dev = ar->net_dev;
if (memcmp(dev->dev_addr, ev->u.ap_bss.bssid, ETH_ALEN) == 0) {
--
1.7.0.4


Subject: [PATCH V2 11/31] ath6kl: Move key information to vif structure

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 21 ++++++++++++---------
drivers/net/wireless/ath/ath6kl/core.h | 4 ++--
drivers/net/wireless/ath/ath6kl/init.c | 5 +++--
drivers/net/wireless/ath/ath6kl/main.c | 8 ++++----
4 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 76a6116..19d719b 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -419,7 +419,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
return -ENOENT;
}

- key = &ar->keys[sme->key_idx];
+ key = &vif->keys[sme->key_idx];
key->key_len = sme->key_len;
memcpy(key->key, sme->key, key->key_len);
key->cipher = vif->prwise_crypto;
@@ -856,7 +856,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
return -ENOENT;
}

- key = &ar->keys[key_index];
+ key = &vif->keys[key_index];
memset(key, 0, sizeof(struct ath6kl_key));

if (pairwise)
@@ -934,8 +934,9 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
*/
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration "
"until AP mode has been started\n");
- ar->wep_key_list[key_index].key_len = key->key_len;
- memcpy(ar->wep_key_list[key_index].key, key->key, key->key_len);
+ vif->wep_key_list[key_index].key_len = key->key_len;
+ memcpy(vif->wep_key_list[key_index].key, key->key,
+ key->key_len);
return 0;
}

@@ -955,6 +956,7 @@ static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
const u8 *mac_addr)
{
struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+ struct ath6kl_vif *vif = netdev_priv(ndev);

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);

@@ -968,13 +970,13 @@ static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
return -ENOENT;
}

- if (!ar->keys[key_index].key_len) {
+ if (!vif->keys[key_index].key_len) {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"%s: index %d is empty\n", __func__, key_index);
return 0;
}

- ar->keys[key_index].key_len = 0;
+ vif->keys[key_index].key_len = 0;

return ath6kl_wmi_deletekey_cmd(ar->wmi, key_index);
}
@@ -986,6 +988,7 @@ static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
struct key_params *))
{
struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+ struct ath6kl_vif *vif = netdev_priv(ndev);
struct ath6kl_key *key = NULL;
struct key_params params;

@@ -1001,7 +1004,7 @@ static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
return -ENOENT;
}

- key = &ar->keys[key_index];
+ key = &vif->keys[key_index];
memset(&params, 0, sizeof(params));
params.cipher = key->cipher;
params.key_len = key->key_len;
@@ -1038,14 +1041,14 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
return -ENOENT;
}

- if (!ar->keys[key_index].key_len) {
+ if (!vif->keys[key_index].key_len) {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
__func__, key_index);
return -EINVAL;
}

vif->def_txkey_index = key_index;
- key = &ar->keys[vif->def_txkey_index];
+ key = &vif->keys[vif->def_txkey_index];
key_usage = GROUP_USAGE;
if (vif->prwise_crypto == WEP_CRYPT)
key_usage |= TX_USAGE;
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index ab33244..dc21d7a 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -413,6 +413,8 @@ struct ath6kl_vif {
u8 req_bssid[ETH_ALEN];
u16 ch_hint;
u16 bss_ch;
+ struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
+ struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1];
};

/* Flag info */
@@ -441,7 +443,6 @@ struct ath6kl {
struct ath6kl_vif *vif;
spinlock_t lock;
struct semaphore sem;
- struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
u16 listen_intvl_b;
u16 listen_intvl_t;
u8 lrssi_roam_threshold;
@@ -480,7 +481,6 @@ struct ath6kl {
u8 rx_meta_ver;
struct wireless_dev *wdev;
struct cfg80211_scan_request *scan_req;
- struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1];
enum sme_state sme_state;
enum wlan_low_pwr_state wlan_pwr_state;
struct wmi_scan_params_cmd sc_params;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 09125cc..a26faae 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -87,7 +87,7 @@ void ath6kl_init_profile_info(struct ath6kl *ar)
vif->prwise_crypto_len = 0;
vif->grp_crypto = NONE_CRYPT;
vif->grp_crypto_len = 0;
- memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
+ memset(vif->wep_key_list, 0, sizeof(vif->wep_key_list));
memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
memset(vif->bssid, 0, sizeof(vif->bssid));
vif->bss_ch = 0;
@@ -248,11 +248,12 @@ static int ath6kl_init_service_ep(struct ath6kl *ar)

void ath6kl_init_control_info(struct ath6kl *ar)
{
+ /* TODO: Findout vif */
struct ath6kl_vif *vif = ar->vif;

ath6kl_init_profile_info(ar);
vif->def_txkey_index = 0;
- memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
+ memset(vif->wep_key_list, 0, sizeof(vif->wep_key_list));
vif->ch_hint = 0;
}

diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 15838de..eb2137c 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -506,7 +506,7 @@ static void ath6kl_install_static_wep_keys(struct ath6kl *ar)
u8 keyusage;

for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
- if (ar->wep_key_list[index].key_len) {
+ if (vif->wep_key_list[index].key_len) {
keyusage = GROUP_USAGE;
if (index == vif->def_txkey_index)
keyusage |= TX_USAGE;
@@ -515,9 +515,9 @@ static void ath6kl_install_static_wep_keys(struct ath6kl *ar)
index,
WEP_CRYPT,
keyusage,
- ar->wep_key_list[index].key_len,
+ vif->wep_key_list[index].key_len,
NULL,
- ar->wep_key_list[index].key,
+ vif->wep_key_list[index].key,
KEY_OP_INIT_VAL, NULL,
NO_SYNC_WMIFLAG);
}
@@ -1384,7 +1384,7 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
}

if (memcmp(ar->net_dev->dev_addr, bssid, ETH_ALEN) == 0) {
- memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
+ memset(vif->wep_key_list, 0, sizeof(vif->wep_key_list));
clear_bit(CONNECTED, &vif->flags);
}
return;
--
1.7.0.4


Subject: [PATCH V2 09/31] ath6kl: Move bssid information to vif structure

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 27 ++++++++++++++++-----------
drivers/net/wireless/ath/ath6kl/core.h | 4 ++--
drivers/net/wireless/ath/ath6kl/init.c | 4 ++--
drivers/net/wireless/ath/ath6kl/main.c | 8 ++++----
drivers/net/wireless/ath/ath6kl/wmi.c | 2 +-
5 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 5164e65..4861fd7 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -363,7 +363,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
vif->ssid_len == sme->ssid_len &&
!memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
ar->reconnect_flag = true;
- status = ath6kl_wmi_reconnect_cmd(ar->wmi, ar->req_bssid,
+ status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->req_bssid,
ar->ch_hint);

up(&ar->sem);
@@ -384,9 +384,9 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
if (sme->channel)
ar->ch_hint = sme->channel->center_freq;

- memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
+ memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
- memcpy(ar->req_bssid, sme->bssid, sizeof(ar->req_bssid));
+ memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));

ath6kl_set_wpa_version(ar, sme->crypto.wpa_versions);

@@ -461,7 +461,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
vif->prwise_crypto_len,
vif->grp_crypto, vif->grp_crypto_len,
vif->ssid_len, vif->ssid,
- ar->req_bssid, ar->ch_hint,
+ vif->req_bssid, ar->ch_hint,
ar->connect_ctrl_flags);

up(&ar->sem);
@@ -644,7 +644,7 @@ static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
vif->ssid_len = 0;

if (!test_bit(SKIP_SCAN, &ar->flag))
- memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
+ memset(vif->req_bssid, 0, sizeof(vif->req_bssid));

up(&ar->sem);

@@ -1071,10 +1071,13 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid,
bool ismcast)
{
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
+
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);

- cfg80211_michael_mic_failure(ar->net_dev, ar->bssid,
+ cfg80211_michael_mic_failure(ar->net_dev, vif->bssid,
(ismcast ? NL80211_KEYTYPE_GROUP :
NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
GFP_KERNEL);
@@ -1261,9 +1264,10 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
return -EOPNOTSUPP;
}

- memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
+ memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
- memcpy(ar->req_bssid, ibss_param->bssid, sizeof(ar->req_bssid));
+ memcpy(vif->req_bssid, ibss_param->bssid,
+ sizeof(vif->req_bssid));

ath6kl_set_wpa_version(ar, 0);

@@ -1296,7 +1300,7 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
vif->prwise_crypto_len,
vif->grp_crypto, vif->grp_crypto_len,
vif->ssid_len, vif->ssid,
- ar->req_bssid, ar->ch_hint,
+ vif->req_bssid, ar->ch_hint,
ar->connect_ctrl_flags);
set_bit(CONNECT_PEND, &vif->flags);

@@ -1399,7 +1403,7 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
int ret;
u8 mcs;

- if (memcmp(mac, ar->bssid, ETH_ALEN) != 0)
+ if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
return -ENOENT;

if (down_interruptible(&ar->sem))
@@ -1509,7 +1513,8 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
struct ath6kl_vif *vif = netdev_priv(netdev);

if (test_bit(CONNECTED, &vif->flags))
- return ath6kl_wmi_setpmkid_cmd(ar->wmi, ar->bssid, NULL, false);
+ return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->bssid,
+ NULL, false);
return 0;
}

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 714092a..298b339 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -409,6 +409,8 @@ struct ath6kl_vif {
u8 def_txkey_index;
u8 next_mode;
u8 nw_type;
+ u8 bssid[ETH_ALEN];
+ u8 req_bssid[ETH_ALEN];
};

/* Flag info */
@@ -438,8 +440,6 @@ struct ath6kl {
spinlock_t lock;
struct semaphore sem;
struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
- u8 bssid[ETH_ALEN];
- u8 req_bssid[ETH_ALEN];
u16 ch_hint;
u16 bss_ch;
u16 listen_intvl_b;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index e6f4dde..a43bb29 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -88,8 +88,8 @@ void ath6kl_init_profile_info(struct ath6kl *ar)
vif->grp_crypto = NONE_CRYPT;
vif->grp_crypto_len = 0;
memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
- memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
- memset(ar->bssid, 0, sizeof(ar->bssid));
+ memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
+ memset(vif->bssid, 0, sizeof(vif->bssid));
ar->bss_ch = 0;
vif->nw_type = vif->next_mode = INFRA_NETWORK;
}
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 4add0ef..bdefb89 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -464,7 +464,7 @@ void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
if (discon_issued)
ath6kl_disconnect_event(ar, DISCONNECT_CMD,
(vif->nw_type & AP_NETWORK) ?
- bcast_mac : ar->bssid,
+ bcast_mac : vif->bssid,
0, NULL, 0);

ar->user_key_ctrl = 0;
@@ -943,7 +943,7 @@ void ath6kl_deep_sleep_enable(struct ath6kl *ar)

switch (ar->sme_state) {
case SME_CONNECTING:
- cfg80211_connect_result(ar->net_dev, ar->bssid, NULL, 0,
+ cfg80211_connect_result(ar->net_dev, vif->bssid, NULL, 0,
NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
@@ -1057,7 +1057,7 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
assoc_req_len, assoc_resp_len,
assoc_info);

- memcpy(ar->bssid, bssid, sizeof(ar->bssid));
+ memcpy(vif->bssid, bssid, sizeof(vif->bssid));
ar->bss_ch = channel;

if ((vif->nw_type == INFRA_NETWORK))
@@ -1433,7 +1433,7 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
ar->user_key_ctrl = 0;

netif_stop_queue(ar->net_dev);
- memset(ar->bssid, 0, sizeof(ar->bssid));
+ memset(vif->bssid, 0, sizeof(vif->bssid));
ar->bss_ch = 0;

ath6kl_tx_data_cleanup(ar);
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 701d26d..2f4e8b5 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -988,7 +988,7 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
return -EINVAL;

if (bih->frame_type == BEACON_FTYPE && test_bit(CONNECTED, &vif->flags)
- && memcmp(bih->bssid, ar->bssid, ETH_ALEN) == 0) {
+ && memcmp(bih->bssid, vif->bssid, ETH_ALEN) == 0) {
const u8 *tim;
tim = cfg80211_find_ie(WLAN_EID_TIM, buf + 8 + 2 + 2,
len - 8 - 2 - 2);
--
1.7.0.4


Subject: [PATCH V2 03/31] ath6kl: Refactor wiphy dev and net dev init functions

This refactoring is done in a manner that it can be used
for multiple virtual interface.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 146 +++++++++++++++++++++++----
drivers/net/wireless/ath/ath6kl/cfg80211.h | 7 +-
drivers/net/wireless/ath/ath6kl/core.h | 3 +
drivers/net/wireless/ath/ath6kl/init.c | 149 +++++++---------------------
drivers/net/wireless/ath/ath6kl/sdio.c | 8 +-
5 files changed, 173 insertions(+), 140 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 16c21a4..fcddf1a 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1918,45 +1918,83 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
.mgmt_frame_register = ath6kl_mgmt_frame_register,
};

-struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
+struct ath6kl *ath6kl_core_alloc(struct device *dev)
{
- int ret = 0;
- struct wireless_dev *wdev;
struct ath6kl *ar;
struct wiphy *wiphy;
-
- wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
- if (!wdev) {
- ath6kl_err("couldn't allocate wireless device\n");
- return NULL;
- }
+ u8 ctr;

/* create a new wiphy for use with cfg80211 */
wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
+
if (!wiphy) {
ath6kl_err("couldn't allocate wiphy device\n");
- kfree(wdev);
return NULL;
}

ar = wiphy_priv(wiphy);
ar->p2p = !!ath6kl_p2p;
ar->wiphy = wiphy;
- wdev->wiphy = wiphy;
+ ar->dev = dev;
+
+ spin_lock_init(&ar->lock);
+ spin_lock_init(&ar->mcastpsq_lock);
+
+ init_waitqueue_head(&ar->event_wq);
+ sema_init(&ar->sem, 1);
+
+ INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
+
+ clear_bit(WMI_ENABLED, &ar->flag);
+ clear_bit(SKIP_SCAN, &ar->flag);
+ clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
+
+ ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL;
+ ar->listen_intvl_b = 0;
+ ar->tx_pwr = 0;
+
+ ar->intra_bss = 1;
+ memset(&ar->sc_params, 0, sizeof(ar->sc_params));
+ ar->sc_params.short_scan_ratio = WMI_SHORTSCANRATIO_DEFAULT;
+ ar->sc_params.scan_ctrl_flags = DEFAULT_SCAN_CTRL_FLAGS;
+ ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD;
+
+ memset((u8 *)ar->sta_list, 0,
+ AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
+
+ /* Init the PS queues */
+ for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
+ spin_lock_init(&ar->sta_list[ctr].psq_lock);
+ skb_queue_head_init(&ar->sta_list[ctr].psq);
+ }
+
+ skb_queue_head_init(&ar->mcastpsq);
+
+ memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
+
+ return ar;
+}
+
+int ath6kl_register_ieee80211_hw(struct ath6kl *ar)
+{
+ struct wiphy *wiphy = ar->wiphy;
+ int ret;

wiphy->mgmt_stypes = ath6kl_mgmt_stypes;

wiphy->max_remain_on_channel_duration = 5000;

/* set device pointer for wiphy */
- set_wiphy_dev(wiphy, dev);
+ set_wiphy_dev(wiphy, ar->dev);

wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_AP);
if (ar->p2p) {
wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
- BIT(NL80211_IFTYPE_P2P_CLIENT);
+ BIT(NL80211_IFTYPE_P2P_CLIENT);
}
+
/* max num of ssids that can be probed during scanning */
wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
@@ -1970,18 +2008,85 @@ struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
ret = wiphy_register(wiphy);
if (ret < 0) {
ath6kl_err("couldn't register wiphy device\n");
- wiphy_free(wiphy);
- kfree(wdev);
- return NULL;
+ return ret;
}

- return wdev;
+ return 0;
}

-void ath6kl_cfg80211_deinit(struct ath6kl *ar)
+static int ath6kl_init_if_data(struct ath6kl *ar, struct net_device *ndev)
{
- struct wireless_dev *wdev = ar->wdev;
+ ar->aggr_cntxt = aggr_init(ndev);
+ if (!ar->aggr_cntxt) {
+ ath6kl_err("failed to initialize aggr\n");
+ return -ENOMEM;
+ }
+
+ setup_timer(&ar->disconnect_timer, disconnect_timer_handler,
+ (unsigned long) ndev);

+ return 0;
+}
+
+void ath6kl_deinit_if_data(struct ath6kl *ar, struct net_device *ndev)
+{
+ aggr_module_destroy(ar->aggr_cntxt);
+
+ ar->aggr_cntxt = NULL;
+
+ if (test_bit(NETDEV_REGISTERED, &ar->flag)) {
+ unregister_netdev(ndev);
+ clear_bit(NETDEV_REGISTERED, &ar->flag);
+ }
+
+ free_netdev(ndev);
+}
+
+struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
+ enum nl80211_iftype type)
+{
+ struct net_device *ndev;
+ struct wireless_dev *wdev;
+
+ ndev = alloc_netdev(sizeof(*wdev), "wlan%d", ether_setup);
+ if (!ndev)
+ return NULL;
+
+ wdev = netdev_priv(ndev);
+ ndev->ieee80211_ptr = wdev;
+ wdev->wiphy = ar->wiphy;
+ SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
+ wdev->netdev = ndev;
+ wdev->iftype = type;
+ ar->wdev = wdev;
+ ar->net_dev = ndev;
+
+ init_netdev(ndev);
+
+ ath6kl_init_control_info(ar);
+
+ /* TODO: Pass interface specific pointer instead of ar */
+ if (ath6kl_init_if_data(ar, ndev))
+ goto err;
+
+ if (register_netdev(ndev))
+ goto err;
+
+ ar->sme_state = SME_DISCONNECTED;
+ set_bit(WLAN_ENABLED, &ar->flag);
+ ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
+ set_bit(NETDEV_REGISTERED, &ar->flag);
+
+ return ndev;
+
+err:
+ ath6kl_deinit_if_data(ar, ndev);
+
+ return NULL;
+}
+
+void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar)
+{
if (ar->scan_req) {
cfg80211_scan_done(ar->scan_req, true);
ar->scan_req = NULL;
@@ -1989,5 +2094,4 @@ void ath6kl_cfg80211_deinit(struct ath6kl *ar)

wiphy_unregister(ar->wiphy);
wiphy_free(ar->wiphy);
- kfree(wdev);
}
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h
index a84adc2..5daf685 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.h
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h
@@ -17,8 +17,11 @@
#ifndef ATH6KL_CFG80211_H
#define ATH6KL_CFG80211_H

-struct wireless_dev *ath6kl_cfg80211_init(struct device *dev);
-void ath6kl_cfg80211_deinit(struct ath6kl *ar);
+struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
+ enum nl80211_iftype type);
+int ath6kl_register_ieee80211_hw(struct ath6kl *ar);
+struct ath6kl *ath6kl_core_alloc(struct device *dev);
+void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar);

void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status);

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index fb5a322..f1b3c47 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -642,4 +642,7 @@ void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no,
void ath6kl_wakeup_event(void *dev);
void ath6kl_target_failure(struct ath6kl *ar);

+void ath6kl_init_control_info(struct ath6kl *ar);
+void ath6kl_deinit_if_data(struct ath6kl *ar, struct net_device *ndev);
+void ath6kl_core_free(struct ath6kl *ar);
#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 0b24c90..6bbfe6f 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -258,40 +258,12 @@ static int ath6kl_init_service_ep(struct ath6kl *ar)
return 0;
}

-static void ath6kl_init_control_info(struct ath6kl *ar)
+void ath6kl_init_control_info(struct ath6kl *ar)
{
- u8 ctr;
-
- clear_bit(WMI_ENABLED, &ar->flag);
ath6kl_init_profile_info(ar);
ar->def_txkey_index = 0;
memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
ar->ch_hint = 0;
- ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL;
- ar->listen_intvl_b = 0;
- ar->tx_pwr = 0;
- clear_bit(SKIP_SCAN, &ar->flag);
- set_bit(WMM_ENABLED, &ar->flag);
- ar->intra_bss = 1;
- memset(&ar->sc_params, 0, sizeof(ar->sc_params));
- ar->sc_params.short_scan_ratio = WMI_SHORTSCANRATIO_DEFAULT;
- ar->sc_params.scan_ctrl_flags = DEFAULT_SCAN_CTRL_FLAGS;
- ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD;
-
- memset((u8 *)ar->sta_list, 0,
- AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
-
- spin_lock_init(&ar->mcastpsq_lock);
-
- /* Init the PS queues */
- for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
- spin_lock_init(&ar->sta_list[ctr].psq_lock);
- skb_queue_head_init(&ar->sta_list[ctr].psq);
- }
-
- skb_queue_head_init(&ar->mcastpsq);
-
- memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
}

/*
@@ -553,61 +525,9 @@ int ath6kl_configure_target(struct ath6kl *ar)
return 0;
}

-struct ath6kl *ath6kl_core_alloc(struct device *sdev)
+void ath6kl_core_free(struct ath6kl *ar)
{
- struct net_device *dev;
- struct ath6kl *ar;
- struct wireless_dev *wdev;
-
- wdev = ath6kl_cfg80211_init(sdev);
- if (!wdev) {
- ath6kl_err("ath6kl_cfg80211_init failed\n");
- return NULL;
- }
-
- ar = wdev_priv(wdev);
- ar->dev = sdev;
- ar->wdev = wdev;
- wdev->iftype = NL80211_IFTYPE_STATION;
-
- if (ath6kl_debug_init(ar)) {
- ath6kl_err("Failed to initialize debugfs\n");
- ath6kl_cfg80211_deinit(ar);
- return NULL;
- }
-
- dev = alloc_netdev(0, "wlan%d", ether_setup);
- if (!dev) {
- ath6kl_err("no memory for network device instance\n");
- ath6kl_cfg80211_deinit(ar);
- return NULL;
- }
-
- dev->ieee80211_ptr = wdev;
- SET_NETDEV_DEV(dev, wiphy_dev(ar->wiphy));
- wdev->netdev = dev;
- ar->sme_state = SME_DISCONNECTED;
-
- init_netdev(dev);
-
- ar->net_dev = dev;
- set_bit(WLAN_ENABLED, &ar->flag);
-
- ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
-
- spin_lock_init(&ar->lock);
-
- ath6kl_init_control_info(ar);
- init_waitqueue_head(&ar->event_wq);
- sema_init(&ar->sem, 1);
- clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
-
- INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
-
- setup_timer(&ar->disconnect_timer, disconnect_timer_handler,
- (unsigned long) dev);
-
- return ar;
+ wiphy_free(ar->wiphy);
}

int ath6kl_unavail_ev(struct ath6kl *ar)
@@ -1465,6 +1385,7 @@ static int ath6kl_init(struct ath6kl *ar)
{
int status = 0;
s32 timeleft;
+ struct net_device *ndev;

if (!ar)
return -EIO;
@@ -1486,6 +1407,29 @@ static int ath6kl_init(struct ath6kl *ar)

ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);

+ status = ath6kl_register_ieee80211_hw(ar);
+ if (status)
+ goto err_node_cleanup;
+
+ status = ath6kl_debug_init(ar);
+ if (status) {
+ wiphy_unregister(ar->wiphy);
+ goto err_node_cleanup;
+ }
+
+ /* Add an initial station interface */
+ ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION);
+ if (!ndev) {
+ ath6kl_err("Failed to instantiate a network device\n");
+ status = -ENOMEM;
+ wiphy_unregister(ar->wiphy);
+ goto err_debug_init;
+ }
+
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
+ __func__, ar->net_dev->name, ar->net_dev, ar);
+
/*
* The reason we have to wait for the target here is that the
* driver layer has to init BMI in order to set the host block
@@ -1493,7 +1437,7 @@ static int ath6kl_init(struct ath6kl *ar)
*/
if (ath6kl_htc_wait_target(ar->htc_target)) {
status = -EIO;
- goto err_node_cleanup;
+ goto err_if_deinit;
}

if (ath6kl_init_service_ep(ar)) {
@@ -1570,6 +1514,11 @@ err_rxbuf_cleanup:
ath6kl_cleanup_amsdu_rxbufs(ar);
err_cleanup_scatter:
ath6kl_hif_cleanup_scatter(ar);
+err_if_deinit:
+ ath6kl_deinit_if_data(ar, ndev);
+ wiphy_unregister(ar->wiphy);
+err_debug_init:
+ ath6kl_debug_cleanup(ar);
err_node_cleanup:
ath6kl_wmi_shutdown(ar->wmi);
clear_bit(WMI_ENABLED, &ar->flag);
@@ -1615,13 +1564,6 @@ int ath6kl_core_init(struct ath6kl *ar)
goto err_bmi_cleanup;
}

- ar->aggr_cntxt = aggr_init(ar->net_dev);
- if (!ar->aggr_cntxt) {
- ath6kl_err("failed to initialize aggr\n");
- ret = -ENOMEM;
- goto err_htc_cleanup;
- }
-
ret = ath6kl_fetch_firmwares(ar);
if (ret)
goto err_htc_cleanup;
@@ -1634,19 +1576,6 @@ int ath6kl_core_init(struct ath6kl *ar)
if (ret)
goto err_htc_cleanup;

- /* This runs the init function if registered */
- ret = register_netdev(ar->net_dev);
- if (ret) {
- ath6kl_err("register_netdev failed\n");
- ath6kl_destroy(ar->net_dev, 0);
- return ret;
- }
-
- set_bit(NETDEV_REGISTERED, &ar->flag);
-
- ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
- __func__, ar->net_dev->name, ar->net_dev, ar);
-
return ret;

err_htc_cleanup:
@@ -1655,6 +1584,7 @@ err_bmi_cleanup:
ath6kl_bmi_cleanup(ar);
err_wq:
destroy_workqueue(ar->ath6kl_wq);
+
return ret;
}

@@ -1710,8 +1640,6 @@ void ath6kl_destroy(struct net_device *dev, unsigned int unregister)
if (ar->htc_target)
ath6kl_htc_cleanup(ar->htc_target);

- aggr_module_destroy(ar->aggr_cntxt);
-
ath6kl_cookie_cleanup(ar);

ath6kl_cleanup_amsdu_rxbufs(ar);
@@ -1720,17 +1648,12 @@ void ath6kl_destroy(struct net_device *dev, unsigned int unregister)

ath6kl_debug_cleanup(ar);

- if (unregister && test_bit(NETDEV_REGISTERED, &ar->flag)) {
- unregister_netdev(dev);
- clear_bit(NETDEV_REGISTERED, &ar->flag);
- }
-
- free_netdev(dev);
+ ath6kl_deinit_if_data(ar, dev);

kfree(ar->fw_board);
kfree(ar->fw_otp);
kfree(ar->fw);
kfree(ar->fw_patch);

- ath6kl_cfg80211_deinit(ar);
+ ath6kl_deinit_ieee80211_hw(ar);
}
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 58e31f6..4e43878 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -837,7 +837,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
ath6kl_err("Failed to enable 4-bit async irq mode %d\n",
ret);
sdio_release_host(func);
- goto err_cfg80211;
+ goto err_core_alloc;
}

ath6kl_dbg(ATH6KL_DBG_SDIO, "4-bit async irq mode enabled\n");
@@ -850,7 +850,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,

ret = ath6kl_sdio_power_on(ar_sdio);
if (ret)
- goto err_cfg80211;
+ goto err_core_alloc;

sdio_claim_host(func);

@@ -874,8 +874,8 @@ static int ath6kl_sdio_probe(struct sdio_func *func,

err_off:
ath6kl_sdio_power_off(ar_sdio);
-err_cfg80211:
- ath6kl_cfg80211_deinit(ar_sdio->ar);
+err_core_alloc:
+ ath6kl_core_free(ar_sdio->ar);
err_dma:
kfree(ar_sdio->dma_buffer);
err_hif:
--
1.7.0.4


Subject: [PATCH V2 04/31] ath6kl: Cleanup fw interface type setting

It is not necessary to use ath6kl_get_fw_iftype() to find out the
firmware interface type during initialization because the type
of the initial interface in INFRA_NETWORK. Hardcode the fw interface
type corresponding to INFRA_BSS instead of using ath6kl_get_fw_iftype().

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/init.c | 19 +------------------
1 files changed, 1 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 6bbfe6f..7720177 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -91,21 +91,6 @@ void ath6kl_init_profile_info(struct ath6kl *ar)
ar->nw_type = ar->next_mode = INFRA_NETWORK;
}

-static u8 ath6kl_get_fw_iftype(struct ath6kl *ar)
-{
- switch (ar->nw_type) {
- case INFRA_NETWORK:
- return HI_OPTION_FW_MODE_BSS_STA;
- case ADHOC_NETWORK:
- return HI_OPTION_FW_MODE_IBSS;
- case AP_NETWORK:
- return HI_OPTION_FW_MODE_AP;
- default:
- ath6kl_err("Unsupported interface type :%d\n", ar->nw_type);
- return 0xff;
- }
-}
-
static int ath6kl_set_host_app_area(struct ath6kl *ar)
{
u32 address, data;
@@ -446,9 +431,7 @@ int ath6kl_configure_target(struct ath6kl *ar)
u32 param, ram_reserved_size;
u8 fw_iftype;

- fw_iftype = ath6kl_get_fw_iftype(ar);
- if (fw_iftype == 0xff)
- return -EINVAL;
+ fw_iftype = HI_OPTION_FW_MODE_BSS_STA;

/* Tell target which HTC version it is used*/
param = HTC_PROTOCOL_VERSION;
--
1.7.0.4


Subject: [PATCH V2 12/31] ath6kl: Move aggregation information to vif structure

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 10 ++++------
drivers/net/wireless/ath/ath6kl/core.h | 2 +-
drivers/net/wireless/ath/ath6kl/main.c | 4 ++--
drivers/net/wireless/ath/ath6kl/txrx.c | 10 +++++++---
4 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 19d719b..5959c84 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -2063,8 +2063,8 @@ static int ath6kl_init_if_data(struct ath6kl_vif *vif)
{
struct ath6kl *ar = vif->ar;

- ar->aggr_cntxt = aggr_init(vif->ndev);
- if (!ar->aggr_cntxt) {
+ vif->aggr_cntxt = aggr_init(vif->ndev);
+ if (!vif->aggr_cntxt) {
ath6kl_err("failed to initialize aggr\n");
return -ENOMEM;
}
@@ -2077,11 +2077,9 @@ static int ath6kl_init_if_data(struct ath6kl_vif *vif)

void ath6kl_deinit_if_data(struct ath6kl_vif *vif)
{
- struct ath6kl *ar = vif->ar;
-
- aggr_module_destroy(ar->aggr_cntxt);
+ aggr_module_destroy(vif->aggr_cntxt);

- ar->aggr_cntxt = NULL;
+ vif->aggr_cntxt = NULL;

if (test_bit(NETDEV_REGISTERED, &vif->flags)) {
unregister_netdev(vif->ndev);
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index dc21d7a..f15dd6d 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -415,6 +415,7 @@ struct ath6kl_vif {
u16 bss_ch;
struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1];
+ struct aggr_info *aggr_cntxt;
};

/* Flag info */
@@ -473,7 +474,6 @@ struct ath6kl {
struct sk_buff_head mcastpsq;
spinlock_t mcastpsq_lock;
u8 intra_bss;
- struct aggr_info *aggr_cntxt;
struct wmi_ap_mode_stat ap_stats;
u8 ap_country_code[3];
struct list_head amsdu_rx_buffer_queue;
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index eb2137c..0bdb73c 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -1073,7 +1073,7 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
netif_carrier_on(ar->net_dev);
spin_unlock_bh(&ar->lock);

- aggr_reset_state(ar->aggr_cntxt);
+ aggr_reset_state(vif->aggr_cntxt);
ar->reconnect_flag = 0;

if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) {
@@ -1394,7 +1394,7 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
assoc_resp_len, assoc_info,
prot_reason_status);

- aggr_reset_state(ar->aggr_cntxt);
+ aggr_reset_state(vif->aggr_cntxt);

del_timer(&ar->disconnect_timer);

diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 6b1795c..ba1678e 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -1268,7 +1268,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
datap = (struct ethhdr *) skb->data;

if (is_unicast_ether_addr(datap->h_dest) &&
- aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no,
+ aggr_process_recv_frm(vif->aggr_cntxt, tid, seq_no,
is_amsdu, skb))
/* aggregation code will handle the skb */
return;
@@ -1353,7 +1353,9 @@ static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)

void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no, u8 win_sz)
{
- struct aggr_info *p_aggr = ar->aggr_cntxt;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
+ struct aggr_info *p_aggr = vif->aggr_cntxt;
struct rxtid *rxtid;
struct rxtid_stats *stats;
u16 hold_q_size;
@@ -1422,7 +1424,9 @@ struct aggr_info *aggr_init(struct net_device *dev)

void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid)
{
- struct aggr_info *p_aggr = ar->aggr_cntxt;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
+ struct aggr_info *p_aggr = vif->aggr_cntxt;
struct rxtid *rxtid;

if (!p_aggr)
--
1.7.0.4


Subject: [PATCH V2 15/31] ath6kl: Move few more vif specific information to struct ath6kl_vif

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 25 +++++++++++++------------
drivers/net/wireless/ath/ath6kl/core.h | 13 ++++++-------
drivers/net/wireless/ath/ath6kl/main.c | 8 ++++----
drivers/net/wireless/ath/ath6kl/wmi.c | 6 +++---
4 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index acc5c86..fa206be 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -362,7 +362,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
if (test_bit(CONNECTED, &vif->flags) &&
vif->ssid_len == sme->ssid_len &&
!memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
- ar->reconnect_flag = true;
+ vif->reconnect_flag = true;
status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->req_bssid,
vif->ch_hint);

@@ -454,7 +454,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
vif->prwise_crypto_len, vif->grp_crypto,
vif->grp_crypto_len, vif->ch_hint);

- ar->reconnect_flag = 0;
+ vif->reconnect_flag = 0;
status = ath6kl_wmi_connect_cmd(ar->wmi, vif->nw_type,
vif->dot11_auth_mode, vif->auth_mode,
vif->prwise_crypto,
@@ -566,7 +566,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
* Store Beacon interval here; DTIM period will be available only once
* a Beacon frame from the AP is seen.
*/
- ar->assoc_bss_beacon_int = beacon_intvl;
+ vif->assoc_bss_beacon_int = beacon_intvl;
clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);

if (nw_type & ADHOC_NETWORK) {
@@ -638,7 +638,7 @@ static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
return -ERESTARTSYS;
}

- ar->reconnect_flag = 0;
+ vif->reconnect_flag = 0;
ath6kl_disconnect(ar);
memset(vif->ssid, 0, sizeof(vif->ssid));
vif->ssid_len = 0;
@@ -1489,8 +1489,8 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
vif->nw_type == INFRA_NETWORK) {
sinfo->filled |= STATION_INFO_BSS_PARAM;
sinfo->bss_param.flags = 0;
- sinfo->bss_param.dtim_period = ar->assoc_bss_dtim_period;
- sinfo->bss_param.beacon_interval = ar->assoc_bss_beacon_int;
+ sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
+ sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
}

return 0;
@@ -1545,13 +1545,14 @@ static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
enum nl80211_channel_type channel_type)
{
struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);

if (!ath6kl_cfg80211_ready(ar))
return -EIO;

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
__func__, chan->center_freq, chan->hw_value);
- ar->next_chan = chan->center_freq;
+ vif->next_chan = chan->center_freq;

return 0;
}
@@ -1731,7 +1732,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
p.ssid_len = vif->ssid_len;
memcpy(p.ssid, vif->ssid, vif->ssid_len);
p.dot11_auth_mode = vif->dot11_auth_mode;
- p.ch = cpu_to_le16(ar->next_chan);
+ p.ch = cpu_to_le16(vif->next_chan);

res = ath6kl_wmi_ap_profile_commit(ar->wmi, &p);
if (res < 0)
@@ -1876,13 +1877,13 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
chan->center_freq);
}

- id = ar->send_action_id++;
+ id = vif->send_action_id++;
if (id == 0) {
/*
* 0 is a reserved value in the WMI command and shall not be
* used for the command.
*/
- id = ar->send_action_id++;
+ id = vif->send_action_id++;
}

*cookie = id;
@@ -1894,7 +1895,7 @@ static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
struct net_device *dev,
u16 frame_type, bool reg)
{
- struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
__func__, frame_type, reg);
@@ -1904,7 +1905,7 @@ static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
* we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
* hardcode target to report Probe Request frames all the time.
*/
- ar->probe_req_report = reg;
+ vif->probe_req_report = reg;
}
}

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index e949a3b..ba780eb 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -419,6 +419,12 @@ struct ath6kl_vif {
struct timer_list disconnect_timer;
struct cfg80211_scan_request *scan_req;
enum sme_state sme_state;
+ int reconnect_flag;
+ u32 send_action_id;
+ bool probe_req_report;
+ u16 next_chan;
+ u16 assoc_bss_beacon_int;
+ u8 assoc_bss_dtim_period;
};

/* Flag info */
@@ -503,7 +509,6 @@ struct ath6kl {
struct ath6kl_mbox_info mbox_info;

struct ath6kl_cookie cookie_mem[MAX_COOKIE_NUM];
- int reconnect_flag;
unsigned long flag;

u8 *fw_board;
@@ -524,13 +529,7 @@ struct ath6kl {

struct dentry *debugfs_phy;

- u32 send_action_id;
- bool probe_req_report;
- u16 next_chan;
-
bool p2p;
- u16 assoc_bss_beacon_int;
- u8 assoc_bss_dtim_period;

#ifdef CONFIG_ATH6KL_DEBUG
struct {
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 204901d..b91ac7e 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -1074,7 +1074,7 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
spin_unlock_bh(&ar->lock);

aggr_reset_state(vif->aggr_cntxt);
- ar->reconnect_flag = 0;
+ vif->reconnect_flag = 0;

if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) {
memset(ar->node_map, 0, sizeof(ar->node_map));
@@ -1414,7 +1414,7 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
if (((reason == ASSOC_FAILED) &&
(prot_reason_status == 0x11)) ||
((reason == ASSOC_FAILED) && (prot_reason_status == 0x0)
- && (ar->reconnect_flag == 1))) {
+ && (vif->reconnect_flag == 1))) {
set_bit(CONNECTED, &vif->flags);
return;
}
@@ -1426,8 +1426,8 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
netif_carrier_off(ar->net_dev);
spin_unlock_bh(&ar->lock);

- if ((reason != CSERV_DISCONNECT) || (ar->reconnect_flag != 1))
- ar->reconnect_flag = 0;
+ if ((reason != CSERV_DISCONNECT) || (vif->reconnect_flag != 1))
+ vif->reconnect_flag = 0;

if (reason != CSERV_DISCONNECT)
ar->user_key_ctrl = 0;
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 2f4e8b5..8e7e7b5 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -520,9 +520,9 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len)
}
ath6kl_dbg(ATH6KL_DBG_WMI, "rx_probe_req: len=%u freq=%u "
"probe_req_report=%d\n",
- dlen, freq, ar->probe_req_report);
+ dlen, freq, vif->probe_req_report);

- if (ar->probe_req_report || vif->nw_type == AP_NETWORK)
+ if (vif->probe_req_report || vif->nw_type == AP_NETWORK)
cfg80211_rx_mgmt(ar->net_dev, freq, ev->data, dlen, GFP_ATOMIC);

return 0;
@@ -993,7 +993,7 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
tim = cfg80211_find_ie(WLAN_EID_TIM, buf + 8 + 2 + 2,
len - 8 - 2 - 2);
if (tim && tim[1] >= 2) {
- ar->assoc_bss_dtim_period = tim[3];
+ vif->assoc_bss_dtim_period = tim[3];
set_bit(DTIM_PERIOD_AVAIL, &vif->flags);
}
}
--
1.7.0.4


Subject: [PATCH V2 19/31] ath6kl: Remove net_device from ath6kl

Use one which is available in vif structure instead.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 1 -
drivers/net/wireless/ath/ath6kl/core.h | 1 -
drivers/net/wireless/ath/ath6kl/init.c | 6 +++---
drivers/net/wireless/ath/ath6kl/main.c | 6 +++---
drivers/net/wireless/ath/ath6kl/txrx.c | 16 ++++++++--------
5 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index e870c9c..636b64e 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -2115,7 +2115,6 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
vif->wdev.iftype = type;
vif->fw_vif_idx = fw_vif_idx;
ar->wdev = &vif->wdev;
- ar->net_dev = ndev;

init_netdev(ndev);

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 3fb8898..4db0b15 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -446,7 +446,6 @@ enum ath6kl_dev_state {

struct ath6kl {
struct device *dev;
- struct net_device *net_dev;
struct wiphy *wiphy;
struct ath6kl_bmi bmi;
const struct ath6kl_hif_ops *hif_ops;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index fb78a2a..a874665 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -521,7 +521,7 @@ void ath6kl_core_free(struct ath6kl *ar)

int ath6kl_unavail_ev(struct ath6kl *ar)
{
- ath6kl_destroy(ar->net_dev, 1);
+ ath6kl_destroy(ar->vif->ndev, 1);

return 0;
}
@@ -1417,7 +1417,7 @@ static int ath6kl_init(struct ath6kl *ar)


ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
- __func__, ar->net_dev->name, ar->net_dev, ar);
+ __func__, ndev->name, ndev, ar);

/*
* The reason we have to wait for the target here is that the
@@ -1579,8 +1579,8 @@ err_wq:

void ath6kl_stop_txrx(struct ath6kl *ar)
{
- struct net_device *ndev = ar->net_dev;
struct ath6kl_vif *vif = ar->vif;
+ struct net_device *ndev = vif->ndev;

if (!ndev)
return;
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 19b64ae..023624d 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -938,7 +938,7 @@ void ath6kl_deep_sleep_enable(struct ath6kl *ar)

switch (vif->sme_state) {
case SME_CONNECTING:
- cfg80211_connect_result(ar->net_dev, vif->bssid, NULL, 0,
+ cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
@@ -950,7 +950,7 @@ void ath6kl_deep_sleep_enable(struct ath6kl *ar)
* suspend, why? Need to send disconnected event in that
* state.
*/
- cfg80211_disconnected(ar->net_dev, 0, NULL, 0, GFP_KERNEL);
+ cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL);
break;
}

@@ -995,7 +995,7 @@ static const char *get_hw_id_string(u32 id)
void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
{
struct ath6kl *ar = devt;
- struct net_device *dev = ar->net_dev;
+ struct net_device *dev = ar->vif->ndev;

memcpy(dev->dev_addr, datap, ETH_ALEN);
ath6kl_dbg(ATH6KL_DBG_TRC, "%s: mac addr = %pM\n",
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 50ff9a4..7e2d601 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -478,7 +478,7 @@ stop_net_queues:
spin_lock_bh(&ar->lock);
set_bit(NETQ_STOPPED, &vif->flags);
spin_unlock_bh(&ar->lock);
- netif_stop_queue(ar->net_dev);
+ netif_stop_queue(vif->ndev);

return HTC_SEND_FULL_KEEP;
}
@@ -619,7 +619,7 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue)

if (test_bit(CONNECTED, &vif->flags)) {
if (!flushing)
- netif_wake_queue(ar->net_dev);
+ netif_wake_queue(vif->ndev);
}

if (wake_event)
@@ -1086,12 +1086,12 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ",
skb->data, skb->len);

- skb->dev = ar->net_dev;
+ skb->dev = vif->ndev;

if (!test_bit(WMI_ENABLED, &ar->flag)) {
if (EPPING_ALIGNMENT_PAD > 0)
skb_pull(skb, EPPING_ALIGNMENT_PAD);
- ath6kl_deliver_frames_to_nw_stack(ar->net_dev, skb);
+ ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb);
return;
}

@@ -1174,7 +1174,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
while ((skbuff = skb_dequeue(&conn->psq))
!= NULL) {
spin_unlock_bh(&conn->psq_lock);
- ath6kl_data_tx(skbuff, ar->net_dev);
+ ath6kl_data_tx(skbuff, vif->ndev);
spin_lock_bh(&conn->psq_lock);
}
spin_unlock_bh(&conn->psq_lock);
@@ -1230,7 +1230,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
return;
}

- if (!(ar->net_dev->flags & IFF_UP)) {
+ if (!(vif->ndev->flags & IFF_UP)) {
dev_kfree_skb(skb);
return;
}
@@ -1261,7 +1261,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
}
}
if (skb1)
- ath6kl_data_tx(skb1, ar->net_dev);
+ ath6kl_data_tx(skb1, vif->ndev);

if (skb == NULL) {
/* nothing to deliver up the stack */
@@ -1277,7 +1277,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
/* aggregation code will handle the skb */
return;

- ath6kl_deliver_frames_to_nw_stack(ar->net_dev, skb);
+ ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb);
}

static void aggr_timeout(unsigned long arg)
--
1.7.0.4


Subject: [PATCH V2 14/31] ath6kl: Move scan_req info and sme_state to vif

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 49 +++++++++++++++------------
drivers/net/wireless/ath/ath6kl/core.h | 4 +-
drivers/net/wireless/ath/ath6kl/main.c | 4 +-
3 files changed, 31 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index d55c396..acc5c86 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -311,7 +311,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
struct ath6kl_vif *vif = netdev_priv(dev);
int status;

- ar->sme_state = SME_CONNECTING;
+ vif->sme_state = SME_CONNECTING;

if (!ath6kl_cfg80211_ready(ar))
return -EIO;
@@ -601,14 +601,14 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
return;
}

- if (ar->sme_state == SME_CONNECTING) {
+ if (vif->sme_state == SME_CONNECTING) {
/* inform connect result to cfg80211 */
- ar->sme_state = SME_CONNECTED;
+ vif->sme_state = SME_CONNECTED;
cfg80211_connect_result(ar->net_dev, bssid,
assoc_req_ie, assoc_req_len,
assoc_resp_ie, assoc_resp_len,
WLAN_STATUS_SUCCESS, GFP_KERNEL);
- } else if (ar->sme_state == SME_CONNECTED) {
+ } else if (vif->sme_state == SME_CONNECTED) {
/* inform roam event to cfg80211 */
cfg80211_roamed(ar->net_dev, chan, bssid,
assoc_req_ie, assoc_req_len,
@@ -648,7 +648,7 @@ static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,

up(&ar->sem);

- ar->sme_state = SME_DISCONNECTED;
+ vif->sme_state = SME_DISCONNECTED;

return 0;
}
@@ -660,9 +660,9 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
/* TODO: Findout vif */
struct ath6kl_vif *vif = ar->vif;

- if (ar->scan_req) {
- cfg80211_scan_done(ar->scan_req, true);
- ar->scan_req = NULL;
+ if (vif->scan_req) {
+ cfg80211_scan_done(vif->scan_req, true);
+ vif->scan_req = NULL;
}

if (vif->nw_type & ADHOC_NETWORK) {
@@ -701,18 +701,18 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,

clear_bit(CONNECT_PEND, &vif->flags);

- if (ar->sme_state == SME_CONNECTING) {
+ if (vif->sme_state == SME_CONNECTING) {
cfg80211_connect_result(ar->net_dev,
bssid, NULL, 0,
NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
- } else if (ar->sme_state == SME_CONNECTED) {
+ } else if (vif->sme_state == SME_CONNECTED) {
cfg80211_disconnected(ar->net_dev, reason,
NULL, 0, GFP_KERNEL);
}

- ar->sme_state = SME_DISCONNECTED;
+ vif->sme_state = SME_DISCONNECTED;
}

static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
@@ -793,7 +793,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
if (ret)
ath6kl_err("wmi_startscan_cmd failed\n");
else
- ar->scan_req = request;
+ vif->scan_req = request;

kfree(channels);

@@ -802,22 +802,24 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,

void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)
{
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
int i;

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status %d\n", __func__, status);

- if (!ar->scan_req)
+ if (!vif->scan_req)
return;

if ((status == -ECANCELED) || (status == -EBUSY)) {
- cfg80211_scan_done(ar->scan_req, true);
+ cfg80211_scan_done(vif->scan_req, true);
goto out;
}

- cfg80211_scan_done(ar->scan_req, false);
+ cfg80211_scan_done(vif->scan_req, false);

- if (ar->scan_req->n_ssids && ar->scan_req->ssids[0].ssid_len) {
- for (i = 0; i < ar->scan_req->n_ssids; i++) {
+ if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
+ for (i = 0; i < vif->scan_req->n_ssids; i++) {
ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
DISABLE_SSID_FLAG,
0, NULL);
@@ -825,7 +827,7 @@ void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)
}

out:
- ar->scan_req = NULL;
+ vif->scan_req = NULL;
}

static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
@@ -2121,7 +2123,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
if (register_netdev(ndev))
goto err;

- ar->sme_state = SME_DISCONNECTED;
+ vif->sme_state = SME_DISCONNECTED;
set_bit(WLAN_ENABLED, &vif->flags);
ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
set_bit(NETDEV_REGISTERED, &vif->flags);
@@ -2136,9 +2138,12 @@ err:

void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar)
{
- if (ar->scan_req) {
- cfg80211_scan_done(ar->scan_req, true);
- ar->scan_req = NULL;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
+
+ if (vif->scan_req) {
+ cfg80211_scan_done(vif->scan_req, true);
+ vif->scan_req = NULL;
}

wiphy_unregister(ar->wiphy);
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 5403116..e949a3b 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -417,6 +417,8 @@ struct ath6kl_vif {
struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1];
struct aggr_info *aggr_cntxt;
struct timer_list disconnect_timer;
+ struct cfg80211_scan_request *scan_req;
+ enum sme_state sme_state;
};

/* Flag info */
@@ -480,8 +482,6 @@ struct ath6kl {
struct list_head amsdu_rx_buffer_queue;
u8 rx_meta_ver;
struct wireless_dev *wdev;
- struct cfg80211_scan_request *scan_req;
- enum sme_state sme_state;
enum wlan_low_pwr_state wlan_pwr_state;
struct wmi_scan_params_cmd sc_params;
#define AR_MCAST_FILTER_MAC_ADDR_SIZE 4
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index d292e17..204901d 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -941,7 +941,7 @@ void ath6kl_deep_sleep_enable(struct ath6kl *ar)
/* TODO: Pass vif instead of taking it from ar */
struct ath6kl_vif *vif = ar->vif;

- switch (ar->sme_state) {
+ switch (vif->sme_state) {
case SME_CONNECTING:
cfg80211_connect_result(ar->net_dev, vif->bssid, NULL, 0,
NULL, 0,
@@ -963,7 +963,7 @@ void ath6kl_deep_sleep_enable(struct ath6kl *ar)
test_bit(CONNECT_PEND, &vif->flags))
ath6kl_wmi_disconnect_cmd(ar->wmi);

- ar->sme_state = SME_DISCONNECTED;
+ vif->sme_state = SME_DISCONNECTED;

/* disable scanning */
if (ath6kl_wmi_scanparams_cmd(ar->wmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0,
--
1.7.0.4


Subject: [PATCH V2 25/31] ath6kl: Maintain virtual interface in a list

This patch removes all references to ar->vif and takes
vif from a list.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 66 ++++++++++++++++----------
drivers/net/wireless/ath/ath6kl/core.h | 6 ++-
drivers/net/wireless/ath/ath6kl/debug.c | 25 +++++++---
drivers/net/wireless/ath/ath6kl/init.c | 15 ++++--
drivers/net/wireless/ath/ath6kl/main.c | 32 ++++++++++++-
drivers/net/wireless/ath/ath6kl/txrx.c | 72 ++++++++++++++++------------
drivers/net/wireless/ath/ath6kl/wmi.c | 22 +++++++--
drivers/net/wireless/ath/ath6kl/wmi.h | 4 +-
8 files changed, 163 insertions(+), 79 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 5eadcaa..a97365e 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -228,9 +228,9 @@ static void ath6kl_set_key_mgmt(struct ath6kl_vif *vif, u32 key_mgmt)
}
}

-static bool ath6kl_cfg80211_ready(struct ath6kl *ar)
+static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif)
{
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;

if (!test_bit(WMI_READY, &ar->flag)) {
ath6kl_err("wmi is not ready\n");
@@ -302,7 +302,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,

vif->sme_state = SME_CONNECTING;

- if (!ath6kl_cfg80211_ready(ar))
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
@@ -614,7 +614,7 @@ static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
reason_code);

- if (!ath6kl_cfg80211_ready(ar))
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
@@ -713,7 +713,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
int ret = 0;
u32 force_fg_scan = 0;

- if (!ath6kl_cfg80211_ready(ar))
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

if (!ar->usr_bss_filter) {
@@ -831,7 +831,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_type;
int status = 0;

- if (!ath6kl_cfg80211_ready(ar))
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
@@ -953,7 +953,7 @@ static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);

- if (!ath6kl_cfg80211_ready(ar))
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
@@ -980,14 +980,13 @@ static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
void (*callback) (void *cookie,
struct key_params *))
{
- struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
struct ath6kl_vif *vif = netdev_priv(ndev);
struct ath6kl_key *key = NULL;
struct key_params params;

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);

- if (!ath6kl_cfg80211_ready(ar))
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
@@ -1024,7 +1023,7 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);

- if (!ath6kl_cfg80211_ready(ar))
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
@@ -1080,12 +1079,17 @@ void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
{
struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
+ struct ath6kl_vif *vif;
int ret;

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
changed);

- if (!ath6kl_cfg80211_ready(ar))
+ vif = ath6kl_vif_first(ar);
+ if (!vif)
+ return -EIO;
+
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
@@ -1108,12 +1112,17 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
int dbm)
{
struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
+ struct ath6kl_vif *vif;
u8 ath6kl_dbm;

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
type, dbm);

- if (!ath6kl_cfg80211_ready(ar))
+ vif = ath6kl_vif_first(ar);
+ if (!vif)
+ return -EIO;
+
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

switch (type) {
@@ -1128,7 +1137,7 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
return -EOPNOTSUPP;
}

- ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, ath6kl_dbm);
+ ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, ath6kl_dbm);

return 0;
}
@@ -1136,15 +1145,19 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
{
struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl_vif *vif;
+
+ vif = ath6kl_vif_first(ar);
+ if (!vif)
+ return -EIO;

- if (!ath6kl_cfg80211_ready(ar))
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

if (test_bit(CONNECTED, &vif->flags)) {
ar->tx_pwr = 0;

- if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi) != 0) {
+ if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
return -EIO;
}
@@ -1173,7 +1186,7 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
__func__, pmgmt, timeout);

- if (!ath6kl_cfg80211_ready(ar))
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

if (pmgmt) {
@@ -1204,7 +1217,7 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);

- if (!ath6kl_cfg80211_ready(ar))
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

switch (type) {
@@ -1241,7 +1254,7 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
struct ath6kl_vif *vif = netdev_priv(dev);
int status;

- if (!ath6kl_cfg80211_ready(ar))
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

vif->ssid_len = ibss_param->ssid_len;
@@ -1306,10 +1319,9 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
struct net_device *dev)
{
- struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
struct ath6kl_vif *vif = netdev_priv(dev);

- if (!ath6kl_cfg80211_ready(ar))
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

ath6kl_disconnect(vif);
@@ -1539,10 +1551,9 @@ static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type)
{
- struct ath6kl *ar = ath6kl_priv(dev);
struct ath6kl_vif *vif = netdev_priv(dev);

- if (!ath6kl_cfg80211_ready(ar))
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
@@ -1609,7 +1620,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add);

- if (!ath6kl_cfg80211_ready(ar))
+ if (!ath6kl_cfg80211_ready(vif))
return -EIO;

if (vif->next_mode != AP_NETWORK)
@@ -1990,11 +2001,13 @@ struct ath6kl *ath6kl_core_alloc(struct device *dev)

spin_lock_init(&ar->lock);
spin_lock_init(&ar->mcastpsq_lock);
+ spin_lock_init(&ar->list_lock);

init_waitqueue_head(&ar->event_wq);
sema_init(&ar->sem, 1);

INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
+ INIT_LIST_HEAD(&ar->vif_list);

clear_bit(WMI_ENABLED, &ar->flag);
clear_bit(SKIP_SCAN, &ar->flag);
@@ -2109,7 +2122,6 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
ndev->ieee80211_ptr = &vif->wdev;
vif->wdev.wiphy = ar->wiphy;
vif->ar = ar;
- ar->vif = vif;
vif->ndev = ndev;
SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
vif->wdev.netdev = ndev;
@@ -2133,6 +2145,10 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
set_bit(NETDEV_REGISTERED, &vif->flags);

+ spin_lock(&ar->list_lock);
+ list_add_tail(&vif->list, &ar->vif_list);
+ spin_unlock(&ar->list_lock);
+
return ndev;

err:
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 2c64652..29bb235 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -397,6 +397,7 @@ enum ath6kl_vif_state {
};

struct ath6kl_vif {
+ struct list_head list;
struct wireless_dev wdev;
struct net_device *ndev;
struct ath6kl *ar;
@@ -456,7 +457,9 @@ struct ath6kl {
int total_tx_data_pend;
struct htc_target *htc_target;
void *hif_priv;
- struct ath6kl_vif *vif;
+ struct list_head vif_list;
+ /* Lock to avoid race in vif_list entries among add/del/traverse */
+ spinlock_t list_lock;
spinlock_t lock;
struct semaphore sem;
u16 listen_intvl_b;
@@ -662,4 +665,5 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
void ath6kl_init_control_info(struct ath6kl_vif *vif);
void ath6kl_deinit_if_data(struct ath6kl_vif *vif);
void ath6kl_core_free(struct ath6kl *ar);
+struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar);
#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 54faa6b..e515c83 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -397,15 +397,20 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath6kl *ar = file->private_data;
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
- struct target_stats *tgt_stats = &vif->target_stats;
+ struct ath6kl_vif *vif;
+ struct target_stats *tgt_stats;
char *buf;
unsigned int len = 0, buf_len = 1500;
int i;
long left;
ssize_t ret_cnt;

+ vif = ath6kl_vif_first(ar);
+ if (!vif)
+ return -EIO;
+
+ tgt_stats = &vif->target_stats;
+
buf = kzalloc(buf_len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -1249,8 +1254,7 @@ static ssize_t ath6kl_create_qos_write(struct file *file,
{

struct ath6kl *ar = file->private_data;
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl_vif *vif;
char buf[100];
ssize_t len;
char *sptr, *token;
@@ -1258,6 +1262,10 @@ static ssize_t ath6kl_create_qos_write(struct file *file,
u32 val32;
u16 val16;

+ vif = ath6kl_vif_first(ar);
+ if (!vif)
+ return -EIO;
+
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EFAULT;
@@ -1423,14 +1431,17 @@ static ssize_t ath6kl_delete_qos_write(struct file *file,
{

struct ath6kl *ar = file->private_data;
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl_vif *vif;
char buf[100];
ssize_t len;
char *sptr, *token;
u8 traffic_class;
u8 tsid;

+ vif = ath6kl_vif_first(ar);
+ if (!vif)
+ return -EIO;
+
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EFAULT;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index bafb30d..ea45f64 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1627,11 +1627,7 @@ static void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)

void ath6kl_stop_txrx(struct ath6kl *ar)
{
- struct ath6kl_vif *vif = ar->vif;
- struct net_device *ndev = vif->ndev;
-
- if (!ndev)
- return;
+ struct ath6kl_vif *vif, *tmp_vif;

set_bit(DESTROY_IN_PROGRESS, &ar->flag);

@@ -1640,7 +1636,14 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
return;
}

- ath6kl_cleanup_vif(ar->vif, test_bit(WMI_READY, &ar->flag));
+ spin_lock(&ar->list_lock);
+ list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) {
+ list_del(&vif->list);
+ spin_unlock(&ar->list_lock);
+ ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
+ spin_lock(&ar->list_lock);
+ }
+ spin_unlock(&ar->list_lock);

clear_bit(WMI_READY, &ar->flag);

diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index ca86ed3..17cabdc 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -861,8 +861,19 @@ void ath6kl_disconnect(struct ath6kl_vif *vif)

void ath6kl_deep_sleep_enable(struct ath6kl *ar)
{
- /* TODO: Pass vif instead of taking it from ar */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl_vif *vif;
+
+ /* FIXME: for multi vif */
+ vif = ath6kl_vif_first(ar);
+ if (!vif) {
+ /* save the current power mode before enabling power save */
+ ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
+
+ if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
+ ath6kl_warn("ath6kl_deep_sleep_enable: "
+ "wmi_powermode_cmd failed\n");
+ return;
+ }

switch (vif->sme_state) {
case SME_CONNECTING:
@@ -1363,6 +1374,23 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
ath6kl_tx_data_cleanup(ar);
}

+struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar)
+{
+ struct ath6kl_vif *vif;
+
+ spin_lock(&ar->list_lock);
+ if (list_empty(&ar->vif_list)) {
+ spin_unlock(&ar->list_lock);
+ return NULL;
+ }
+
+ vif = list_first_entry(&ar->vif_list, struct ath6kl_vif, list);
+
+ spin_unlock(&ar->list_lock);
+
+ return vif;
+}
+
static int ath6kl_open(struct net_device *dev)
{
struct ath6kl_vif *vif = netdev_priv(dev);
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index ff288da..ab9a5c1 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -432,9 +432,9 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
struct htc_packet *packet)
{
struct ath6kl *ar = target->dev->ar;
- /* TODO: Findout vif properly */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl_vif *vif;
enum htc_endpoint_id endpoint = packet->endpoint;
+ enum htc_send_full_action action = HTC_SEND_FULL_KEEP;

if (endpoint == ar->ctrl_ep) {
/*
@@ -447,19 +447,11 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
set_bit(WMI_CTRL_EP_FULL, &ar->flag);
spin_unlock_bh(&ar->lock);
ath6kl_err("wmi ctrl ep is full\n");
- return HTC_SEND_FULL_KEEP;
+ goto stop_adhoc_netq;
}

if (packet->info.tx.tag == ATH6KL_CONTROL_PKT_TAG)
- return HTC_SEND_FULL_KEEP;
-
- if (vif->nw_type == ADHOC_NETWORK)
- /*
- * In adhoc mode, we cannot differentiate traffic
- * priorities so there is no need to continue, however we
- * should stop the network.
- */
- goto stop_net_queues;
+ goto stop_adhoc_netq;

/*
* The last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for
@@ -467,28 +459,40 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
*/
if (ar->ac_stream_pri_map[ar->ep2ac_map[endpoint]] <
ar->hiac_stream_active_pri &&
- ar->cookie_count <= MAX_HI_COOKIE_NUM)
+ ar->cookie_count <= MAX_HI_COOKIE_NUM) {
/*
* Give preference to the highest priority stream by
* dropping the packets which overflowed.
*/
- return HTC_SEND_FULL_DROP;
+ action = HTC_SEND_FULL_DROP;
+ goto stop_adhoc_netq;
+ }

-stop_net_queues:
- spin_lock_bh(&vif->if_lock);
- set_bit(NETQ_STOPPED, &vif->flags);
- spin_unlock_bh(&vif->if_lock);
- netif_stop_queue(vif->ndev);
+stop_adhoc_netq:
+ /* FIXME: Locking */
+ spin_lock(&ar->list_lock);
+ list_for_each_entry(vif, &ar->vif_list, list) {
+ if (vif->nw_type == ADHOC_NETWORK) {
+ spin_unlock(&ar->list_lock);

- return HTC_SEND_FULL_KEEP;
+ spin_lock_bh(&vif->if_lock);
+ set_bit(NETQ_STOPPED, &vif->flags);
+ spin_unlock_bh(&vif->if_lock);
+ netif_stop_queue(vif->ndev);
+
+ return action;
+ }
+ }
+ spin_unlock(&ar->list_lock);
+
+ return action;
}

/* TODO this needs to be looked at */
-static void ath6kl_tx_clear_node_map(struct ath6kl *ar,
+static void ath6kl_tx_clear_node_map(struct ath6kl_vif *vif,
enum htc_endpoint_id eid, u32 map_no)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl *ar = vif->ar;
u32 i;

if (vif->nw_type != ADHOC_NETWORK)
@@ -533,10 +537,9 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue)
int status;
enum htc_endpoint_id eid;
bool wake_event = false;
- bool flushing = false;
+ bool flushing[MAX_NUM_VIF] = {false};
u8 if_idx;
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
+ struct ath6kl_vif *vif;

skb_queue_head_init(&skb_queue);

@@ -599,7 +602,7 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue)
if (status) {
if (status == -ECANCELED)
/* a packet was flushed */
- flushing = true;
+ flushing[if_idx] = true;

vif->net_stats.tx_errors++;

@@ -615,12 +618,12 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue)
__func__, skb, packet->buf, packet->act_len,
eid, "OK");

- flushing = false;
+ flushing[if_idx] = false;
vif->net_stats.tx_packets++;
vif->net_stats.tx_bytes += skb->len;
}

- ath6kl_tx_clear_node_map(ar, eid, map_no);
+ ath6kl_tx_clear_node_map(vif, eid, map_no);

ath6kl_free_cookie(ar, ath6kl_cookie);

@@ -632,10 +635,17 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue)

__skb_queue_purge(&skb_queue);

- if (test_bit(CONNECTED, &vif->flags)) {
- if (!flushing)
+ /* FIXME: Locking */
+ spin_lock(&ar->list_lock);
+ list_for_each_entry(vif, &ar->vif_list, list) {
+ if (test_bit(CONNECTED, &vif->flags) &&
+ !flushing[vif->fw_vif_idx]) {
+ spin_unlock(&ar->list_lock);
netif_wake_queue(vif->ndev);
+ spin_lock(&ar->list_lock);
+ }
}
+ spin_unlock(&ar->list_lock);

if (wake_event)
wake_up(&ar->event_wq);
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index ed95c2a..1fada31 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -83,10 +83,22 @@ enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi)

struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx)
{
+ struct ath6kl_vif *vif, *found = NULL;
+
if (WARN_ON(if_idx > (MAX_NUM_VIF - 1)))
return NULL;

- return ar->vif;
+ /* FIXME: Locking */
+ spin_lock(&ar->list_lock);
+ list_for_each_entry(vif, &ar->vif_list, list) {
+ if (vif->fw_vif_idx == if_idx) {
+ found = vif;
+ break;
+ }
+ }
+ spin_unlock(&ar->list_lock);
+
+ return found;
}

/* Performs DIX to 802.3 encapsulation for transmit packets.
@@ -2459,7 +2471,7 @@ int ath6kl_wmi_get_stats_cmd(struct wmi *wmi, u8 if_idx)
return ath6kl_wmi_simple_cmd(wmi, if_idx, WMI_GET_STATISTICS_CMDID);
}

-int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM)
+int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 if_idx, u8 dbM)
{
struct sk_buff *skb;
struct wmi_set_tx_pwr_cmd *cmd;
@@ -2472,15 +2484,15 @@ int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM)
cmd = (struct wmi_set_tx_pwr_cmd *) skb->data;
cmd->dbM = dbM;

- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_TX_PWR_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_TX_PWR_CMDID,
NO_SYNC_WMIFLAG);

return ret;
}

-int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi)
+int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi, u8 if_idx)
{
- return ath6kl_wmi_simple_cmd(wmi, 0, WMI_GET_TX_PWR_CMDID);
+ return ath6kl_wmi_simple_cmd(wmi, if_idx, WMI_GET_TX_PWR_CMDID);
}

int ath6kl_wmi_get_roam_tbl_cmd(struct wmi *wmi)
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 621189b..e2f3304 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -2258,8 +2258,8 @@ int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, u8 *krk);
int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index);
int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, u8 if_idx, const u8 *bssid,
const u8 *pmkid, bool set);
-int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM);
-int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi);
+int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 if_idx, u8 dbM);
+int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi, u8 if_idx);
int ath6kl_wmi_get_roam_tbl_cmd(struct wmi *wmi);

int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg);
--
1.7.0.4


Subject: [PATCH V2 29/31] ath6kl: Add a modparam to enable multi normal interface support

This option lets operate more than one vif in normal mode (AP/STA/IBSS)
when support for multiple vif is enabled. This modparam needs to be used
as

modprobe ath6kl multi_norm_if_support=1

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 23 ++++++++++++++++++++++-
drivers/net/wireless/ath/ath6kl/core.h | 1 +
drivers/net/wireless/ath/ath6kl/init.c | 24 +++++++++++++-----------
3 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 7713ab4..ae58d9a 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -21,8 +21,10 @@
#include "testmode.h"

static unsigned int ath6kl_p2p;
+static unsigned int multi_norm_if_support;

module_param(ath6kl_p2p, uint, 0644);
+module_param(multi_norm_if_support, uint, 0644);

#define RATETAB_ENT(_rate, _rateid, _flags) { \
.bitrate = (_rate), \
@@ -341,6 +343,16 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
}
}

+ if (type == NL80211_IFTYPE_P2P_CLIENT ||
+ type == NL80211_IFTYPE_P2P_GO) {
+ for (i = ar->max_norm_iface; i < MAX_NUM_VIF; i++) {
+ if ((ar->avail_idx_map >> i) & BIT(0)) {
+ *if_idx = i;
+ return true;
+ }
+ }
+ }
+
return false;
}

@@ -2094,10 +2106,19 @@ struct ath6kl *ath6kl_core_alloc(struct device *dev)
}

ar = wiphy_priv(wiphy);
- ar->p2p = !!ath6kl_p2p;
+ if (!multi_norm_if_support)
+ ar->p2p = !!ath6kl_p2p;
ar->wiphy = wiphy;
ar->dev = dev;

+ if (multi_norm_if_support)
+ ar->max_norm_iface = 2;
+ else
+ ar->max_norm_iface = 1;
+
+ /* FIXME: Remove this once the multivif support is enabled */
+ ar->max_norm_iface = 1;
+
spin_lock_init(&ar->lock);
spin_lock_init(&ar->mcastpsq_lock);
spin_lock_init(&ar->list_lock);
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 6933fb6..427db08 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -461,6 +461,7 @@ struct ath6kl {
/* Lock to avoid race in vif_list entries among add/del/traverse */
spinlock_t list_lock;
u8 num_vif;
+ u8 max_norm_iface;
u8 avail_idx_map;
spinlock_t lock;
struct semaphore sem;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 2780170..6f5bdff 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -428,7 +428,7 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar)
int ath6kl_configure_target(struct ath6kl *ar)
{
u32 param, ram_reserved_size;
- u8 fw_iftype, fw_mode = 0, fw_submode;
+ u8 fw_iftype, fw_mode = 0, fw_submode = 0;
int i;

/*
@@ -445,15 +445,19 @@ int ath6kl_configure_target(struct ath6kl *ar)
fw_mode |= fw_iftype << (i * HI_OPTION_FW_MODE_BITS);

/*
- * submodes : vif[0] - AP/STA/IBSS
- * vif[1] - "P2P dev"/"P2P GO"/"P2P Client"
- * vif[2] - "P2P dev"/"P2P GO"/"P2P Client"
+ * By default, submodes :
+ * vif[0] - AP/STA/IBSS
+ * vif[1] - "P2P dev"/"P2P GO"/"P2P Client"
+ * vif[2] - "P2P dev"/"P2P GO"/"P2P Client"
*/
- fw_submode = HI_OPTION_FW_SUBMODE_NONE |
- (HI_OPTION_FW_SUBMODE_P2PDEV <<
- (1 * HI_OPTION_FW_SUBMODE_BITS)) |
- (HI_OPTION_FW_SUBMODE_P2PDEV <<
- (2 * HI_OPTION_FW_SUBMODE_BITS));
+
+ for (i = 0; i < ar->max_norm_iface; i++)
+ fw_submode |= HI_OPTION_FW_SUBMODE_NONE <<
+ (i * HI_OPTION_FW_SUBMODE_BITS);
+
+ for (i = ar->max_norm_iface; i < MAX_NUM_VIF; i++)
+ fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV <<
+ (i * HI_OPTION_FW_SUBMODE_BITS);

/*
* FIXME: This needs to be removed once the multivif
@@ -461,8 +465,6 @@ int ath6kl_configure_target(struct ath6kl *ar)
*/
if (ar->p2p)
fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV;
- else
- fw_submode = HI_OPTION_FW_SUBMODE_NONE;

param = HTC_PROTOCOL_VERSION;
if (ath6kl_bmi_write(ar,
--
1.7.0.4


Subject: [PATCH V2 26/31] ath6kl: Use the other variant of netdev (un)register APIs

Use replace (un)register_netdev() with (un)register_netdevice()
so that the same ath6kl function can be used with
add_virtual_intf()/del_virtual_intf().

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 15 ++++-----------
drivers/net/wireless/ath/ath6kl/init.c | 12 ++++++++++--
drivers/net/wireless/ath/ath6kl/main.c | 1 +
3 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index a97365e..7cdd893 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -2098,14 +2098,7 @@ void ath6kl_deinit_if_data(struct ath6kl_vif *vif)
{
aggr_module_destroy(vif->aggr_cntxt);

- vif->aggr_cntxt = NULL;
-
- if (test_bit(NETDEV_REGISTERED, &vif->flags)) {
- unregister_netdev(vif->ndev);
- clear_bit(NETDEV_REGISTERED, &vif->flags);
- }
-
- free_netdev(vif->ndev);
+ unregister_netdevice(vif->ndev);
}

struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
@@ -2137,7 +2130,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
if (ath6kl_init_if_data(vif))
goto err;

- if (register_netdev(ndev))
+ if (register_netdevice(ndev))
goto err;

vif->sme_state = SME_DISCONNECTED;
@@ -2152,8 +2145,8 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
return ndev;

err:
- ath6kl_deinit_if_data(vif);
-
+ aggr_module_destroy(vif->aggr_cntxt);
+ free_netdev(ndev);
return NULL;
}

diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index ea45f64..d541dc9 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1416,8 +1416,13 @@ static int ath6kl_init(struct ath6kl *ar)
goto err_node_cleanup;
}

+ rtnl_lock();
+
/* Add an initial station interface */
ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0);
+
+ rtnl_unlock();
+
if (!ndev) {
ath6kl_err("Failed to instantiate a network device\n");
status = -ENOMEM;
@@ -1522,7 +1527,9 @@ err_rxbuf_cleanup:
err_cleanup_scatter:
ath6kl_hif_cleanup_scatter(ar);
err_if_deinit:
+ rtnl_lock();
ath6kl_deinit_if_data(netdev_priv(ndev));
+ rtnl_unlock();
wiphy_unregister(ar->wiphy);
err_debug_init:
ath6kl_debug_cleanup(ar);
@@ -1621,8 +1628,6 @@ static void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
cfg80211_scan_done(vif->scan_req, true);
vif->scan_req = NULL;
}
-
- ath6kl_deinit_if_data(vif);
}

void ath6kl_stop_txrx(struct ath6kl *ar)
@@ -1641,6 +1646,9 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
list_del(&vif->list);
spin_unlock(&ar->list_lock);
ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
+ rtnl_lock();
+ ath6kl_deinit_if_data(vif);
+ rtnl_unlock();
spin_lock(&ar->list_lock);
}
spin_unlock(&ar->list_lock);
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 17cabdc..9ccdc4d 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -1445,6 +1445,7 @@ static struct net_device_ops ath6kl_netdev_ops = {
void init_netdev(struct net_device *dev)
{
dev->netdev_ops = &ath6kl_netdev_ops;
+ dev->destructor = free_netdev;
dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;

dev->needed_headroom = ETH_HLEN;
--
1.7.0.4


Subject: [PATCH V2 05/31] ath6kl: Define an initial vif structure and use it

vif specific information need to be moved from struct ath6kl.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 41 ++++++++++++++++-----------
drivers/net/wireless/ath/ath6kl/core.h | 11 ++++++-
drivers/net/wireless/ath/ath6kl/init.c | 4 +-
3 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index fcddf1a..e663d60 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -2014,51 +2014,58 @@ int ath6kl_register_ieee80211_hw(struct ath6kl *ar)
return 0;
}

-static int ath6kl_init_if_data(struct ath6kl *ar, struct net_device *ndev)
+static int ath6kl_init_if_data(struct ath6kl_vif *vif)
{
- ar->aggr_cntxt = aggr_init(ndev);
+ struct ath6kl *ar = vif->ar;
+
+ ar->aggr_cntxt = aggr_init(vif->ndev);
if (!ar->aggr_cntxt) {
ath6kl_err("failed to initialize aggr\n");
return -ENOMEM;
}

setup_timer(&ar->disconnect_timer, disconnect_timer_handler,
- (unsigned long) ndev);
+ (unsigned long) vif->ndev);

return 0;
}

-void ath6kl_deinit_if_data(struct ath6kl *ar, struct net_device *ndev)
+void ath6kl_deinit_if_data(struct ath6kl_vif *vif)
{
+ struct ath6kl *ar = vif->ar;
+
aggr_module_destroy(ar->aggr_cntxt);

ar->aggr_cntxt = NULL;

if (test_bit(NETDEV_REGISTERED, &ar->flag)) {
- unregister_netdev(ndev);
+ unregister_netdev(vif->ndev);
clear_bit(NETDEV_REGISTERED, &ar->flag);
}

- free_netdev(ndev);
+ free_netdev(vif->ndev);
}

struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
enum nl80211_iftype type)
{
struct net_device *ndev;
- struct wireless_dev *wdev;
+ struct ath6kl_vif *vif;

- ndev = alloc_netdev(sizeof(*wdev), "wlan%d", ether_setup);
+ ndev = alloc_netdev(sizeof(*vif), "wlan%d", ether_setup);
if (!ndev)
return NULL;

- wdev = netdev_priv(ndev);
- ndev->ieee80211_ptr = wdev;
- wdev->wiphy = ar->wiphy;
- SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
- wdev->netdev = ndev;
- wdev->iftype = type;
- ar->wdev = wdev;
+ vif = netdev_priv(ndev);
+ ndev->ieee80211_ptr = &vif->wdev;
+ vif->wdev.wiphy = ar->wiphy;
+ vif->ar = ar;
+ ar->vif = vif;
+ vif->ndev = ndev;
+ SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
+ vif->wdev.netdev = ndev;
+ vif->wdev.iftype = type;
+ ar->wdev = &vif->wdev;
ar->net_dev = ndev;

init_netdev(ndev);
@@ -2066,7 +2073,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
ath6kl_init_control_info(ar);

/* TODO: Pass interface specific pointer instead of ar */
- if (ath6kl_init_if_data(ar, ndev))
+ if (ath6kl_init_if_data(vif))
goto err;

if (register_netdev(ndev))
@@ -2080,7 +2087,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
return ndev;

err:
- ath6kl_deinit_if_data(ar, ndev);
+ ath6kl_deinit_if_data(vif);

return NULL;
}
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index f1b3c47..0c1dee0 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -380,6 +380,12 @@ struct ath6kl_req_key {
u8 key_len;
};

+struct ath6kl_vif {
+ struct wireless_dev wdev;
+ struct net_device *ndev;
+ struct ath6kl *ar;
+};
+
/* Flag info */
#define WMI_ENABLED 0
#define WMI_READY 1
@@ -410,6 +416,7 @@ struct ath6kl {
int total_tx_data_pend;
struct htc_target *htc_target;
void *hif_priv;
+ struct ath6kl_vif *vif;
spinlock_t lock;
struct semaphore sem;
int ssid_len;
@@ -543,7 +550,7 @@ struct ath6kl {

static inline void *ath6kl_priv(struct net_device *dev)
{
- return wdev_priv(dev->ieee80211_ptr);
+ return ((struct ath6kl_vif *) netdev_priv(dev))->ar;
}

static inline void ath6kl_deposit_credit_to_ep(struct htc_credit_state_info
@@ -643,6 +650,6 @@ void ath6kl_wakeup_event(void *dev);
void ath6kl_target_failure(struct ath6kl *ar);

void ath6kl_init_control_info(struct ath6kl *ar);
-void ath6kl_deinit_if_data(struct ath6kl *ar, struct net_device *ndev);
+void ath6kl_deinit_if_data(struct ath6kl_vif *vif);
void ath6kl_core_free(struct ath6kl *ar);
#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 7720177..246399d 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1498,7 +1498,7 @@ err_rxbuf_cleanup:
err_cleanup_scatter:
ath6kl_hif_cleanup_scatter(ar);
err_if_deinit:
- ath6kl_deinit_if_data(ar, ndev);
+ ath6kl_deinit_if_data(netdev_priv(ndev));
wiphy_unregister(ar->wiphy);
err_debug_init:
ath6kl_debug_cleanup(ar);
@@ -1631,7 +1631,7 @@ void ath6kl_destroy(struct net_device *dev, unsigned int unregister)

ath6kl_debug_cleanup(ar);

- ath6kl_deinit_if_data(ar, dev);
+ ath6kl_deinit_if_data(netdev_priv(dev));

kfree(ar->fw_board);
kfree(ar->fw_otp);
--
1.7.0.4


Subject: [PATCH V2 02/31] ath6kl: Keep wiphy reference in ath6kl structure

This is to avoid using ar->wdev to get wiphy pointer, this
may need further cleanup for multi vif support.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 50 ++++++++++++++--------------
drivers/net/wireless/ath/ath6kl/core.h | 1 +
drivers/net/wireless/ath/ath6kl/debug.c | 2 +-
drivers/net/wireless/ath/ath6kl/init.c | 6 ++--
drivers/net/wireless/ath/ath6kl/main.c | 8 ++--
drivers/net/wireless/ath/ath6kl/wmi.c | 10 +++---
6 files changed, 39 insertions(+), 38 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 0680d2b..16c21a4 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -481,7 +481,7 @@ static int ath6kl_add_bss_if_needed(struct ath6kl *ar, const u8 *bssid,
struct cfg80211_bss *bss;
u8 *ie;

- bss = cfg80211_get_bss(ar->wdev->wiphy, chan, bssid,
+ bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
ar->ssid, ar->ssid_len, WLAN_CAPABILITY_ESS,
WLAN_CAPABILITY_ESS);
if (bss == NULL) {
@@ -500,7 +500,7 @@ static int ath6kl_add_bss_if_needed(struct ath6kl *ar, const u8 *bssid,
ie[1] = ar->ssid_len;
memcpy(ie + 2, ar->ssid, ar->ssid_len);
memcpy(ie + 2 + ar->ssid_len, beacon_ie, beacon_ie_len);
- bss = cfg80211_inform_bss(ar->wdev->wiphy, chan,
+ bss = cfg80211_inform_bss(ar->wiphy, chan,
bssid, 0, WLAN_CAPABILITY_ESS, 100,
ie, 2 + ar->ssid_len + beacon_ie_len,
0, GFP_KERNEL);
@@ -567,7 +567,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
}
}

- chan = ieee80211_get_channel(ar->wdev->wiphy, (int) channel);
+ chan = ieee80211_get_channel(ar->wiphy, (int) channel);


if (nw_type & ADHOC_NETWORK) {
@@ -1923,6 +1923,7 @@ struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
int ret = 0;
struct wireless_dev *wdev;
struct ath6kl *ar;
+ struct wiphy *wiphy;

wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
if (!wdev) {
@@ -1931,43 +1932,45 @@ struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
}

/* create a new wiphy for use with cfg80211 */
- wdev->wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
- if (!wdev->wiphy) {
+ wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
+ if (!wiphy) {
ath6kl_err("couldn't allocate wiphy device\n");
kfree(wdev);
return NULL;
}

- ar = wiphy_priv(wdev->wiphy);
+ ar = wiphy_priv(wiphy);
ar->p2p = !!ath6kl_p2p;
+ ar->wiphy = wiphy;
+ wdev->wiphy = wiphy;

- wdev->wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
+ wiphy->mgmt_stypes = ath6kl_mgmt_stypes;

- wdev->wiphy->max_remain_on_channel_duration = 5000;
+ wiphy->max_remain_on_channel_duration = 5000;

/* set device pointer for wiphy */
- set_wiphy_dev(wdev->wiphy, dev);
+ set_wiphy_dev(wiphy, dev);

- wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
if (ar->p2p) {
- wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
+ wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_P2P_CLIENT);
}
/* max num of ssids that can be probed during scanning */
- wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
- wdev->wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
- wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
- wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
- wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+ wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
+ wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
+ wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
+ wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
+ wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;

- wdev->wiphy->cipher_suites = cipher_suites;
- wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+ wiphy->cipher_suites = cipher_suites;
+ wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);

- ret = wiphy_register(wdev->wiphy);
+ ret = wiphy_register(wiphy);
if (ret < 0) {
ath6kl_err("couldn't register wiphy device\n");
- wiphy_free(wdev->wiphy);
+ wiphy_free(wiphy);
kfree(wdev);
return NULL;
}
@@ -1984,10 +1987,7 @@ void ath6kl_cfg80211_deinit(struct ath6kl *ar)
ar->scan_req = NULL;
}

- if (!wdev)
- return;
-
- wiphy_unregister(wdev->wiphy);
- wiphy_free(wdev->wiphy);
+ wiphy_unregister(ar->wiphy);
+ wiphy_free(ar->wiphy);
kfree(wdev);
}
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 31e5c7e..fb5a322 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -402,6 +402,7 @@ struct ath6kl_req_key {
struct ath6kl {
struct device *dev;
struct net_device *net_dev;
+ struct wiphy *wiphy;
struct ath6kl_bmi bmi;
const struct ath6kl_hif_ops *hif_ops;
struct wmi *wmi;
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index bafc810..f067c7b 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -1509,7 +1509,7 @@ int ath6kl_debug_init(struct ath6kl *ar)
ar->debug.fwlog_mask = 0;

ar->debugfs_phy = debugfs_create_dir("ath6kl",
- ar->wdev->wiphy->debugfsdir);
+ ar->wiphy->debugfsdir);
if (!ar->debugfs_phy) {
vfree(ar->debug.fwlog_buf.buf);
kfree(ar->debug.fwlog_tmp);
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 5fd1693..0b24c90 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -584,7 +584,7 @@ struct ath6kl *ath6kl_core_alloc(struct device *sdev)
}

dev->ieee80211_ptr = wdev;
- SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
+ SET_NETDEV_DEV(dev, wiphy_dev(ar->wiphy));
wdev->netdev = dev;
ar->sme_state = SME_DISCONNECTED;

@@ -1557,7 +1557,7 @@ static int ath6kl_init(struct ath6kl *ar)
ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;

- ar->wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
+ ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;

status = ath6kl_target_config_wlan_params(ar);
if (!status)
@@ -1598,7 +1598,7 @@ int ath6kl_core_init(struct ath6kl *ar)

ar->version.target_ver = le32_to_cpu(targ_info.version);
ar->target_type = le32_to_cpu(targ_info.type);
- ar->wdev->wiphy->hw_version = le32_to_cpu(targ_info.version);
+ ar->wiphy->hw_version = le32_to_cpu(targ_info.version);

ret = ath6kl_init_hw_params(ar);
if (ret)
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index e693756..4470f6e 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -996,8 +996,8 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
ar->version.wlan_ver = sw_ver;
ar->version.abi_ver = abi_ver;

- snprintf(ar->wdev->wiphy->fw_version,
- sizeof(ar->wdev->wiphy->fw_version),
+ snprintf(ar->wiphy->fw_version,
+ sizeof(ar->wiphy->fw_version),
"%u.%u.%u.%u",
(ar->version.wlan_ver & 0xf0000000) >> 28,
(ar->version.wlan_ver & 0x0f000000) >> 24,
@@ -1009,8 +1009,8 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
wake_up(&ar->event_wq);

ath6kl_info("hw %s fw %s%s\n",
- get_hw_id_string(ar->wdev->wiphy->hw_version),
- ar->wdev->wiphy->fw_version,
+ get_hw_id_string(ar->wiphy->hw_version),
+ ar->wiphy->fw_version,
test_bit(TESTMODE, &ar->flag) ? " testmode" : "");
}

diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 7b6bfdd..7f4c2c2 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -431,7 +431,7 @@ static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap,
dur = le32_to_cpu(ev->duration);
ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl: freq=%u dur=%u\n",
freq, dur);
- chan = ieee80211_get_channel(ar->wdev->wiphy, freq);
+ chan = ieee80211_get_channel(ar->wiphy, freq);
if (!chan) {
ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl: Unknown channel "
"(freq=%u)\n", freq);
@@ -460,7 +460,7 @@ static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi,
dur = le32_to_cpu(ev->duration);
ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: freq=%u dur=%u "
"status=%u\n", freq, dur, ev->status);
- chan = ieee80211_get_channel(ar->wdev->wiphy, freq);
+ chan = ieee80211_get_channel(ar->wiphy, freq);
if (!chan) {
ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: Unknown "
"channel (freq=%u)\n", freq);
@@ -878,7 +878,7 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
alpha2[0] = country->isoName[0];
alpha2[1] = country->isoName[1];

- regulatory_hint(wmi->parent_dev->wdev->wiphy, alpha2);
+ regulatory_hint(wmi->parent_dev->wiphy, alpha2);

ath6kl_dbg(ATH6KL_DBG_WMI, "Country alpha2 being used: %c%c\n",
alpha2[0], alpha2[1]);
@@ -974,7 +974,7 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
}

- channel = ieee80211_get_channel(ar->wdev->wiphy, le16_to_cpu(bih->ch));
+ channel = ieee80211_get_channel(ar->wiphy, le16_to_cpu(bih->ch));
if (channel == NULL)
return -EINVAL;

@@ -1021,7 +1021,7 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)

memcpy(&mgmt->u.beacon, buf, len);

- bss = cfg80211_inform_bss_frame(ar->wdev->wiphy, channel, mgmt,
+ bss = cfg80211_inform_bss_frame(ar->wiphy, channel, mgmt,
24 + len, (bih->snr - 95) * 100,
GFP_ATOMIC);
kfree(mgmt);
--
1.7.0.4


Subject: [PATCH V2 21/31] ath6kl: Refactor ath6kl_destroy()

So that the deinitialization of ath6kl and vif are separated.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 8 --
drivers/net/wireless/ath/ath6kl/common.h | 2 +-
drivers/net/wireless/ath/ath6kl/core.h | 5 +-
drivers/net/wireless/ath/ath6kl/init.c | 124 ++++++++++++++++-----------
drivers/net/wireless/ath/ath6kl/main.c | 75 +----------------
drivers/net/wireless/ath/ath6kl/sdio.c | 2 +-
6 files changed, 79 insertions(+), 137 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 0d02ba0..d42cb3e 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -2142,14 +2142,6 @@ err:

void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
-
- if (vif->scan_req) {
- cfg80211_scan_done(vif->scan_req, true);
- vif->scan_req = NULL;
- }
-
wiphy_unregister(ar->wiphy);
wiphy_free(ar->wiphy);
}
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
index b92f0e5..877cb70 100644
--- a/drivers/net/wireless/ath/ath6kl/common.h
+++ b/drivers/net/wireless/ath/ath6kl/common.h
@@ -92,6 +92,6 @@ void ath6k_seek_credits(struct htc_credit_state_info *cred_inf,
struct htc_endpoint_credit_dist *ep_dist);
struct ath6kl *ath6kl_core_alloc(struct device *sdev);
int ath6kl_core_init(struct ath6kl *ar);
-int ath6kl_unavail_ev(struct ath6kl *ar);
+void ath6kl_core_cleanup(struct ath6kl *ar);
struct sk_buff *ath6kl_buf_alloc(int size);
#endif /* COMMON_H */
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index de288ff..498b626 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -584,7 +584,6 @@ static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
return addr;
}

-void ath6kl_destroy(struct net_device *dev, unsigned int unregister);
int ath6kl_configure_target(struct ath6kl *ar);
void ath6kl_detect_error(unsigned long ptr);
void disconnect_timer_handler(unsigned long ptr);
@@ -604,8 +603,6 @@ int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length);
int ath6kl_read_fwlogs(struct ath6kl *ar);
void ath6kl_init_profile_info(struct ath6kl_vif *vif);
void ath6kl_tx_data_cleanup(struct ath6kl *ar);
-void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
- bool get_dbglogs);

struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar);
void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie);
@@ -657,6 +654,8 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no,
void ath6kl_wakeup_event(void *dev);
void ath6kl_target_failure(struct ath6kl *ar);

+void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
+ bool wait_fot_compltn, bool cold_reset);
void ath6kl_init_control_info(struct ath6kl_vif *vif);
void ath6kl_deinit_if_data(struct ath6kl_vif *vif);
void ath6kl_core_free(struct ath6kl *ar);
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 4bb348e..c5170c3 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -513,11 +513,27 @@ void ath6kl_core_free(struct ath6kl *ar)
wiphy_free(ar->wiphy);
}

-int ath6kl_unavail_ev(struct ath6kl *ar)
+void ath6kl_core_cleanup(struct ath6kl *ar)
{
- ath6kl_destroy(ar->vif->ndev, 1);
+ destroy_workqueue(ar->ath6kl_wq);

- return 0;
+ if (ar->htc_target)
+ ath6kl_htc_cleanup(ar->htc_target);
+
+ ath6kl_cookie_cleanup(ar);
+
+ ath6kl_cleanup_amsdu_rxbufs(ar);
+
+ ath6kl_bmi_cleanup(ar);
+
+ ath6kl_debug_cleanup(ar);
+
+ kfree(ar->fw_board);
+ kfree(ar->fw_otp);
+ kfree(ar->fw);
+ kfree(ar->fw_patch);
+
+ ath6kl_deinit_ieee80211_hw(ar);
}

/* firmware upload */
@@ -1571,6 +1587,36 @@ err_wq:
return ret;
}

+static void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
+{
+ static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ bool discon_issued;
+
+ netif_stop_queue(vif->ndev);
+
+ clear_bit(WLAN_ENABLED, &vif->flags);
+
+ if (wmi_ready) {
+ discon_issued = test_bit(CONNECTED, &vif->flags) ||
+ test_bit(CONNECT_PEND, &vif->flags);
+ ath6kl_disconnect(vif);
+ del_timer(&vif->disconnect_timer);
+
+ if (discon_issued)
+ ath6kl_disconnect_event(vif, DISCONNECT_CMD,
+ (vif->nw_type & AP_NETWORK) ?
+ bcast_mac : vif->bssid,
+ 0, NULL, 0);
+ }
+
+ if (vif->scan_req) {
+ cfg80211_scan_done(vif->scan_req, true);
+ vif->scan_req = NULL;
+ }
+
+ ath6kl_deinit_if_data(vif);
+}
+
void ath6kl_stop_txrx(struct ath6kl *ar)
{
struct ath6kl_vif *vif = ar->vif;
@@ -1586,58 +1632,34 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
return;
}

- if (ar->wlan_pwr_state != WLAN_POWER_STATE_CUT_PWR)
- ath6kl_stop_endpoint(ndev, false, true);
+ ath6kl_cleanup_vif(ar->vif, test_bit(WMI_READY, &ar->flag));

- clear_bit(WLAN_ENABLED, &vif->flags);
-}
+ clear_bit(WMI_READY, &ar->flag);

-/*
- * We need to differentiate between the surprise and planned removal of the
- * device because of the following consideration:
- *
- * - In case of surprise removal, the hcd already frees up the pending
- * for the device and hence there is no need to unregister the function
- * driver inorder to get these requests. For planned removal, the function
- * driver has to explicitly unregister itself to have the hcd return all the
- * pending requests before the data structures for the devices are freed up.
- * Note that as per the current implementation, the function driver will
- * end up releasing all the devices since there is no API to selectively
- * release a particular device.
- *
- * - Certain commands issued to the target can be skipped for surprise
- * removal since they will anyway not go through.
- */
-void ath6kl_destroy(struct net_device *dev, unsigned int unregister)
-{
- struct ath6kl *ar;
+ /*
+ * After wmi_shudown all WMI events will be dropped. We
+ * need to cleanup the buffers allocated in AP mode and
+ * give disconnect notification to stack, which usually
+ * happens in the disconnect_event. Simulate the disconnect
+ * event by calling the function directly. Sometimes
+ * disconnect_event will be received when the debug logs
+ * are collected.
+ */
+ ath6kl_wmi_shutdown(ar->wmi);

- if (!dev || !ath6kl_priv(dev)) {
- ath6kl_err("failed to get device structure\n");
- return;
+ clear_bit(WMI_ENABLED, &ar->flag);
+ if (ar->htc_target) {
+ ath6kl_dbg(ATH6KL_DBG_TRC, "%s: shut down htc\n", __func__);
+ ath6kl_htc_stop(ar->htc_target);
}

- ar = ath6kl_priv(dev);
-
- destroy_workqueue(ar->ath6kl_wq);
-
- if (ar->htc_target)
- ath6kl_htc_cleanup(ar->htc_target);
-
- ath6kl_cookie_cleanup(ar);
-
- ath6kl_cleanup_amsdu_rxbufs(ar);
-
- ath6kl_bmi_cleanup(ar);
-
- ath6kl_debug_cleanup(ar);
-
- ath6kl_deinit_if_data(netdev_priv(dev));
-
- kfree(ar->fw_board);
- kfree(ar->fw_otp);
- kfree(ar->fw);
- kfree(ar->fw_patch);
+ /*
+ * Try to reset the device if we can. The driver may have been
+ * configure NOT to reset the target during a debug session.
+ */
+ ath6kl_dbg(ATH6KL_DBG_TRC,
+ "attempting to reset target on instance destroy\n");
+ ath6kl_reset_device(ar, ar->target_type, true, true);

- ath6kl_deinit_ieee80211_hw(ar);
+ clear_bit(WLAN_ENABLED, &ar->flag);
}
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 08af257..a10002d 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -395,8 +395,8 @@ out:
#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
#define AR6004_RESET_CONTROL_ADDRESS 0x00004000

-static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
- bool wait_fot_compltn, bool cold_reset)
+void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
+ bool wait_fot_compltn, bool cold_reset)
{
int status = 0;
u32 address;
@@ -427,77 +427,6 @@ static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
ath6kl_err("failed to reset target\n");
}

-void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
- bool get_dbglogs)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ath6kl_vif *vif = netdev_priv(dev);
- static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- bool discon_issued;
-
- netif_stop_queue(dev);
-
- /* disable the target and the interrupts associated with it */
- if (test_bit(WMI_READY, &ar->flag)) {
- discon_issued = (test_bit(CONNECTED, &vif->flags) ||
- test_bit(CONNECT_PEND, &vif->flags));
- ath6kl_disconnect(vif);
- if (!keep_profile)
- ath6kl_init_profile_info(vif);
-
- del_timer(&vif->disconnect_timer);
-
- clear_bit(WMI_READY, &ar->flag);
- ath6kl_wmi_shutdown(ar->wmi);
- clear_bit(WMI_ENABLED, &ar->flag);
- ar->wmi = NULL;
-
- /*
- * After wmi_shudown all WMI events will be dropped. We
- * need to cleanup the buffers allocated in AP mode and
- * give disconnect notification to stack, which usually
- * happens in the disconnect_event. Simulate the disconnect
- * event by calling the function directly. Sometimes
- * disconnect_event will be received when the debug logs
- * are collected.
- */
- if (discon_issued)
- ath6kl_disconnect_event(vif, DISCONNECT_CMD,
- (vif->nw_type & AP_NETWORK) ?
- bcast_mac : vif->bssid,
- 0, NULL, 0);
-
- ar->user_key_ctrl = 0;
-
- } else {
- ath6kl_dbg(ATH6KL_DBG_TRC,
- "%s: wmi is not ready 0x%p 0x%p\n",
- __func__, ar, ar->wmi);
-
- /* Shut down WMI if we have started it */
- if (test_bit(WMI_ENABLED, &ar->flag)) {
- ath6kl_dbg(ATH6KL_DBG_TRC,
- "%s: shut down wmi\n", __func__);
- ath6kl_wmi_shutdown(ar->wmi);
- clear_bit(WMI_ENABLED, &ar->flag);
- ar->wmi = NULL;
- }
- }
-
- if (ar->htc_target) {
- ath6kl_dbg(ATH6KL_DBG_TRC, "%s: shut down htc\n", __func__);
- ath6kl_htc_stop(ar->htc_target);
- }
-
- /*
- * Try to reset the device if we can. The driver may have been
- * configure NOT to reset the target during a debug session.
- */
- ath6kl_dbg(ATH6KL_DBG_TRC,
- "attempting to reset target on instance destroy\n");
- ath6kl_reset_device(ar, ar->target_type, true, true);
-}
-
static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif)
{
u8 index;
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index f73e14f..b7c0566 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -897,7 +897,7 @@ static void ath6kl_sdio_remove(struct sdio_func *func)
ath6kl_stop_txrx(ar_sdio->ar);
cancel_work_sync(&ar_sdio->wr_async_work);

- ath6kl_unavail_ev(ar_sdio->ar);
+ ath6kl_core_cleanup(ar_sdio->ar);

ath6kl_sdio_power_off(ar_sdio);

--
1.7.0.4


2011-10-26 07:22:37

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH V2 00/31] ath6kl Add multiple vif support

On 10/25/2011 05:03 PM, Vasanthakumar Thiagarajan wrote:
> This patch set adds basic infrastructure for multiple
> virtual interface. As configuring the firmware with more than one
> vif causes random target assert, the number of supported vifs is
> restricted to 1 for now. I would like to thank Vivek Natarajan
> ([email protected]) for his inital work in this area and
> Arthi Thiruvengadam ([email protected]) for finding some
> critical bugs.

I saw the lockdep warning below after I loaded the module and connected
to an AP. But the driver still functioned normally.

Kalle

[ 73.439849] ath6kl: hw 2.1.1 fw 3.1.1.609
[ 75.408050]
[ 75.408081] =========================================================
[ 75.416320] [ INFO: possible irq lock inversion dependency detected ]
[ 75.423004] 3.1.0-rc9-wl+ #44
[ 75.426086] ---------------------------------------------------------
[ 75.432800] swapper/0 just changed the state of lock:
[ 75.438049] (&(&ar->lock)->rlock){+.-...}, at: [<bf011b94>]
ath6kl_indicate_tx_activity+0x38/0xb8 [ath6kl]
[ 75.448303] but this lock took another, SOFTIRQ-unsafe lock in the past:
[ 75.455261] (&(&ar->list_lock)->rlock){+.+...}
[ 75.459808]
[ 75.459808] and interrupts could create inverse lock ordering between
them.
[ 75.459808]
[ 75.470306]
[ 75.470306] other info that might help us debug this:
[ 75.477081] Possible interrupt unsafe locking scenario:
[ 75.477081]
[ 75.484130] CPU0 CPU1
[ 75.488861] ---- ----
[ 75.493560] lock(&(&ar->list_lock)->rlock);
[ 75.498107] local_irq_disable();
[ 75.504241] lock(&(&ar->lock)->rlock);
[ 75.510955]
lock(&(&ar->list_lock)->rlock);
[ 75.518096] <Interrupt>
[ 75.520812] lock(&(&ar->lock)->rlock);
[ 75.525085]
[ 75.525085] *** DEADLOCK ***
[ 75.525085]
[ 75.531249] 3 locks held by swapper/0:
[ 75.535156] #0: (&n->timer){+.-...}, at: [<c004ebe0>]
run_timer_softirq+0x244/0x564
[ 75.543334] #1: (rcu_read_lock_bh){.+....}, at: [<c03175e4>]
dev_queue_xmit+0x0/0x714
[ 75.551696] #2: (_xmit_ETHER#2){+.-...}, at: [<c032bfc4>]
sch_direct_xmit+0x38/0x2dc
[ 75.559936]
[ 75.559967] the shortest dependencies between 2nd lock and 1st lock:
[ 75.568115] -> (&(&ar->list_lock)->rlock){+.+...} ops: 60 {
[ 75.574035] HARDIRQ-ON-W at:
[ 75.577392] [<c0078004>]
__lock_acquire+0x7b0/0x1a8c
[ 75.586273] [<c00799d4>]
lock_acquire+0x158/0x1a8
[ 75.594879] [<c03e272c>]
_raw_spin_lock+0x4c/0x84
[ 75.603485] [<bf00898c>]
ath6kl_interface_add+0x184/0x1e0 [ath6kl]
[ 75.613677] [<bf00d204>]
ath6kl_core_init+0xe9c/0x1760 [ath6kl]
[ 75.623565] [<bf01859c>]
ath6kl_sdio_probe+0x324/0x3bc [ath6kl]
[ 75.633483] [<c02ed524>]
sdio_bus_probe+0x100/0x164
[ 75.642272] [<c0274de0>]
driver_probe_device+0x14c/0x290
[ 75.651519] [<c0274f8c>]
__driver_attach+0x68/0x8c
[ 75.660217] [<c0274458>]
bus_for_each_dev+0x4c/0x8c
[ 75.669006] [<c0273c9c>]
bus_add_driver+0xc4/0x250
[ 75.677703] [<c02755f0>]
driver_register+0xc0/0x150
[ 75.686462] [<bf02700c>]
0xbf02700c
[ 75.693817] [<c00086c0>]
do_one_initcall+0x94/0x160
[ 75.702606] [<c0084670>]
sys_init_module+0x1220/0x13e0
[ 75.711669] [<c00139e0>]
ret_fast_syscall+0x0/0x3c
[ 75.720367] SOFTIRQ-ON-W at:
[ 75.723724] [<c0078028>]
__lock_acquire+0x7d4/0x1a8c
[ 75.732604] [<c00799d4>]
lock_acquire+0x158/0x1a8
[ 75.741180] [<c03e272c>]
_raw_spin_lock+0x4c/0x84
[ 75.749786] [<bf00898c>]
ath6kl_interface_add+0x184/0x1e0 [ath6kl]
[ 75.759979] [<bf00d204>]
ath6kl_core_init+0xe9c/0x1760 [ath6kl]
[ 75.769897] [<bf01859c>]
ath6kl_sdio_probe+0x324/0x3bc [ath6kl]
[ 75.779785] [<c02ed524>]
sdio_bus_probe+0x100/0x164
[ 75.788574] [<c0274de0>]
driver_probe_device+0x14c/0x290
[ 75.797821] [<c0274f8c>]
__driver_attach+0x68/0x8c
[ 75.806518] [<c0274458>]
bus_for_each_dev+0x4c/0x8c
[ 75.815307] [<c0273c9c>]
bus_add_driver+0xc4/0x250
[ 75.824005] [<c02755f0>]
driver_register+0xc0/0x150
[ 75.832794] [<bf02700c>]
0xbf02700c
[ 75.840118] [<c00086c0>]
do_one_initcall+0x94/0x160
[ 75.848907] [<c0084670>]
sys_init_module+0x1220/0x13e0
[ 75.857940] [<c00139e0>]
ret_fast_syscall+0x0/0x3c
[ 75.866638] INITIAL USE at:
[ 75.869903] [<c007808c>]
__lock_acquire+0x838/0x1a8c
[ 75.878692] [<c00799d4>]
lock_acquire+0x158/0x1a8
[ 75.887207] [<c03e272c>]
_raw_spin_lock+0x4c/0x84
[ 75.895721] [<bf00898c>]
ath6kl_interface_add+0x184/0x1e0 [ath6kl]
[ 75.905792] [<bf00d204>]
ath6kl_core_init+0xe9c/0x1760 [ath6kl]
[ 75.915618] [<bf01859c>]
ath6kl_sdio_probe+0x324/0x3bc [ath6kl]
[ 75.925445] [<c02ed524>]
sdio_bus_probe+0x100/0x164
[ 75.934143] [<c0274de0>]
driver_probe_device+0x14c/0x290
[ 75.943298] [<c0274f8c>]
__driver_attach+0x68/0x8c
[ 75.951904] [<c0274458>]
bus_for_each_dev+0x4c/0x8c
[ 75.960571] [<c0273c9c>]
bus_add_driver+0xc4/0x250
[ 75.969177] [<c02755f0>]
driver_register+0xc0/0x150
[ 75.977874] [<bf02700c>]
0xbf02700c
[ 75.985107] [<c00086c0>]
do_one_initcall+0x94/0x160
[ 75.993804] [<c0084670>]
sys_init_module+0x1220/0x13e0
[ 76.002777] [<c00139e0>]
ret_fast_syscall+0x0/0x3c
[ 76.011383] }
[ 76.013183] ... key at: [<bf020544>]
__key.38763+0x0/0xffff848c [ath6kl]
[ 76.020843] ... acquired at:
[ 76.024017] [<c00799d4>] lock_acquire+0x158/0x1a8
[ 76.029174] [<c03e272c>] _raw_spin_lock+0x4c/0x84
[ 76.034362] [<bf015410>] ath6kl_get_vif_by_index+0x68/0x78 [ath6kl]
[ 76.041198] [<bf0116b0>] ath6kl_tx_complete+0x178/0x4c0 [ath6kl]
[ 76.047760] [<bf0046ec>] htc_tx_comp_handler+0x4c/0x54 [ath6kl]
[ 76.054229] [<bf0030a8>] ath6kl_hif_rw_comp_handler+0x48/0x60 [ath6kl]
[ 76.061340] [<bf0186c4>] ath6kl_sdio_write_async_work+0x90/0xbc
[ath6kl]
[ 76.068634] [<c005a8c4>] process_one_work+0x354/0x628
[ 76.074157] [<c005cb74>] worker_thread+0x1f4/0x3c0
[ 76.079437] [<c006147c>] kthread+0x80/0x88
[ 76.083953] [<c001496c>] kernel_thread_exit+0x0/0x8
[ 76.089324]
[ 76.090850] -> (&(&ar->lock)->rlock){+.-...} ops: 23 {
[ 76.096221] HARDIRQ-ON-W at:
[ 76.099487] [<c0078004>]
__lock_acquire+0x7b0/0x1a8c
[ 76.108184] [<c00799d4>]
lock_acquire+0x158/0x1a8
[ 76.116607] [<c03e2aa0>]
_raw_spin_lock_bh+0x54/0x8c
[ 76.125305] [<bf0112d8>]
ath6kl_refill_amsdu_rxbufs+0x68/0x94 [ath6kl]
[ 76.135681] [<bf00da98>]
ath6kl_core_init+0x1730/0x1760 [ath6kl]
[ 76.145477] [<bf01859c>]
ath6kl_sdio_probe+0x324/0x3bc [ath6kl]
[ 76.155212] [<c02ed524>]
sdio_bus_probe+0x100/0x164
[ 76.163818] [<c0274de0>]
driver_probe_device+0x14c/0x290
[ 76.172882] [<c0274f8c>]
__driver_attach+0x68/0x8c
[ 76.181396] [<c0274458>]
bus_for_each_dev+0x4c/0x8c
[ 76.190002] [<c0273c9c>]
bus_add_driver+0xc4/0x250
[ 76.198516] [<c02755f0>]
driver_register+0xc0/0x150
[ 76.207122] [<bf02700c>]
0xbf02700c
[ 76.214263] [<c00086c0>]
do_one_initcall+0x94/0x160
[ 76.222869] [<c0084670>]
sys_init_module+0x1220/0x13e0
[ 76.231750] [<c00139e0>]
ret_fast_syscall+0x0/0x3c
[ 76.240264] IN-SOFTIRQ-W at:
[ 76.243530] [<c0077f9c>]
__lock_acquire+0x748/0x1a8c
[ 76.252227] [<c00799d4>]
lock_acquire+0x158/0x1a8
[ 76.260650] [<c03e2aa0>]
_raw_spin_lock_bh+0x54/0x8c
[ 76.269348] [<bf011b94>]
ath6kl_indicate_tx_activity+0x38/0xb8 [ath6kl]
[ 76.279785] [<bf014460>]
ath6kl_wmi_create_pstream_cmd+0x1e0/0x224 [ath6kl]
[ 76.290618] [<bf0145a4>]
ath6kl_wmi_implicit_create_pstream+0x100/0x138 [ath6kl]
[ 76.301910] [<bf012020>]
ath6kl_data_tx+0x2d0/0x5fc [ath6kl]
[ 76.311370] [<c03172a8>]
dev_hard_start_xmit+0x504/0x840
[ 76.320404] [<c032bfe8>]
sch_direct_xmit+0x5c/0x2dc
[ 76.329010] [<c0317a08>]
dev_queue_xmit+0x424/0x714
[ 76.337615] [<c0363864>]
arp_solicit+0x214/0x254
[ 76.345977] [<c0323c30>]
neigh_timer_handler+0x22c/0x2a8
[ 76.355010] [<c004ed08>]
run_timer_softirq+0x36c/0x564
[ 76.363891] [<c0047e48>]
__do_softirq+0x138/0x314
[ 76.372314] [<c00481d4>]
irq_exit+0x54/0xb4
[ 76.380187] [<c00148f8>]
handle_IRQ+0x68/0x8c
[ 76.388244] [<c03e34b8>]
__irq_svc+0x38/0xa0
[ 76.396240] [<c007673c>]
trace_hardirqs_on_caller+0x1c/0x19c
[ 76.405639] [<c0015018>]
cpu_idle+0x7c/0xcc
[ 76.413513] [<c05687f8>]
start_kernel+0x2ac/0x30c
[ 76.421936] INITIAL USE at:
[ 76.425109] [<c007808c>]
__lock_acquire+0x838/0x1a8c
[ 76.433715] [<c00799d4>]
lock_acquire+0x158/0x1a8
[ 76.442047] [<c03e2aa0>]
_raw_spin_lock_bh+0x54/0x8c
[ 76.450653] [<bf0112d8>]
ath6kl_refill_amsdu_rxbufs+0x68/0x94 [ath6kl]
[ 76.460937] [<bf00da98>]
ath6kl_core_init+0x1730/0x1760 [ath6kl]
[ 76.470672] [<bf01859c>]
ath6kl_sdio_probe+0x324/0x3bc [ath6kl]
[ 76.480316] [<c02ed524>]
sdio_bus_probe+0x100/0x164
[ 76.488830] [<c0274de0>]
driver_probe_device+0x14c/0x290
[ 76.497802] [<c0274f8c>]
__driver_attach+0x68/0x8c
[ 76.506225] [<c0274458>]
bus_for_each_dev+0x4c/0x8c
[ 76.514739] [<c0273c9c>]
bus_add_driver+0xc4/0x250
[ 76.523162] [<c02755f0>]
driver_register+0xc0/0x150
[ 76.531677] [<bf02700c>] 0xbf02700c
[ 76.538757] [<c00086c0>]
do_one_initcall+0x94/0x160
[ 76.547241] [<c0084670>]
sys_init_module+0x1220/0x13e0
[ 76.556030] [<c00139e0>]
ret_fast_syscall+0x0/0x3c
[ 76.564453] }
[ 76.566192] ... key at: [<bf020554>] __key.38761+0x0/0xffff847c
[ath6kl]
[ 76.573730] ... acquired at:
[ 76.576812] [<c0076ea4>] check_usage_forwards+0xd8/0xfc
[ 76.582519] [<c007618c>] mark_lock+0x388/0x618
[ 76.587432] [<c0077f9c>] __lock_acquire+0x748/0x1a8c
[ 76.592864] [<c00799d4>] lock_acquire+0x158/0x1a8
[ 76.598022] [<c03e2aa0>] _raw_spin_lock_bh+0x54/0x8c
[ 76.603485] [<bf011b94>] ath6kl_indicate_tx_activity+0x38/0xb8
[ath6kl]
[ 76.610687] [<bf014460>] ath6kl_wmi_create_pstream_cmd+0x1e0/0x224
[ath6kl]
[ 76.618255] [<bf0145a4>]
ath6kl_wmi_implicit_create_pstream+0x100/0x138 [ath6kl]
[ 76.626251] [<bf012020>] ath6kl_data_tx+0x2d0/0x5fc [ath6kl]
[ 76.632476] [<c03172a8>] dev_hard_start_xmit+0x504/0x840
[ 76.638275] [<c032bfe8>] sch_direct_xmit+0x5c/0x2dc
[ 76.643615] [<c0317a08>] dev_queue_xmit+0x424/0x714
[ 76.648956] [<c0363864>] arp_solicit+0x214/0x254
[ 76.654052] [<c0323c30>] neigh_timer_handler+0x22c/0x2a8
[ 76.659851] [<c004ed08>] run_timer_softirq+0x36c/0x564
[ 76.665466] [<c0047e48>] __do_softirq+0x138/0x314
[ 76.670654] [<c00481d4>] irq_exit+0x54/0xb4
[ 76.675262] [<c00148f8>] handle_IRQ+0x68/0x8c
[ 76.680084] [<c03e34b8>] __irq_svc+0x38/0xa0
[ 76.684814] [<c007673c>] trace_hardirqs_on_caller+0x1c/0x19c
[ 76.690979] [<c0015018>] cpu_idle+0x7c/0xcc
[ 76.695587] [<c05687f8>] start_kernel+0x2ac/0x30c
[ 76.700775]
[ 76.702301]
[ 76.702301] stack backtrace:
[ 76.706878] [<c0019998>] (unwind_backtrace+0x0/0x128) from
[<c0076d88>] (print_irq_inversion_bug+0x194/0x1d8)
[ 76.717193] [<c0076d88>] (print_irq_inversion_bug+0x194/0x1d8) from
[<c0076ea4>] (check_usage_forwards+0xd8/0xfc)
[ 76.727874] [<c0076ea4>] (check_usage_forwards+0xd8/0xfc) from
[<c007618c>] (mark_lock+0x388/0x618)
[ 76.737274] [<c007618c>] (mark_lock+0x388/0x618) from [<c0077f9c>]
(__lock_acquire+0x748/0x1a8c)
[ 76.746429] [<c0077f9c>] (__lock_acquire+0x748/0x1a8c) from
[<c00799d4>] (lock_acquire+0x158/0x1a8)
[ 76.755859] [<c00799d4>] (lock_acquire+0x158/0x1a8) from [<c03e2aa0>]
(_raw_spin_lock_bh+0x54/0x8c)
[ 76.765319] [<c03e2aa0>] (_raw_spin_lock_bh+0x54/0x8c) from
[<bf011b94>] (ath6kl_indicate_tx_activity+0x38/0xb8 [ath6kl])
[ 76.776824] [<bf011b94>] (ath6kl_indicate_tx_activity+0x38/0xb8
[ath6kl]) from [<bf014460>] (ath6kl_wmi_create_pstream_cmd+0x1e0/0x224
[ath6kl])
[ 76.790405] [<bf014460>] (ath6kl_wmi_create_pstream_cmd+0x1e0/0x224
[ath6kl]) from [<bf0145a4>]
(ath6kl_wmi_implicit_create_pstream+0x100/0x138 [ath6kl])
[ 76.804809] [<bf0145a4>]
(ath6kl_wmi_implicit_create_pstream+0x100/0x138 [ath6kl]) from
[<bf012020>] (ath6kl_data_tx+0x2d0/0x5fc [ath6kl])
[ 76.817779] [<bf012020>] (ath6kl_data_tx+0x2d0/0x5fc [ath6kl]) from
[<c03172a8>] (dev_hard_start_xmit+0x504/0x840)
[ 76.828552] [<c03172a8>] (dev_hard_start_xmit+0x504/0x840) from
[<c032bfe8>] (sch_direct_xmit+0x5c/0x2dc)
[ 76.838531] [<c032bfe8>] (sch_direct_xmit+0x5c/0x2dc) from
[<c0317a08>] (dev_queue_xmit+0x424/0x714)
[ 76.848022] [<c0317a08>] (dev_queue_xmit+0x424/0x714) from
[<c0363864>] (arp_solicit+0x214/0x254)
[ 76.857269] [<c0363864>] (arp_solicit+0x214/0x254) from [<c0323c30>]
(neigh_timer_handler+0x22c/0x2a8)
[ 76.866973] [<c0323c30>] (neigh_timer_handler+0x22c/0x2a8) from
[<c004ed08>] (run_timer_softirq+0x36c/0x564)
[ 76.877197] [<c004ed08>] (run_timer_softirq+0x36c/0x564) from
[<c0047e48>] (__do_softirq+0x138/0x314)
[ 76.886779] [<c0047e48>] (__do_softirq+0x138/0x314) from [<c00481d4>]
(irq_exit+0x54/0xb4)
[ 76.895385] [<c00481d4>] (irq_exit+0x54/0xb4) from [<c00148f8>]
(handle_IRQ+0x68/0x8c)
[ 76.903625] [<c00148f8>] (handle_IRQ+0x68/0x8c) from [<c03e34b8>]
(__irq_svc+0x38/0xa0)
[ 76.911987] [<c03e34b8>] (__irq_svc+0x38/0xa0) from [<c007673c>]
(trace_hardirqs_on_caller+0x1c/0x19c)
[ 76.921661] [<c007673c>] (trace_hardirqs_on_caller+0x1c/0x19c) from
[<c0015018>] (cpu_idle+0x7c/0xcc)
[ 76.931243] [<c0015018>] (cpu_idle+0x7c/0xcc) from [<c05687f8>]
(start_kernel+0x2ac/0x30c)

Subject: [PATCH V2 30/31] ath6kl: Initialize target wlan values for every vif

Wlan parameters need to be configured for every vif
in target.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/debug.c | 4 +-
drivers/net/wireless/ath/ath6kl/init.c | 34 +++++++++++++++++++----------
drivers/net/wireless/ath/ath6kl/wmi.c | 35 ++++++++++++++++--------------
drivers/net/wireless/ath/ath6kl/wmi.h | 18 ++++++++-------
4 files changed, 53 insertions(+), 38 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index e515c83..725d598 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -1188,7 +1188,7 @@ static ssize_t ath6kl_keepalive_write(struct file *file,
if (ret)
return ret;

- ret = ath6kl_wmi_set_keepalive_cmd(ar->wmi, val);
+ ret = ath6kl_wmi_set_keepalive_cmd(ar->wmi, 0, val);
if (ret)
return ret;

@@ -1233,7 +1233,7 @@ static ssize_t ath6kl_disconnect_timeout_write(struct file *file,
if (ret)
return ret;

- ret = ath6kl_wmi_disctimeout_cmd(ar->wmi, val);
+ ret = ath6kl_wmi_disctimeout_cmd(ar->wmi, 0, val);
if (ret)
return ret;

diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 6f5bdff..49f1a94 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -352,7 +352,7 @@ void ath6kl_target_failure(struct ath6kl *ar)

}

-static int ath6kl_target_config_wlan_params(struct ath6kl *ar)
+static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx)
{
int status = 0;
int ret;
@@ -362,46 +362,50 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar)
* default values. Required if checksum offload is needed. Set
* RxMetaVersion to 2.
*/
- if (ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,
+ if (ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, idx,
ar->rx_meta_ver, 0, 0)) {
ath6kl_err("unable to set the rx frame format\n");
status = -EIO;
}

if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN)
- if ((ath6kl_wmi_pmparams_cmd(ar->wmi, 0, 1, 0, 0, 1,
+ if ((ath6kl_wmi_pmparams_cmd(ar->wmi, idx, 0, 1, 0, 0, 1,
IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) {
ath6kl_err("unable to set power save fail event policy\n");
status = -EIO;
}

if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER))
- if ((ath6kl_wmi_set_lpreamble_cmd(ar->wmi, 0,
+ if ((ath6kl_wmi_set_lpreamble_cmd(ar->wmi, idx, 0,
WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) {
ath6kl_err("unable to set barker preamble policy\n");
status = -EIO;
}

- if (ath6kl_wmi_set_keepalive_cmd(ar->wmi,
+ if (ath6kl_wmi_set_keepalive_cmd(ar->wmi, idx,
WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) {
ath6kl_err("unable to set keep alive interval\n");
status = -EIO;
}

- if (ath6kl_wmi_disctimeout_cmd(ar->wmi,
+ if (ath6kl_wmi_disctimeout_cmd(ar->wmi, idx,
WLAN_CONFIG_DISCONNECT_TIMEOUT)) {
ath6kl_err("unable to set disconnect timeout\n");
status = -EIO;
}

if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST))
- if (ath6kl_wmi_set_wmm_txop(ar->wmi, WMI_TXOP_DISABLED)) {
+ if (ath6kl_wmi_set_wmm_txop(ar->wmi, idx, WMI_TXOP_DISABLED)) {
ath6kl_err("unable to set txop bursting\n");
status = -EIO;
}

+ /*
+ * FIXME: Make sure p2p configurations are not applied to
+ * non-p2p capable interfaces when multivif support is enabled.
+ */
if (ar->p2p) {
- ret = ath6kl_wmi_info_req_cmd(ar->wmi,
+ ret = ath6kl_wmi_info_req_cmd(ar->wmi, idx,
P2P_FLAG_CAPABILITIES_REQ |
P2P_FLAG_MACADDR_REQ |
P2P_FLAG_HMODEL_REQ);
@@ -413,9 +417,13 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar)
}
}

+ /*
+ * FIXME: Make sure p2p configurations are not applied to
+ * non-p2p capable interfaces when multivif support is enabled.
+ */
if (ar->p2p) {
/* Enable Probe Request reporting for P2P */
- ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, true);
+ ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, idx, true);
if (ret) {
ath6kl_dbg(ATH6KL_DBG_TRC, "failed to enable Probe "
"Request reporting (%d)\n", ret);
@@ -1542,9 +1550,11 @@ static int ath6kl_init(struct ath6kl *ar)

ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;

- status = ath6kl_target_config_wlan_params(ar);
- if (status)
- goto err_htc_stop;
+ for (i = 0; i < MAX_NUM_VIF; i++) {
+ status = ath6kl_target_config_wlan_params(ar, i);
+ if (status)
+ goto err_htc_stop;
+ }

/*
* Set mac address which is received in ready event
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 1fada31..e6b0960 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -1940,7 +1940,7 @@ int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode)
return ret;
}

-int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u16 idle_period,
+int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u8 if_idx, u16 idle_period,
u16 ps_poll_num, u16 dtim_policy,
u16 tx_wakeup_policy, u16 num_tx_to_wakeup,
u16 ps_fail_event_policy)
@@ -1961,12 +1961,12 @@ int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u16 idle_period,
pm->num_tx_to_wakeup = cpu_to_le16(num_tx_to_wakeup);
pm->ps_fail_event_policy = cpu_to_le16(ps_fail_event_policy);

- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_POWER_PARAMS_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_POWER_PARAMS_CMDID,
NO_SYNC_WMIFLAG);
return ret;
}

-int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 timeout)
+int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 if_idx, u8 timeout)
{
struct sk_buff *skb;
struct wmi_disc_timeout_cmd *cmd;
@@ -1979,7 +1979,7 @@ int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 timeout)
cmd = (struct wmi_disc_timeout_cmd *) skb->data;
cmd->discon_timeout = timeout;

- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_DISC_TIMEOUT_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_DISC_TIMEOUT_CMDID,
NO_SYNC_WMIFLAG);

if (ret == 0)
@@ -2500,7 +2500,8 @@ int ath6kl_wmi_get_roam_tbl_cmd(struct wmi *wmi)
return ath6kl_wmi_simple_cmd(wmi, 0, WMI_GET_ROAM_TBL_CMDID);
}

-int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status, u8 preamble_policy)
+int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 if_idx, u8 status,
+ u8 preamble_policy)
{
struct sk_buff *skb;
struct wmi_set_lpreamble_cmd *cmd;
@@ -2514,7 +2515,7 @@ int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status, u8 preamble_policy)
cmd->status = status;
cmd->preamble_policy = preamble_policy;

- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_LPREAMBLE_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_LPREAMBLE_CMDID,
NO_SYNC_WMIFLAG);
return ret;
}
@@ -2537,7 +2538,7 @@ int ath6kl_wmi_set_rts_cmd(struct wmi *wmi, u16 threshold)
return ret;
}

-int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg)
+int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, u8 if_idx, enum wmi_txop_cfg cfg)
{
struct sk_buff *skb;
struct wmi_set_wmm_txop_cmd *cmd;
@@ -2553,12 +2554,13 @@ int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg)
cmd = (struct wmi_set_wmm_txop_cmd *) skb->data;
cmd->txop_enable = cfg;

- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_WMM_TXOP_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_WMM_TXOP_CMDID,
NO_SYNC_WMIFLAG);
return ret;
}

-int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl)
+int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 if_idx,
+ u8 keep_alive_intvl)
{
struct sk_buff *skb;
struct wmi_set_keepalive_cmd *cmd;
@@ -2571,7 +2573,7 @@ int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl)
cmd = (struct wmi_set_keepalive_cmd *) skb->data;
cmd->keep_alive_intvl = keep_alive_intvl;

- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_KEEPALIVE_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_KEEPALIVE_CMDID,
NO_SYNC_WMIFLAG);

if (ret == 0)
@@ -2734,7 +2736,8 @@ int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u8 if_idx, u16 aid,
return 0;
}

-int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_ver,
+int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 if_idx,
+ u8 rx_meta_ver,
bool rx_dot11_hdr, bool defrag_on_host)
{
struct sk_buff *skb;
@@ -2751,7 +2754,7 @@ int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_ver,
cmd->meta_ver = rx_meta_ver;

/* Delete the local aggr state, on host */
- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_RX_FRAME_FORMAT_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_RX_FRAME_FORMAT_CMDID,
NO_SYNC_WMIFLAG);

return ret;
@@ -2872,7 +2875,7 @@ int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq,
NO_SYNC_WMIFLAG);
}

-int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, bool enable)
+int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, u8 if_idx, bool enable)
{
struct sk_buff *skb;
struct wmi_probe_req_report_cmd *p;
@@ -2885,11 +2888,11 @@ int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, bool enable)
enable);
p = (struct wmi_probe_req_report_cmd *) skb->data;
p->enable = enable ? 1 : 0;
- return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_PROBE_REQ_REPORT_CMDID,
+ return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_PROBE_REQ_REPORT_CMDID,
NO_SYNC_WMIFLAG);
}

-int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u32 info_req_flags)
+int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u8 if_idx, u32 info_req_flags)
{
struct sk_buff *skb;
struct wmi_get_p2p_info *p;
@@ -2902,7 +2905,7 @@ int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u32 info_req_flags)
info_req_flags);
p = (struct wmi_get_p2p_info *) skb->data;
p->info_req_flags = cpu_to_le32(info_req_flags);
- return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_GET_P2P_INFO_CMDID,
+ return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_GET_P2P_INFO_CMDID,
NO_SYNC_WMIFLAG);
}

diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index e2f3304..495d2e5 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -2230,18 +2230,18 @@ int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx,
u16 listen_interval,
u16 listen_beacons);
int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode);
-int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u16 idle_period,
+int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u8 if_idx, u16 idle_period,
u16 ps_poll_num, u16 dtim_policy,
u16 tx_wakup_policy, u16 num_tx_to_wakeup,
u16 ps_fail_event_policy);
-int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 timeout);
int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi, u8 if_idx,
struct wmi_create_pstream_cmd *pstream);
int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 if_idx, u8 traffic_class,
u8 tsid);
+int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 if_idx, u8 timeout);

int ath6kl_wmi_set_rts_cmd(struct wmi *wmi, u16 threshold);
-int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status,
+int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 if_idx, u8 status,
u8 preamble_policy);

int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source);
@@ -2262,8 +2262,9 @@ int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 if_idx, u8 dbM);
int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi, u8 if_idx);
int ath6kl_wmi_get_roam_tbl_cmd(struct wmi *wmi);

-int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg);
-int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl);
+int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, u8 if_idx, enum wmi_txop_cfg cfg);
+int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 if_idx,
+ u8 keep_alive_intvl);
int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);

s32 ath6kl_wmi_get_rate(s8 rate_index);
@@ -2282,7 +2283,8 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd,

int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u8 if_idx, u16 aid, bool flag);

-int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_version,
+int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 if_idx,
+ u8 rx_meta_version,
bool rx_dot11_hdr, bool defrag_on_host);

int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
@@ -2301,9 +2303,9 @@ int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq,
const u8 *dst, const u8 *data,
u16 data_len);

-int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, bool enable);
+int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, u8 if_idx, bool enable);

-int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u32 info_req_flags);
+int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u8 if_idx, u32 info_req_flags);

int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx);

--
1.7.0.4


Subject: [PATCH V2 31/31] ath6kl: Use appropriate wdev from vif

Remove the wdev reference in struct ath6kl.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 17 +++++++----------
drivers/net/wireless/ath/ath6kl/core.h | 1 -
2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index ae58d9a..007b638 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -622,7 +622,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);

if (nw_type & ADHOC_NETWORK) {
- if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
+ if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"%s: ath6k not in ibss mode\n", __func__);
return;
@@ -630,8 +630,8 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
}

if (nw_type & INFRA_NETWORK) {
- if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
- ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
+ if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
+ vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"%s: ath6k not in station mode\n", __func__);
return;
@@ -717,7 +717,7 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
}

if (vif->nw_type & ADHOC_NETWORK) {
- if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
+ if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"%s: ath6k not in ibss mode\n", __func__);
return;
@@ -728,8 +728,8 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
}

if (vif->nw_type & INFRA_NETWORK) {
- if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
- ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
+ if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
+ vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"%s: ath6k not in station mode\n", __func__);
return;
@@ -1320,8 +1320,6 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
enum nl80211_iftype type, u32 *flags,
struct vif_params *params)
{
- struct ath6kl *ar = ath6kl_priv(ndev);
- struct wireless_dev *wdev = ar->wdev;
struct ath6kl_vif *vif = netdev_priv(ndev);

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
@@ -1350,7 +1348,7 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
return -EOPNOTSUPP;
}

- wdev->iftype = type;
+ vif->wdev.iftype = type;

return 0;
}
@@ -2251,7 +2249,6 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
vif->wdev.iftype = type;
vif->fw_vif_idx = fw_vif_idx;
vif->nw_type = vif->next_mode = nw_type;
- ar->wdev = &vif->wdev;

memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
if (fw_vif_idx != 0)
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 427db08..0d0f80a 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -498,7 +498,6 @@ struct ath6kl {
u8 ap_country_code[3];
struct list_head amsdu_rx_buffer_queue;
u8 rx_meta_ver;
- struct wireless_dev *wdev;
enum wlan_low_pwr_state wlan_pwr_state;
struct wmi_scan_params_cmd sc_params;
u8 mac_addr[ETH_ALEN];
--
1.7.0.4


Subject: [PATCH V2 10/31] ath6kl: Move channel information to vif structure

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 14 +++++++-------
drivers/net/wireless/ath/ath6kl/core.h | 4 ++--
drivers/net/wireless/ath/ath6kl/init.c | 4 ++--
drivers/net/wireless/ath/ath6kl/main.c | 4 ++--
4 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 4861fd7..76a6116 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -364,7 +364,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
!memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
ar->reconnect_flag = true;
status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->req_bssid,
- ar->ch_hint);
+ vif->ch_hint);

up(&ar->sem);
if (status) {
@@ -382,7 +382,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
memcpy(vif->ssid, sme->ssid, sme->ssid_len);

if (sme->channel)
- ar->ch_hint = sme->channel->center_freq;
+ vif->ch_hint = sme->channel->center_freq;

memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
@@ -452,7 +452,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
__func__,
vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
vif->prwise_crypto_len, vif->grp_crypto,
- vif->grp_crypto_len, ar->ch_hint);
+ vif->grp_crypto_len, vif->ch_hint);

ar->reconnect_flag = 0;
status = ath6kl_wmi_connect_cmd(ar->wmi, vif->nw_type,
@@ -461,7 +461,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
vif->prwise_crypto_len,
vif->grp_crypto, vif->grp_crypto_len,
vif->ssid_len, vif->ssid,
- vif->req_bssid, ar->ch_hint,
+ vif->req_bssid, vif->ch_hint,
ar->connect_ctrl_flags);

up(&ar->sem);
@@ -1252,7 +1252,7 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);

if (ibss_param->channel)
- ar->ch_hint = ibss_param->channel->center_freq;
+ vif->ch_hint = ibss_param->channel->center_freq;

if (ibss_param->channel_fixed) {
/*
@@ -1292,7 +1292,7 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
__func__,
vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
vif->prwise_crypto_len, vif->grp_crypto,
- vif->grp_crypto_len, ar->ch_hint);
+ vif->grp_crypto_len, vif->ch_hint);

status = ath6kl_wmi_connect_cmd(ar->wmi, vif->nw_type,
vif->dot11_auth_mode, vif->auth_mode,
@@ -1300,7 +1300,7 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
vif->prwise_crypto_len,
vif->grp_crypto, vif->grp_crypto_len,
vif->ssid_len, vif->ssid,
- vif->req_bssid, ar->ch_hint,
+ vif->req_bssid, vif->ch_hint,
ar->connect_ctrl_flags);
set_bit(CONNECT_PEND, &vif->flags);

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 298b339..ab33244 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -411,6 +411,8 @@ struct ath6kl_vif {
u8 nw_type;
u8 bssid[ETH_ALEN];
u8 req_bssid[ETH_ALEN];
+ u16 ch_hint;
+ u16 bss_ch;
};

/* Flag info */
@@ -440,8 +442,6 @@ struct ath6kl {
spinlock_t lock;
struct semaphore sem;
struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
- u16 ch_hint;
- u16 bss_ch;
u16 listen_intvl_b;
u16 listen_intvl_t;
u8 lrssi_roam_threshold;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index a43bb29..09125cc 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -90,7 +90,7 @@ void ath6kl_init_profile_info(struct ath6kl *ar)
memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
memset(vif->bssid, 0, sizeof(vif->bssid));
- ar->bss_ch = 0;
+ vif->bss_ch = 0;
vif->nw_type = vif->next_mode = INFRA_NETWORK;
}

@@ -253,7 +253,7 @@ void ath6kl_init_control_info(struct ath6kl *ar)
ath6kl_init_profile_info(ar);
vif->def_txkey_index = 0;
memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
- ar->ch_hint = 0;
+ vif->ch_hint = 0;
}

/*
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index bdefb89..15838de 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -1058,7 +1058,7 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
assoc_info);

memcpy(vif->bssid, bssid, sizeof(vif->bssid));
- ar->bss_ch = channel;
+ vif->bss_ch = channel;

if ((vif->nw_type == INFRA_NETWORK))
ath6kl_wmi_listeninterval_cmd(ar->wmi, ar->listen_intvl_t,
@@ -1434,7 +1434,7 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,

netif_stop_queue(ar->net_dev);
memset(vif->bssid, 0, sizeof(vif->bssid));
- ar->bss_ch = 0;
+ vif->bss_ch = 0;

ath6kl_tx_data_cleanup(ar);
}
--
1.7.0.4


Subject: [PATCH V2 28/31] ath6kl: Implement add_virtual_intf() and del_virtual_intf()

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 123 +++++++++++++++++++++++++++-
drivers/net/wireless/ath/ath6kl/cfg80211.h | 2 +-
drivers/net/wireless/ath/ath6kl/core.h | 4 +
drivers/net/wireless/ath/ath6kl/init.c | 10 ++-
4 files changed, 133 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 7cdd893..7713ab4 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -293,6 +293,57 @@ static int ath6kl_set_assoc_req_ies(struct ath6kl_vif *vif, const u8 *ies,
return ret;
}

+static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type)
+{
+ switch (type) {
+ case NL80211_IFTYPE_STATION:
+ *nw_type = INFRA_NETWORK;
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ *nw_type = ADHOC_NETWORK;
+ break;
+ case NL80211_IFTYPE_AP:
+ *nw_type = AP_NETWORK;
+ break;
+ case NL80211_IFTYPE_P2P_CLIENT:
+ *nw_type = INFRA_NETWORK;
+ break;
+ case NL80211_IFTYPE_P2P_GO:
+ *nw_type = AP_NETWORK;
+ break;
+ default:
+ ath6kl_err("invalid interface type %u\n", type);
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
+ u8 *if_idx, u8 *nw_type)
+{
+ int i;
+
+ if (ath6kl_nliftype_to_drv_iftype(type, nw_type))
+ return false;
+
+ if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) &&
+ ar->num_vif))
+ return false;
+
+ if (type == NL80211_IFTYPE_STATION ||
+ type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
+ for (i = 0; i < MAX_NUM_VIF; i++) {
+ if ((ar->avail_idx_map >> i) & BIT(0)) {
+ *if_idx = i;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme)
{
@@ -1206,6 +1257,52 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
return 0;
}

+static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
+ char *name,
+ enum nl80211_iftype type,
+ u32 *flags,
+ struct vif_params *params)
+{
+ struct ath6kl *ar = wiphy_priv(wiphy);
+ struct net_device *ndev;
+ u8 if_idx, nw_type;
+
+ if (ar->num_vif == MAX_NUM_VIF) {
+ ath6kl_err("Reached maximum number of supported vif\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (!ath6kl_is_valid_iftype(ar, type, &if_idx, &nw_type)) {
+ ath6kl_err("Not a supported interface type\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ ndev = ath6kl_interface_add(ar, name, type, if_idx, nw_type);
+ if (!ndev)
+ return ERR_PTR(-ENOMEM);
+
+ ar->num_vif++;
+
+ return ndev;
+}
+
+static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
+ struct net_device *ndev)
+{
+ struct ath6kl *ar = wiphy_priv(wiphy);
+ struct ath6kl_vif *vif = netdev_priv(ndev);
+
+ spin_lock(&ar->list_lock);
+ list_del(&vif->list);
+ spin_unlock(&ar->list_lock);
+
+ ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
+
+ ath6kl_deinit_if_data(vif);
+
+ return 0;
+}
+
static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
struct net_device *ndev,
enum nl80211_iftype type, u32 *flags,
@@ -1946,6 +2043,8 @@ ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
};

static struct cfg80211_ops ath6kl_cfg80211_ops = {
+ .add_virtual_intf = ath6kl_cfg80211_add_iface,
+ .del_virtual_intf = ath6kl_cfg80211_del_iface,
.change_virtual_intf = ath6kl_cfg80211_change_iface,
.scan = ath6kl_cfg80211_scan,
.connect = ath6kl_cfg80211_connect,
@@ -2096,18 +2195,28 @@ static int ath6kl_init_if_data(struct ath6kl_vif *vif)

void ath6kl_deinit_if_data(struct ath6kl_vif *vif)
{
+ struct ath6kl *ar = vif->ar;
+
aggr_module_destroy(vif->aggr_cntxt);

+ ar->avail_idx_map |= BIT(vif->fw_vif_idx);
+
+ if (vif->nw_type == ADHOC_NETWORK)
+ ar->ibss_if_active = false;
+
unregister_netdevice(vif->ndev);
+
+ ar->num_vif--;
}

struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
- enum nl80211_iftype type, u8 fw_vif_idx)
+ enum nl80211_iftype type, u8 fw_vif_idx,
+ u8 nw_type)
{
struct net_device *ndev;
struct ath6kl_vif *vif;

- ndev = alloc_netdev(sizeof(*vif), "wlan%d", ether_setup);
+ ndev = alloc_netdev(sizeof(*vif), name, ether_setup);
if (!ndev)
return NULL;

@@ -2120,8 +2229,14 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
vif->wdev.netdev = ndev;
vif->wdev.iftype = type;
vif->fw_vif_idx = fw_vif_idx;
+ vif->nw_type = vif->next_mode = nw_type;
ar->wdev = &vif->wdev;

+ memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
+ if (fw_vif_idx != 0)
+ ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) |
+ 0x2;
+
init_netdev(ndev);

ath6kl_init_control_info(vif);
@@ -2133,11 +2248,15 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
if (register_netdevice(ndev))
goto err;

+ ar->avail_idx_map &= ~BIT(fw_vif_idx);
vif->sme_state = SME_DISCONNECTED;
set_bit(WLAN_ENABLED, &vif->flags);
ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
set_bit(NETDEV_REGISTERED, &vif->flags);

+ if (type == NL80211_IFTYPE_ADHOC)
+ ar->ibss_if_active = true;
+
spin_lock(&ar->list_lock);
list_add_tail(&vif->list, &ar->vif_list);
spin_unlock(&ar->list_lock);
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h
index 66042f2..d1a0216 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.h
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h
@@ -19,7 +19,7 @@

struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
enum nl80211_iftype type,
- u8 fw_vif_idx);
+ u8 fw_vif_idx, u8 nw_type);
int ath6kl_register_ieee80211_hw(struct ath6kl *ar);
struct ath6kl *ath6kl_core_alloc(struct device *dev);
void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar);
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 29bb235..6933fb6 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -460,6 +460,8 @@ struct ath6kl {
struct list_head vif_list;
/* Lock to avoid race in vif_list entries among add/del/traverse */
spinlock_t list_lock;
+ u8 num_vif;
+ u8 avail_idx_map;
spinlock_t lock;
struct semaphore sem;
u16 listen_intvl_b;
@@ -470,6 +472,7 @@ struct ath6kl {
u8 tx_pwr;
struct ath6kl_node_mapping node_map[MAX_NODE_NUM];
u8 ibss_ps_enable;
+ bool ibss_if_active;
u8 node_num;
u8 next_ep_id;
struct ath6kl_cookie *cookie_list;
@@ -666,4 +669,5 @@ void ath6kl_init_control_info(struct ath6kl_vif *vif);
void ath6kl_deinit_if_data(struct ath6kl_vif *vif);
void ath6kl_core_free(struct ath6kl *ar);
struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar);
+void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready);
#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index e76d118..2780170 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -88,7 +88,6 @@ void ath6kl_init_profile_info(struct ath6kl_vif *vif)
memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
memset(vif->bssid, 0, sizeof(vif->bssid));
vif->bss_ch = 0;
- vif->nw_type = vif->next_mode = INFRA_NETWORK;
}

static int ath6kl_set_host_app_area(struct ath6kl *ar)
@@ -1414,6 +1413,7 @@ static int ath6kl_init(struct ath6kl *ar)
int status = 0;
s32 timeleft;
struct net_device *ndev;
+ int i;

if (!ar)
return -EIO;
@@ -1445,10 +1445,14 @@ static int ath6kl_init(struct ath6kl *ar)
goto err_node_cleanup;
}

+ for (i = 0; i < MAX_NUM_VIF; i++)
+ ar->avail_idx_map |= BIT(i);
+
rtnl_lock();

/* Add an initial station interface */
- ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0);
+ ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0,
+ INFRA_NETWORK);

rtnl_unlock();

@@ -1631,7 +1635,7 @@ err_wq:
return ret;
}

-static void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
+void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
{
static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
bool discon_issued;
--
1.7.0.4


Subject: [PATCH V2 07/31] ath6kl: Move ssid and crypto information to vif structure

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 175 +++++++++++++++-------------
drivers/net/wireless/ath/ath6kl/core.h | 18 ++--
drivers/net/wireless/ath/ath6kl/init.c | 25 +++--
drivers/net/wireless/ath/ath6kl/main.c | 8 +-
4 files changed, 125 insertions(+), 101 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index fed31cf..f9732f7 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -126,14 +126,17 @@ static struct ieee80211_supported_band ath6kl_band_5ghz = {
static int ath6kl_set_wpa_version(struct ath6kl *ar,
enum nl80211_wpa_versions wpa_version)
{
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
+
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);

if (!wpa_version) {
- ar->auth_mode = NONE_AUTH;
+ vif->auth_mode = NONE_AUTH;
} else if (wpa_version & NL80211_WPA_VERSION_2) {
- ar->auth_mode = WPA2_AUTH;
+ vif->auth_mode = WPA2_AUTH;
} else if (wpa_version & NL80211_WPA_VERSION_1) {
- ar->auth_mode = WPA_AUTH;
+ vif->auth_mode = WPA_AUTH;
} else {
ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
return -ENOTSUPP;
@@ -145,22 +148,24 @@ static int ath6kl_set_wpa_version(struct ath6kl *ar,
static int ath6kl_set_auth_type(struct ath6kl *ar,
enum nl80211_auth_type auth_type)
{
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);

switch (auth_type) {
case NL80211_AUTHTYPE_OPEN_SYSTEM:
- ar->dot11_auth_mode = OPEN_AUTH;
+ vif->dot11_auth_mode = OPEN_AUTH;
break;
case NL80211_AUTHTYPE_SHARED_KEY:
- ar->dot11_auth_mode = SHARED_AUTH;
+ vif->dot11_auth_mode = SHARED_AUTH;
break;
case NL80211_AUTHTYPE_NETWORK_EAP:
- ar->dot11_auth_mode = LEAP_AUTH;
+ vif->dot11_auth_mode = LEAP_AUTH;
break;

case NL80211_AUTHTYPE_AUTOMATIC:
- ar->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
+ vif->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
break;

default:
@@ -173,9 +178,12 @@ static int ath6kl_set_auth_type(struct ath6kl *ar,

static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast)
{
- u8 *ar_cipher = ucast ? &ar->prwise_crypto : &ar->grp_crypto;
- u8 *ar_cipher_len = ucast ? &ar->prwise_crypto_len :
- &ar->grp_crypto_len;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
+
+ u8 *ar_cipher = ucast ? &vif->prwise_crypto : &vif->grp_crypto;
+ u8 *ar_cipher_len = ucast ? &vif->prwise_crypto_len :
+ &vif->grp_crypto_len;

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
__func__, cipher, ucast);
@@ -212,20 +220,23 @@ static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast)

static void ath6kl_set_key_mgmt(struct ath6kl *ar, u32 key_mgmt)
{
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
+
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);

if (key_mgmt == WLAN_AKM_SUITE_PSK) {
- if (ar->auth_mode == WPA_AUTH)
- ar->auth_mode = WPA_PSK_AUTH;
- else if (ar->auth_mode == WPA2_AUTH)
- ar->auth_mode = WPA2_PSK_AUTH;
+ if (vif->auth_mode == WPA_AUTH)
+ vif->auth_mode = WPA_PSK_AUTH;
+ else if (vif->auth_mode == WPA2_AUTH)
+ vif->auth_mode = WPA2_PSK_AUTH;
} else if (key_mgmt == 0x00409600) {
- if (ar->auth_mode == WPA_AUTH)
- ar->auth_mode = WPA_AUTH_CCKM;
- else if (ar->auth_mode == WPA2_AUTH)
- ar->auth_mode = WPA2_AUTH_CCKM;
+ if (vif->auth_mode == WPA_AUTH)
+ vif->auth_mode = WPA_AUTH_CCKM;
+ else if (vif->auth_mode == WPA2_AUTH)
+ vif->auth_mode = WPA2_AUTH_CCKM;
} else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
- ar->auth_mode = NONE_AUTH;
+ vif->auth_mode = NONE_AUTH;
}
}

@@ -349,8 +360,8 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
}

if (test_bit(CONNECTED, &vif->flags) &&
- ar->ssid_len == sme->ssid_len &&
- !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
+ vif->ssid_len == sme->ssid_len &&
+ !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
ar->reconnect_flag = true;
status = ath6kl_wmi_reconnect_cmd(ar->wmi, ar->req_bssid,
ar->ch_hint);
@@ -361,14 +372,14 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
return -EIO;
}
return 0;
- } else if (ar->ssid_len == sme->ssid_len &&
- !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
+ } else if (vif->ssid_len == sme->ssid_len &&
+ !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
ath6kl_disconnect(ar);
}

- memset(ar->ssid, 0, sizeof(ar->ssid));
- ar->ssid_len = sme->ssid_len;
- memcpy(ar->ssid, sme->ssid, sme->ssid_len);
+ memset(vif->ssid, 0, sizeof(vif->ssid));
+ vif->ssid_len = sme->ssid_len;
+ memcpy(vif->ssid, sme->ssid, sme->ssid_len);

if (sme->channel)
ar->ch_hint = sme->channel->center_freq;
@@ -396,7 +407,8 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
ath6kl_set_key_mgmt(ar, sme->crypto.akm_suites[0]);

if ((sme->key_len) &&
- (ar->auth_mode == NONE_AUTH) && (ar->prwise_crypto == WEP_CRYPT)) {
+ (vif->auth_mode == NONE_AUTH) &&
+ (vif->prwise_crypto == WEP_CRYPT)) {
struct ath6kl_key *key = NULL;

if (sme->key_idx < WMI_MIN_KEY_INDEX ||
@@ -410,11 +422,11 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
key = &ar->keys[sme->key_idx];
key->key_len = sme->key_len;
memcpy(key->key, sme->key, key->key_len);
- key->cipher = ar->prwise_crypto;
- ar->def_txkey_index = sme->key_idx;
+ key->cipher = vif->prwise_crypto;
+ vif->def_txkey_index = sme->key_idx;

ath6kl_wmi_addkey_cmd(ar->wmi, sme->key_idx,
- ar->prwise_crypto,
+ vif->prwise_crypto,
GROUP_USAGE | TX_USAGE,
key->key_len,
NULL,
@@ -438,25 +450,25 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
" PW crypto %d PW crypto len %d GRP crypto %d"
" GRP crypto len %d channel hint %u\n",
__func__,
- ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
- ar->prwise_crypto_len, ar->grp_crypto,
- ar->grp_crypto_len, ar->ch_hint);
+ vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
+ vif->prwise_crypto_len, vif->grp_crypto,
+ vif->grp_crypto_len, ar->ch_hint);

ar->reconnect_flag = 0;
status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
- ar->dot11_auth_mode, ar->auth_mode,
- ar->prwise_crypto,
- ar->prwise_crypto_len,
- ar->grp_crypto, ar->grp_crypto_len,
- ar->ssid_len, ar->ssid,
+ vif->dot11_auth_mode, vif->auth_mode,
+ vif->prwise_crypto,
+ vif->prwise_crypto_len,
+ vif->grp_crypto, vif->grp_crypto_len,
+ vif->ssid_len, vif->ssid,
ar->req_bssid, ar->ch_hint,
ar->connect_ctrl_flags);

up(&ar->sem);

if (status == -EINVAL) {
- memset(ar->ssid, 0, sizeof(ar->ssid));
- ar->ssid_len = 0;
+ memset(vif->ssid, 0, sizeof(vif->ssid));
+ vif->ssid_len = 0;
ath6kl_err("invalid request\n");
return -ENOENT;
} else if (status) {
@@ -465,8 +477,8 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
}

if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
- ((ar->auth_mode == WPA_PSK_AUTH)
- || (ar->auth_mode == WPA2_PSK_AUTH))) {
+ ((vif->auth_mode == WPA_PSK_AUTH)
+ || (vif->auth_mode == WPA2_PSK_AUTH))) {
mod_timer(&ar->disconnect_timer,
jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
}
@@ -481,11 +493,13 @@ static int ath6kl_add_bss_if_needed(struct ath6kl *ar, const u8 *bssid,
struct ieee80211_channel *chan,
const u8 *beacon_ie, size_t beacon_ie_len)
{
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
struct cfg80211_bss *bss;
u8 *ie;

bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
- ar->ssid, ar->ssid_len, WLAN_CAPABILITY_ESS,
+ vif->ssid, vif->ssid_len, WLAN_CAPABILITY_ESS,
WLAN_CAPABILITY_ESS);
if (bss == NULL) {
/*
@@ -496,16 +510,16 @@ static int ath6kl_add_bss_if_needed(struct ath6kl *ar, const u8 *bssid,
* Prepend SSID element since it is not included in the Beacon
* IEs from the target.
*/
- ie = kmalloc(2 + ar->ssid_len + beacon_ie_len, GFP_KERNEL);
+ ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
if (ie == NULL)
return -ENOMEM;
ie[0] = WLAN_EID_SSID;
- ie[1] = ar->ssid_len;
- memcpy(ie + 2, ar->ssid, ar->ssid_len);
- memcpy(ie + 2 + ar->ssid_len, beacon_ie, beacon_ie_len);
+ ie[1] = vif->ssid_len;
+ memcpy(ie + 2, vif->ssid, vif->ssid_len);
+ memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
bss = cfg80211_inform_bss(ar->wiphy, chan,
bssid, 0, WLAN_CAPABILITY_ESS, 100,
- ie, 2 + ar->ssid_len + beacon_ie_len,
+ ie, 2 + vif->ssid_len + beacon_ie_len,
0, GFP_KERNEL);
if (bss)
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added dummy bss for "
@@ -606,6 +620,7 @@ static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
struct net_device *dev, u16 reason_code)
{
struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
reason_code);
@@ -625,8 +640,8 @@ static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,

ar->reconnect_flag = 0;
ath6kl_disconnect(ar);
- memset(ar->ssid, 0, sizeof(ar->ssid));
- ar->ssid_len = 0;
+ memset(vif->ssid, 0, sizeof(vif->ssid));
+ vif->ssid_len = 0;

if (!test_bit(SKIP_SCAN, &ar->flag))
memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
@@ -879,8 +894,8 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
return -ENOTSUPP;
}

- if (((ar->auth_mode == WPA_PSK_AUTH)
- || (ar->auth_mode == WPA2_PSK_AUTH))
+ if (((vif->auth_mode == WPA_PSK_AUTH)
+ || (vif->auth_mode == WPA2_PSK_AUTH))
&& (key_usage & GROUP_USAGE))
del_timer(&ar->disconnect_timer);

@@ -889,7 +904,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
__func__, key_index, key->key_len, key_type,
key_usage, key->seq_len);

- ar->def_txkey_index = key_index;
+ vif->def_txkey_index = key_index;

if (ar->nw_type == AP_NETWORK && !pairwise &&
(key_type == TKIP_CRYPT || key_type == AES_CRYPT) && params) {
@@ -924,7 +939,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
return 0;
}

- status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
+ status = ath6kl_wmi_addkey_cmd(ar->wmi, vif->def_txkey_index,
key_type, key_usage, key->key_len,
key->seq, key->key, KEY_OP_INIT_VAL,
(u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
@@ -1029,20 +1044,20 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
return -EINVAL;
}

- ar->def_txkey_index = key_index;
- key = &ar->keys[ar->def_txkey_index];
+ vif->def_txkey_index = key_index;
+ key = &ar->keys[vif->def_txkey_index];
key_usage = GROUP_USAGE;
- if (ar->prwise_crypto == WEP_CRYPT)
+ if (vif->prwise_crypto == WEP_CRYPT)
key_usage |= TX_USAGE;
if (unicast)
- key_type = ar->prwise_crypto;
+ key_type = vif->prwise_crypto;
if (multicast)
- key_type = ar->grp_crypto;
+ key_type = vif->grp_crypto;

if (ar->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
return 0; /* Delay until AP mode has been started */

- status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
+ status = ath6kl_wmi_addkey_cmd(ar->wmi, vif->def_txkey_index,
key_type, key_usage,
key->key_len, key->seq, key->key,
KEY_OP_INIT_VAL, NULL,
@@ -1229,8 +1244,8 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
if (!ath6kl_cfg80211_ready(ar))
return -EIO;

- ar->ssid_len = ibss_param->ssid_len;
- memcpy(ar->ssid, ibss_param->ssid, ar->ssid_len);
+ vif->ssid_len = ibss_param->ssid_len;
+ memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);

if (ibss_param->channel)
ar->ch_hint = ibss_param->channel->center_freq;
@@ -1270,16 +1285,16 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
" PW crypto %d PW crypto len %d GRP crypto %d"
" GRP crypto len %d channel hint %u\n",
__func__,
- ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
- ar->prwise_crypto_len, ar->grp_crypto,
- ar->grp_crypto_len, ar->ch_hint);
+ vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
+ vif->prwise_crypto_len, vif->grp_crypto,
+ vif->grp_crypto_len, ar->ch_hint);

status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
- ar->dot11_auth_mode, ar->auth_mode,
- ar->prwise_crypto,
- ar->prwise_crypto_len,
- ar->grp_crypto, ar->grp_crypto_len,
- ar->ssid_len, ar->ssid,
+ vif->dot11_auth_mode, vif->auth_mode,
+ vif->prwise_crypto,
+ vif->prwise_crypto_len,
+ vif->grp_crypto, vif->grp_crypto_len,
+ vif->ssid_len, vif->ssid,
ar->req_bssid, ar->ch_hint,
ar->connect_ctrl_flags);
set_bit(CONNECT_PEND, &vif->flags);
@@ -1291,13 +1306,14 @@ static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
struct net_device *dev)
{
struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);

if (!ath6kl_cfg80211_ready(ar))
return -EIO;

ath6kl_disconnect(ar);
- memset(ar->ssid, 0, sizeof(ar->ssid));
- ar->ssid_len = 0;
+ memset(vif->ssid, 0, sizeof(vif->ssid));
+ vif->ssid_len = 0;

return 0;
}
@@ -1575,6 +1591,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
struct beacon_parameters *info, bool add)
{
struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);
struct ieee80211_mgmt *mgmt;
u8 *ies;
int ies_len;
@@ -1631,12 +1648,12 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,

if (info->ssid == NULL)
return -EINVAL;
- memcpy(ar->ssid, info->ssid, info->ssid_len);
- ar->ssid_len = info->ssid_len;
+ memcpy(vif->ssid, info->ssid, info->ssid_len);
+ vif->ssid_len = info->ssid_len;
if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
return -EOPNOTSUPP; /* TODO */

- ar->dot11_auth_mode = OPEN_AUTH;
+ vif->dot11_auth_mode = OPEN_AUTH;

memset(&p, 0, sizeof(p));

@@ -1658,7 +1675,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
}
if (p.auth_mode == 0)
p.auth_mode = NONE_AUTH;
- ar->auth_mode = p.auth_mode;
+ vif->auth_mode = p.auth_mode;

for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
switch (info->crypto.ciphers_pairwise[i]) {
@@ -1700,9 +1717,9 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
p.nw_type = AP_NETWORK;
ar->nw_type = ar->next_mode;

- p.ssid_len = ar->ssid_len;
- memcpy(p.ssid, ar->ssid, ar->ssid_len);
- p.dot11_auth_mode = ar->dot11_auth_mode;
+ p.ssid_len = vif->ssid_len;
+ memcpy(p.ssid, vif->ssid, vif->ssid_len);
+ p.dot11_auth_mode = vif->dot11_auth_mode;
p.ch = cpu_to_le16(ar->next_chan);

res = ath6kl_wmi_ap_profile_commit(ar->wmi, &p);
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 4777171..f401715 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -398,6 +398,15 @@ struct ath6kl_vif {
struct net_device *ndev;
struct ath6kl *ar;
unsigned long flags;
+ int ssid_len;
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+ u8 dot11_auth_mode;
+ u8 auth_mode;
+ u8 prwise_crypto;
+ u8 prwise_crypto_len;
+ u8 grp_crypto;
+ u8 grp_crypto_len;
+ u8 def_txkey_index;
};

/* Flag info */
@@ -426,17 +435,8 @@ struct ath6kl {
struct ath6kl_vif *vif;
spinlock_t lock;
struct semaphore sem;
- int ssid_len;
- u8 ssid[IEEE80211_MAX_SSID_LEN];
u8 next_mode;
u8 nw_type;
- u8 dot11_auth_mode;
- u8 auth_mode;
- u8 prwise_crypto;
- u8 prwise_crypto_len;
- u8 grp_crypto;
- u8 grp_crypto_len;
- u8 def_txkey_index;
struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
u8 bssid[ETH_ALEN];
u8 req_bssid[ETH_ALEN];
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 91c2783..1aac79c 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -75,15 +75,18 @@ struct sk_buff *ath6kl_buf_alloc(int size)

void ath6kl_init_profile_info(struct ath6kl *ar)
{
- ar->ssid_len = 0;
- memset(ar->ssid, 0, sizeof(ar->ssid));
-
- ar->dot11_auth_mode = OPEN_AUTH;
- ar->auth_mode = NONE_AUTH;
- ar->prwise_crypto = NONE_CRYPT;
- ar->prwise_crypto_len = 0;
- ar->grp_crypto = NONE_CRYPT;
- ar->grp_crypto_len = 0;
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
+
+ vif->ssid_len = 0;
+ memset(vif->ssid, 0, sizeof(vif->ssid));
+
+ vif->dot11_auth_mode = OPEN_AUTH;
+ vif->auth_mode = NONE_AUTH;
+ vif->prwise_crypto = NONE_CRYPT;
+ vif->prwise_crypto_len = 0;
+ vif->grp_crypto = NONE_CRYPT;
+ vif->grp_crypto_len = 0;
memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
memset(ar->bssid, 0, sizeof(ar->bssid));
@@ -245,8 +248,10 @@ static int ath6kl_init_service_ep(struct ath6kl *ar)

void ath6kl_init_control_info(struct ath6kl *ar)
{
+ struct ath6kl_vif *vif = ar->vif;
+
ath6kl_init_profile_info(ar);
- ar->def_txkey_index = 0;
+ vif->def_txkey_index = 0;
memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
ar->ch_hint = 0;
}
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 6a0eaea..a207377 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -498,13 +498,15 @@ void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,

static void ath6kl_install_static_wep_keys(struct ath6kl *ar)
{
+ /* TODO: Findout vif */
+ struct ath6kl_vif *vif = ar->vif;
u8 index;
u8 keyusage;

for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
if (ar->wep_key_list[index].key_len) {
keyusage = GROUP_USAGE;
- if (index == ar->def_txkey_index)
+ if (index == vif->def_txkey_index)
keyusage |= TX_USAGE;

ath6kl_wmi_addkey_cmd(ar->wmi,
@@ -532,9 +534,9 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel)

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "AP mode started on %u MHz\n", channel);

- switch (ar->auth_mode) {
+ switch (vif->auth_mode) {
case NONE_AUTH:
- if (ar->prwise_crypto == WEP_CRYPT)
+ if (vif->prwise_crypto == WEP_CRYPT)
ath6kl_install_static_wep_keys(ar);
break;
case WPA_PSK_AUTH:
--
1.7.0.4


Subject: [PATCH V2 20/31] ath6kl: Cleanup parameters in ath6kl_init_control_info() and ath6kl_init_profile_info()

Pass vif structure to those functions instead of ath6kl because these
functions do vif specific information initialization.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 2 +-
drivers/net/wireless/ath/ath6kl/core.h | 4 ++--
drivers/net/wireless/ath/ath6kl/init.c | 12 +++---------
drivers/net/wireless/ath/ath6kl/main.c | 4 ++--
4 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 636b64e..0d02ba0 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -2118,7 +2118,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,

init_netdev(ndev);

- ath6kl_init_control_info(ar);
+ ath6kl_init_control_info(vif);

/* TODO: Pass interface specific pointer instead of ar */
if (ath6kl_init_if_data(vif))
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 4db0b15..de288ff 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -602,7 +602,7 @@ int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length);
int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value);
int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length);
int ath6kl_read_fwlogs(struct ath6kl *ar);
-void ath6kl_init_profile_info(struct ath6kl *ar);
+void ath6kl_init_profile_info(struct ath6kl_vif *vif);
void ath6kl_tx_data_cleanup(struct ath6kl *ar);
void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
bool get_dbglogs);
@@ -657,7 +657,7 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no,
void ath6kl_wakeup_event(void *dev);
void ath6kl_target_failure(struct ath6kl *ar);

-void ath6kl_init_control_info(struct ath6kl *ar);
+void ath6kl_init_control_info(struct ath6kl_vif *vif);
void ath6kl_deinit_if_data(struct ath6kl_vif *vif);
void ath6kl_core_free(struct ath6kl *ar);
#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index a874665..4bb348e 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -73,11 +73,8 @@ struct sk_buff *ath6kl_buf_alloc(int size)
return skb;
}

-void ath6kl_init_profile_info(struct ath6kl *ar)
+void ath6kl_init_profile_info(struct ath6kl_vif *vif)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
-
vif->ssid_len = 0;
memset(vif->ssid, 0, sizeof(vif->ssid));

@@ -246,12 +243,9 @@ static int ath6kl_init_service_ep(struct ath6kl *ar)
return 0;
}

-void ath6kl_init_control_info(struct ath6kl *ar)
+void ath6kl_init_control_info(struct ath6kl_vif *vif)
{
- /* TODO: Findout vif */
- struct ath6kl_vif *vif = ar->vif;
-
- ath6kl_init_profile_info(ar);
+ ath6kl_init_profile_info(vif);
vif->def_txkey_index = 0;
memset(vif->wep_key_list, 0, sizeof(vif->wep_key_list));
vif->ch_hint = 0;
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 023624d..08af257 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -443,7 +443,7 @@ void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
test_bit(CONNECT_PEND, &vif->flags));
ath6kl_disconnect(vif);
if (!keep_profile)
- ath6kl_init_profile_info(ar);
+ ath6kl_init_profile_info(vif);

del_timer(&vif->disconnect_timer);

@@ -913,7 +913,7 @@ void disconnect_timer_handler(unsigned long ptr)
struct net_device *dev = (struct net_device *)ptr;
struct ath6kl_vif *vif = netdev_priv(dev);

- ath6kl_init_profile_info(vif->ar);
+ ath6kl_init_profile_info(vif);
ath6kl_disconnect(vif);
}

--
1.7.0.4


Subject: [PATCH V2 27/31] ath6kl: Configure inteface information at init time

Virtual interface information need to be configured during
init time to the target. With MAX_NUM_VIF is restricted to
1, currently only a single vif is being configured.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/init.c | 45 ++++++++++++++++++++++++-----
drivers/net/wireless/ath/ath6kl/target.h | 3 ++
2 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index d541dc9..e76d118 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -429,11 +429,42 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar)
int ath6kl_configure_target(struct ath6kl *ar)
{
u32 param, ram_reserved_size;
- u8 fw_iftype;
+ u8 fw_iftype, fw_mode = 0, fw_submode;
+ int i;

+ /*
+ * Note: Even though the firmware interface type is
+ * chosen as BSS_STA for all three interfaces, can
+ * be configured to IBSS/AP as long as the fw submode
+ * remains normal mode (0 - AP, STA and IBSS). But
+ * due to an target assert in firmware only one interface is
+ * configured for now.
+ */
fw_iftype = HI_OPTION_FW_MODE_BSS_STA;

- /* Tell target which HTC version it is used*/
+ for (i = 0; i < MAX_NUM_VIF; i++)
+ fw_mode |= fw_iftype << (i * HI_OPTION_FW_MODE_BITS);
+
+ /*
+ * submodes : vif[0] - AP/STA/IBSS
+ * vif[1] - "P2P dev"/"P2P GO"/"P2P Client"
+ * vif[2] - "P2P dev"/"P2P GO"/"P2P Client"
+ */
+ fw_submode = HI_OPTION_FW_SUBMODE_NONE |
+ (HI_OPTION_FW_SUBMODE_P2PDEV <<
+ (1 * HI_OPTION_FW_SUBMODE_BITS)) |
+ (HI_OPTION_FW_SUBMODE_P2PDEV <<
+ (2 * HI_OPTION_FW_SUBMODE_BITS));
+
+ /*
+ * FIXME: This needs to be removed once the multivif
+ * support is enabled.
+ */
+ if (ar->p2p)
+ fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV;
+ else
+ fw_submode = HI_OPTION_FW_SUBMODE_NONE;
+
param = HTC_PROTOCOL_VERSION;
if (ath6kl_bmi_write(ar,
ath6kl_get_hi_item_addr(ar,
@@ -454,12 +485,10 @@ int ath6kl_configure_target(struct ath6kl *ar)
return -EIO;
}

- param |= (1 << HI_OPTION_NUM_DEV_SHIFT);
- param |= (fw_iftype << HI_OPTION_FW_MODE_SHIFT);
- if (ar->p2p && fw_iftype == HI_OPTION_FW_MODE_BSS_STA) {
- param |= HI_OPTION_FW_SUBMODE_P2PDEV <<
- HI_OPTION_FW_SUBMODE_SHIFT;
- }
+ param |= (MAX_NUM_VIF << HI_OPTION_NUM_DEV_SHIFT);
+ param |= fw_mode << HI_OPTION_FW_MODE_SHIFT;
+ param |= fw_submode << HI_OPTION_FW_SUBMODE_SHIFT;
+
param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);

diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h
index c9a7605..687e2b3 100644
--- a/drivers/net/wireless/ath/ath6kl/target.h
+++ b/drivers/net/wireless/ath/ath6kl/target.h
@@ -320,7 +320,10 @@ struct host_interest {
| (2) | (2) | (2) | (2) | (2) | (2) | (2) | (2)
|------------------------------------------------------------------------------|
*/
+#define HI_OPTION_FW_MODE_BITS 0x2
#define HI_OPTION_FW_MODE_SHIFT 0xC
+
+#define HI_OPTION_FW_SUBMODE_BITS 0x2
#define HI_OPTION_FW_SUBMODE_SHIFT 0x14

/* Convert a Target virtual address into a Target physical address */
--
1.7.0.4


Subject: [PATCH V2 17/31] ath6kl: Maintain firmware interface index in struct ath6kl_vif

Pass this index to target in wmi commands to specify the interface
for which the command needs to be handled.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 125 ++++++++++++---------
drivers/net/wireless/ath/ath6kl/cfg80211.h | 3 +-
drivers/net/wireless/ath/ath6kl/core.h | 5 +-
drivers/net/wireless/ath/ath6kl/debug.c | 4 +-
drivers/net/wireless/ath/ath6kl/init.c | 2 +-
drivers/net/wireless/ath/ath6kl/main.c | 42 ++++---
drivers/net/wireless/ath/ath6kl/sdio.c | 2 +-
drivers/net/wireless/ath/ath6kl/txrx.c | 5 +-
drivers/net/wireless/ath/ath6kl/wmi.c | 172 ++++++++++++++++------------
drivers/net/wireless/ath/ath6kl/wmi.h | 63 ++++++-----
10 files changed, 243 insertions(+), 180 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 55e4c92..c8c5712 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -269,9 +269,10 @@ static bool ath6kl_is_rsn_ie(const u8 *pos)
return pos[0] == WLAN_EID_RSN;
}

-static int ath6kl_set_assoc_req_ies(struct ath6kl *ar, const u8 *ies,
- size_t ies_len)
+static int ath6kl_set_assoc_req_ies(struct ath6kl_vif *vif, const u8 *ies,
+ size_t ies_len)
{
+ struct ath6kl *ar = vif->ar;
const u8 *pos;
u8 *buf = NULL;
size_t len = 0;
@@ -298,8 +299,8 @@ static int ath6kl_set_assoc_req_ies(struct ath6kl *ar, const u8 *ies,
}
}

- ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_ASSOC_REQ,
- buf, len);
+ ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
+ WMI_FRAME_ASSOC_REQ, buf, len);
kfree(buf);
return ret;
}
@@ -354,7 +355,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
}

if (sme->ie && (sme->ie_len > 0)) {
- status = ath6kl_set_assoc_req_ies(ar, sme->ie, sme->ie_len);
+ status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
if (status)
return status;
}
@@ -363,7 +364,8 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
vif->ssid_len == sme->ssid_len &&
!memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
vif->reconnect_flag = true;
- status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->req_bssid,
+ status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->fw_vif_idx,
+ vif->req_bssid,
vif->ch_hint);

up(&ar->sem);
@@ -374,7 +376,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
return 0;
} else if (vif->ssid_len == sme->ssid_len &&
!memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
- ath6kl_disconnect(ar);
+ ath6kl_disconnect(ar, vif->fw_vif_idx);
}

memset(vif->ssid, 0, sizeof(vif->ssid));
@@ -425,7 +427,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
key->cipher = vif->prwise_crypto;
vif->def_txkey_index = sme->key_idx;

- ath6kl_wmi_addkey_cmd(ar->wmi, sme->key_idx,
+ ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, sme->key_idx,
vif->prwise_crypto,
GROUP_USAGE | TX_USAGE,
key->key_len,
@@ -455,7 +457,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
vif->grp_crypto_len, vif->ch_hint);

vif->reconnect_flag = 0;
- status = ath6kl_wmi_connect_cmd(ar->wmi, vif->nw_type,
+ status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
vif->dot11_auth_mode, vif->auth_mode,
vif->prwise_crypto,
vif->prwise_crypto_len,
@@ -639,7 +641,7 @@ static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
}

vif->reconnect_flag = 0;
- ath6kl_disconnect(ar);
+ ath6kl_disconnect(ar, vif->fw_vif_idx);
memset(vif->ssid, 0, sizeof(vif->ssid));
vif->ssid_len = 0;

@@ -695,7 +697,7 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
*/

if (reason != DISCONNECT_CMD) {
- ath6kl_wmi_disconnect_cmd(ar->wmi);
+ ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
return;
}

@@ -747,14 +749,15 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
request->n_ssids = MAX_PROBED_SSID_INDEX - 1;

for (i = 0; i < request->n_ssids; i++)
- ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
- SPECIFIC_SSID_FLAG,
+ ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
+ i + 1, SPECIFIC_SSID_FLAG,
request->ssids[i].ssid_len,
request->ssids[i].ssid);
}

if (request->ie) {
- ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_REQ,
+ ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
+ WMI_FRAME_PROBE_REQ,
request->ie, request->ie_len);
if (ret) {
ath6kl_err("failed to set Probe Request appie for "
@@ -788,8 +791,9 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
if (test_bit(CONNECTED, &vif->flags))
force_fg_scan = 1;

- ret = ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, force_fg_scan,
- false, 0, 0, n_channels, channels);
+ ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx, WMI_LONG_SCAN,
+ force_fg_scan, false, 0, 0, n_channels,
+ channels);
if (ret)
ath6kl_err("wmi_startscan_cmd failed\n");
else
@@ -820,8 +824,8 @@ void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)

if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
for (i = 0; i < vif->scan_req->n_ssids; i++) {
- ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
- DISABLE_SSID_FLAG,
+ ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
+ i + 1, DISABLE_SSID_FLAG,
0, NULL);
}
}
@@ -942,7 +946,8 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
return 0;
}

- status = ath6kl_wmi_addkey_cmd(ar->wmi, vif->def_txkey_index,
+ status = ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
+ vif->def_txkey_index,
key_type, key_usage, key->key_len,
key->seq, key->key, KEY_OP_INIT_VAL,
(u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
@@ -980,7 +985,7 @@ static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,

vif->keys[key_index].key_len = 0;

- return ath6kl_wmi_deletekey_cmd(ar->wmi, key_index);
+ return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index);
}

static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
@@ -1062,7 +1067,8 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
return 0; /* Delay until AP mode has been started */

- status = ath6kl_wmi_addkey_cmd(ar->wmi, vif->def_txkey_index,
+ status = ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
+ vif->def_txkey_index,
key_type, key_usage,
key->key_len, key->seq, key->key,
KEY_OP_INIT_VAL, NULL,
@@ -1179,6 +1185,7 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
{
struct ath6kl *ar = ath6kl_priv(dev);
struct wmi_power_mode_cmd mode;
+ struct ath6kl_vif *vif = netdev_priv(dev);

ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
__func__, pmgmt, timeout);
@@ -1194,7 +1201,8 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
mode.pwr_mode = MAX_PERF_POWER;
}

- if (ath6kl_wmi_powermode_cmd(ar->wmi, mode.pwr_mode) != 0) {
+ if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
+ mode.pwr_mode) != 0) {
ath6kl_err("wmi_powermode_cmd failed\n");
return -EIO;
}
@@ -1299,7 +1307,7 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
vif->prwise_crypto_len, vif->grp_crypto,
vif->grp_crypto_len, vif->ch_hint);

- status = ath6kl_wmi_connect_cmd(ar->wmi, vif->nw_type,
+ status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
vif->dot11_auth_mode, vif->auth_mode,
vif->prwise_crypto,
vif->prwise_crypto_len,
@@ -1321,7 +1329,7 @@ static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
if (!ath6kl_cfg80211_ready(ar))
return -EIO;

- ath6kl_disconnect(ar);
+ ath6kl_disconnect(ar, vif->fw_vif_idx);
memset(vif->ssid, 0, sizeof(vif->ssid));
vif->ssid_len = 0;

@@ -1416,7 +1424,7 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,

set_bit(STATS_UPDATE_PEND, &vif->flags);

- ret = ath6kl_wmi_get_stats_cmd(ar->wmi);
+ ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx);

if (ret != 0) {
up(&ar->sem);
@@ -1500,7 +1508,9 @@ static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
struct cfg80211_pmksa *pmksa)
{
struct ath6kl *ar = ath6kl_priv(netdev);
- return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
+ struct ath6kl_vif *vif = netdev_priv(netdev);
+
+ return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
pmksa->pmkid, true);
}

@@ -1508,7 +1518,9 @@ static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
struct cfg80211_pmksa *pmksa)
{
struct ath6kl *ar = ath6kl_priv(netdev);
- return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
+ struct ath6kl_vif *vif = netdev_priv(netdev);
+
+ return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
pmksa->pmkid, false);
}

@@ -1518,8 +1530,8 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
struct ath6kl_vif *vif = netdev_priv(netdev);

if (test_bit(CONNECTED, &vif->flags))
- return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->bssid,
- NULL, false);
+ return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx,
+ vif->bssid, NULL, false);
return 0;
}

@@ -1564,9 +1576,10 @@ static bool ath6kl_is_p2p_ie(const u8 *pos)
pos[4] == 0x9a && pos[5] == 0x09;
}

-static int ath6kl_set_ap_probe_resp_ies(struct ath6kl *ar, const u8 *ies,
- size_t ies_len)
+static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
+ const u8 *ies, size_t ies_len)
{
+ struct ath6kl *ar = vif->ar;
const u8 *pos;
u8 *buf = NULL;
size_t len = 0;
@@ -1593,8 +1606,8 @@ static int ath6kl_set_ap_probe_resp_ies(struct ath6kl *ar, const u8 *ies,
}
}

- ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_RESP,
- buf, len);
+ ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
+ WMI_FRAME_PROBE_RESP, buf, len);
kfree(buf);
return ret;
}
@@ -1620,20 +1633,22 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
return -EOPNOTSUPP;

if (info->beacon_ies) {
- res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_BEACON,
+ res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
+ WMI_FRAME_BEACON,
info->beacon_ies,
info->beacon_ies_len);
if (res)
return res;
}
if (info->proberesp_ies) {
- res = ath6kl_set_ap_probe_resp_ies(ar, info->proberesp_ies,
+ res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
info->proberesp_ies_len);
if (res)
return res;
}
if (info->assocresp_ies) {
- res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_ASSOC_RESP,
+ res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
+ WMI_FRAME_ASSOC_RESP,
info->assocresp_ies,
info->assocresp_ies_len);
if (res)
@@ -1734,7 +1749,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
p.dot11_auth_mode = vif->dot11_auth_mode;
p.ch = cpu_to_le16(vif->next_chan);

- res = ath6kl_wmi_ap_profile_commit(ar->wmi, &p);
+ res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
if (res < 0)
return res;

@@ -1763,7 +1778,7 @@ static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
if (!test_bit(CONNECTED, &vif->flags))
return -ENOTCONN;

- ath6kl_wmi_disconnect_cmd(ar->wmi);
+ ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
clear_bit(CONNECTED, &vif->flags);

return 0;
@@ -1783,10 +1798,10 @@ static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
return -EOPNOTSUPP;

if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
- return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_AUTHORIZE,
- mac, 0);
- return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_UNAUTHORIZE, mac,
- 0);
+ return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
+ WMI_AP_MLME_AUTHORIZE, mac, 0);
+ return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
+ WMI_AP_MLME_UNAUTHORIZE, mac, 0);
}

static int ath6kl_remain_on_channel(struct wiphy *wiphy,
@@ -1797,13 +1812,14 @@ static int ath6kl_remain_on_channel(struct wiphy *wiphy,
u64 *cookie)
{
struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);

/* TODO: if already pending or ongoing remain-on-channel,
* return -EBUSY */
*cookie = 1; /* only a single pending request is supported */

- return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, chan->center_freq,
- duration);
+ return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
+ chan->center_freq, duration);
}

static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
@@ -1811,16 +1827,19 @@ static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
u64 cookie)
{
struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);

if (cookie != 1)
return -ENOENT;

- return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi);
+ return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
}

-static int ath6kl_send_go_probe_resp(struct ath6kl *ar, const u8 *buf,
- size_t len, unsigned int freq)
+static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
+ const u8 *buf, size_t len,
+ unsigned int freq)
{
+ struct ath6kl *ar = vif->ar;
const u8 *pos;
u8 *p2p;
int p2p_len;
@@ -1847,8 +1866,8 @@ static int ath6kl_send_go_probe_resp(struct ath6kl *ar, const u8 *buf,
pos += 2 + pos[1];
}

- ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, freq, mgmt->da,
- p2p, p2p_len);
+ ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
+ mgmt->da, p2p, p2p_len);
kfree(p2p);
return ret;
}
@@ -1873,7 +1892,7 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
* command to allow the target to fill in the generic IEs.
*/
*cookie = 0; /* TX status not supported */
- return ath6kl_send_go_probe_resp(ar, buf, len,
+ return ath6kl_send_go_probe_resp(vif, buf, len,
chan->center_freq);
}

@@ -1887,7 +1906,8 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
}

*cookie = id;
- return ath6kl_wmi_send_action_cmd(ar->wmi, id, chan->center_freq, wait,
+ return ath6kl_wmi_send_action_cmd(ar->wmi, vif->fw_vif_idx, id,
+ chan->center_freq, wait,
buf, len);
}

@@ -2092,7 +2112,7 @@ void ath6kl_deinit_if_data(struct ath6kl_vif *vif)
}

struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
- enum nl80211_iftype type)
+ enum nl80211_iftype type, u8 fw_vif_idx)
{
struct net_device *ndev;
struct ath6kl_vif *vif;
@@ -2110,6 +2130,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
vif->wdev.netdev = ndev;
vif->wdev.iftype = type;
+ vif->fw_vif_idx = fw_vif_idx;
ar->wdev = &vif->wdev;
ar->net_dev = ndev;

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h
index 5daf685..033e742 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.h
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h
@@ -18,7 +18,8 @@
#define ATH6KL_CFG80211_H

struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
- enum nl80211_iftype type);
+ enum nl80211_iftype type,
+ u8 fw_vif_idx);
int ath6kl_register_ieee80211_hw(struct ath6kl *ar);
struct ath6kl *ath6kl_core_alloc(struct device *dev);
void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar);
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 41d6ae0..f21d777 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -380,6 +380,8 @@ struct ath6kl_req_key {
u8 key_len;
};

+#define MAX_NUM_VIF 1
+
/* vif flags info */
enum ath6kl_vif_state {
CONNECTED,
@@ -398,6 +400,7 @@ struct ath6kl_vif {
struct wireless_dev wdev;
struct net_device *ndev;
struct ath6kl *ar;
+ u8 fw_vif_idx;
unsigned long flags;
int ssid_len;
u8 ssid[IEEE80211_MAX_SSID_LEN];
@@ -647,7 +650,7 @@ enum htc_endpoint_id ath6kl_ac2_endpoint_id(void *devt, u8 ac);
void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid);

void ath6kl_dtimexpiry_event(struct ath6kl *ar);
-void ath6kl_disconnect(struct ath6kl *ar);
+void ath6kl_disconnect(struct ath6kl *ar, u8 if_idx);
void ath6kl_deep_sleep_enable(struct ath6kl *ar);
void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid);
void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no,
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 9a89b42..870e9b1 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -417,7 +417,7 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,

set_bit(STATS_UPDATE_PEND, &vif->flags);

- if (ath6kl_wmi_get_stats_cmd(ar->wmi)) {
+ if (ath6kl_wmi_get_stats_cmd(ar->wmi, 0)) {
up(&ar->sem);
kfree(buf);
return -EIO;
@@ -1477,7 +1477,7 @@ static ssize_t ath6kl_bgscan_int_write(struct file *file,
if (bgscan_int == 0)
bgscan_int = 0xffff;

- ath6kl_wmi_scanparams_cmd(ar->wmi, 0, 0, bgscan_int, 0, 0, 0, 3,
+ ath6kl_wmi_scanparams_cmd(ar->wmi, 0, 0, 0, bgscan_int, 0, 0, 0, 3,
0, 0, 0);

return count;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index a26faae..fb78a2a 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1407,7 +1407,7 @@ static int ath6kl_init(struct ath6kl *ar)
}

/* Add an initial station interface */
- ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION);
+ ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0);
if (!ndev) {
ath6kl_err("Failed to instantiate a network device\n");
status = -ENOMEM;
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index fff1f4a..9929901 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -441,7 +441,7 @@ void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
if (test_bit(WMI_READY, &ar->flag)) {
discon_issued = (test_bit(CONNECTED, &vif->flags) ||
test_bit(CONNECT_PEND, &vif->flags));
- ath6kl_disconnect(ar);
+ ath6kl_disconnect(ar, vif->fw_vif_idx);
if (!keep_profile)
ath6kl_init_profile_info(ar);

@@ -511,7 +511,7 @@ static void ath6kl_install_static_wep_keys(struct ath6kl *ar)
if (index == vif->def_txkey_index)
keyusage |= TX_USAGE;

- ath6kl_wmi_addkey_cmd(ar->wmi,
+ ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
index,
WEP_CRYPT,
keyusage,
@@ -551,7 +551,7 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel)
"the initial group key for AP mode\n");
memset(key_rsc, 0, sizeof(key_rsc));
res = ath6kl_wmi_addkey_cmd(
- ar->wmi, ik->key_index, ik->key_type,
+ ar->wmi, vif->fw_vif_idx, ik->key_index, ik->key_type,
GROUP_USAGE, ik->key_len, key_rsc, ik->key,
KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG);
if (res) {
@@ -913,20 +913,20 @@ void ath6k_credit_distribute(struct htc_credit_state_info *cred_info,
void disconnect_timer_handler(unsigned long ptr)
{
struct net_device *dev = (struct net_device *)ptr;
- struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_vif *vif = netdev_priv(dev);

- ath6kl_init_profile_info(ar);
- ath6kl_disconnect(ar);
+ ath6kl_init_profile_info(vif->ar);
+ ath6kl_disconnect(vif->ar, vif->fw_vif_idx);
}

-void ath6kl_disconnect(struct ath6kl *ar)
+void ath6kl_disconnect(struct ath6kl *ar, u8 if_idx)
{
/* TODO: Pass vif instead of taking it from ar */
struct ath6kl_vif *vif = ar->vif;

if (test_bit(CONNECTED, &vif->flags) ||
test_bit(CONNECT_PEND, &vif->flags)) {
- ath6kl_wmi_disconnect_cmd(ar->wmi);
+ ath6kl_wmi_disconnect_cmd(ar->wmi, if_idx);
/*
* Disconnect command is issued, clear the connect pending
* flag. The connected flag will be cleared in
@@ -961,13 +961,13 @@ void ath6kl_deep_sleep_enable(struct ath6kl *ar)

if (test_bit(CONNECTED, &vif->flags) ||
test_bit(CONNECT_PEND, &vif->flags))
- ath6kl_wmi_disconnect_cmd(ar->wmi);
+ ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);

vif->sme_state = SME_DISCONNECTED;

/* disable scanning */
- if (ath6kl_wmi_scanparams_cmd(ar->wmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0,
- 0, 0) != 0)
+ if (ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0xFFFF, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0) != 0)
printk(KERN_WARNING "ath6kl: failed to disable scan "
"during suspend\n");

@@ -976,7 +976,7 @@ void ath6kl_deep_sleep_enable(struct ath6kl *ar)
/* save the current power mode before enabling power save */
ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;

- if (ath6kl_wmi_powermode_cmd(ar->wmi, REC_POWER) != 0)
+ if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
ath6kl_warn("ath6kl_deep_sleep_enable: "
"wmi_powermode_cmd failed\n");
}
@@ -1061,7 +1061,8 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
vif->bss_ch = channel;

if ((vif->nw_type == INFRA_NETWORK))
- ath6kl_wmi_listeninterval_cmd(ar->wmi, ar->listen_intvl_t,
+ ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
+ ar->listen_intvl_t,
ar->listen_intvl_b);

netif_wake_queue(ar->net_dev);
@@ -1280,6 +1281,8 @@ void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid)
struct ath6kl_sta *conn;
struct sk_buff *skb;
bool psq_empty = false;
+ /* TODO: Pass vif instead of taking it from ar */
+ struct ath6kl_vif *vif = ar->vif;

conn = ath6kl_find_sta_by_aid(ar, aid);

@@ -1310,7 +1313,7 @@ void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid)
spin_unlock_bh(&conn->psq_lock);

if (psq_empty)
- ath6kl_wmi_set_pvb_cmd(ar->wmi, conn->aid, 0);
+ ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, conn->aid, 0);
}

void ath6kl_dtimexpiry_event(struct ath6kl *ar)
@@ -1355,7 +1358,7 @@ void ath6kl_dtimexpiry_event(struct ath6kl *ar)
clear_bit(DTIM_EXPIRED, &vif->flags);

/* clear the LSB of the BitMapCtl field of the TIM IE */
- ath6kl_wmi_set_pvb_cmd(ar->wmi, MCAST_AID, 0);
+ ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, MCAST_AID, 0);
}

void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
@@ -1377,7 +1380,8 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,

/* clear the LSB of the TIM IE's BitMapCtl field */
if (test_bit(WMI_READY, &ar->flag))
- ath6kl_wmi_set_pvb_cmd(ar->wmi, MCAST_AID, 0);
+ ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
+ MCAST_AID, 0);
}

if (!is_broadcast_ether_addr(bssid)) {
@@ -1468,11 +1472,11 @@ static int ath6kl_close(struct net_device *dev)

netif_stop_queue(dev);

- ath6kl_disconnect(ar);
+ ath6kl_disconnect(ar, vif->fw_vif_idx);

if (test_bit(WMI_READY, &ar->flag)) {
- if (ath6kl_wmi_scanparams_cmd(ar->wmi, 0xFFFF, 0, 0, 0, 0, 0, 0,
- 0, 0, 0))
+ if (ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0xFFFF,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0))
return -EIO;

clear_bit(WLAN_ENABLED, &vif->flags);
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 4e43878..f73e14f 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -747,7 +747,7 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar)
static int ath6kl_sdio_resume(struct ath6kl *ar)
{
if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
- if (ath6kl_wmi_powermode_cmd(ar->wmi,
+ if (ath6kl_wmi_powermode_cmd(ar->wmi, 0,
ar->wmi->saved_pwr_mode) != 0)
ath6kl_warn("ath6kl_sdio_resume: "
"wmi_powermode_cmd failed\n");
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index cada197..c54f1a9 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -118,6 +118,7 @@ static bool ath6kl_powersave_ap(struct ath6kl *ar, struct sk_buff *skb,
*/
if (is_mcastq_empty)
ath6kl_wmi_set_pvb_cmd(ar->wmi,
+ vif->fw_vif_idx,
MCAST_AID, 1);

ps_queued = true;
@@ -156,6 +157,7 @@ static bool ath6kl_powersave_ap(struct ath6kl *ar, struct sk_buff *skb,
*/
if (is_psq_empty)
ath6kl_wmi_set_pvb_cmd(ar->wmi,
+ vif->fw_vif_idx,
conn->aid, 1);

ps_queued = true;
@@ -1176,7 +1178,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
}
spin_unlock_bh(&conn->psq_lock);
/* Clear the PVB for this STA */
- ath6kl_wmi_set_pvb_cmd(ar->wmi, conn->aid, 0);
+ ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
+ conn->aid, 0);
}
}

diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 8e7e7b5..a4ad7cb 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -627,7 +627,8 @@ static inline struct sk_buff *ath6kl_wmi_get_new_buf(u32 size)
}

/* Send a "simple" wmi command -- one with no arguments */
-static int ath6kl_wmi_simple_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id)
+static int ath6kl_wmi_simple_cmd(struct wmi *wmi, u8 if_idx,
+ enum wmi_cmd_id cmd_id)
{
struct sk_buff *skb;
int ret;
@@ -636,7 +637,7 @@ static int ath6kl_wmi_simple_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id)
if (!skb)
return -ENOMEM;

- ret = ath6kl_wmi_cmd_send(wmi, skb, cmd_id, NO_SYNC_WMIFLAG);
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, cmd_id, NO_SYNC_WMIFLAG);

return ret;
}
@@ -679,7 +680,8 @@ int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi)
cmd->info.params.roam_rssi_floor = DEF_LRSSI_ROAM_FLOOR;
cmd->roam_ctrl = WMI_SET_LRSSI_SCAN_PARAMS;

- ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_ROAM_CTRL_CMDID, NO_SYNC_WMIFLAG);
+ ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID,
+ NO_SYNC_WMIFLAG);

return 0;
}
@@ -700,7 +702,7 @@ int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid)
cmd->roam_ctrl = WMI_FORCE_ROAM;

ath6kl_dbg(ATH6KL_DBG_WMI, "force roam to %pM\n", bssid);
- return ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_ROAM_CTRL_CMDID,
+ return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID,
NO_SYNC_WMIFLAG);
}

@@ -720,7 +722,7 @@ int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode)
cmd->roam_ctrl = WMI_SET_ROAM_MODE;

ath6kl_dbg(ATH6KL_DBG_WMI, "set roam mode %d\n", mode);
- return ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_ROAM_CTRL_CMDID,
+ return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID,
NO_SYNC_WMIFLAG);
}

@@ -1270,7 +1272,7 @@ static int ath6kl_wmi_send_rssi_threshold_params(struct wmi *wmi,
cmd = (struct wmi_rssi_threshold_params_cmd *) skb->data;
memcpy(cmd, rssi_cmd, sizeof(struct wmi_rssi_threshold_params_cmd));

- return ath6kl_wmi_cmd_send(wmi, skb, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
+ return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
NO_SYNC_WMIFLAG);
}

@@ -1451,7 +1453,7 @@ static int ath6kl_wmi_send_snr_threshold_params(struct wmi *wmi,
cmd = (struct wmi_snr_threshold_params_cmd *) skb->data;
memcpy(cmd, snr_cmd, sizeof(struct wmi_snr_threshold_params_cmd));

- return ath6kl_wmi_cmd_send(wmi, skb, WMI_SNR_THRESHOLD_PARAMS_CMDID,
+ return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SNR_THRESHOLD_PARAMS_CMDID,
NO_SYNC_WMIFLAG);
}

@@ -1576,14 +1578,15 @@ static int ath6kl_wmi_aplist_event_rx(struct wmi *wmi, u8 *datap, int len)
return 0;
}

-int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,
+int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb,
enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag)
{
struct wmi_cmd_hdr *cmd_hdr;
enum htc_endpoint_id ep_id = wmi->ep_id;
int ret;
+ u16 info1;

- if (WARN_ON(skb == NULL))
+ if (WARN_ON(skb == NULL || (if_idx > (MAX_NUM_VIF - 1))))
return -EINVAL;

ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n",
@@ -1609,7 +1612,8 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,

cmd_hdr = (struct wmi_cmd_hdr *) skb->data;
cmd_hdr->cmd_id = cpu_to_le16(cmd_id);
- cmd_hdr->info1 = 0; /* added for virtual interface */
+ info1 = if_idx & WMI_CMD_HDR_IF_ID_MASK;
+ cmd_hdr->info1 = cpu_to_le16(info1);

/* Only for OPT_TX_CMD, use BE endpoint. */
if (cmd_id == WMI_OPT_TX_FRAME_CMDID) {
@@ -1636,7 +1640,8 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,
return 0;
}

-int ath6kl_wmi_connect_cmd(struct wmi *wmi, enum network_type nw_type,
+int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx,
+ enum network_type nw_type,
enum dot11_auth_mode dot11_auth_mode,
enum auth_mode auth_mode,
enum crypto_type pairwise_crypto,
@@ -1687,12 +1692,14 @@ int ath6kl_wmi_connect_cmd(struct wmi *wmi, enum network_type nw_type,
if (bssid != NULL)
memcpy(cc->bssid, bssid, ETH_ALEN);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG);
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_CONNECT_CMDID,
+ NO_SYNC_WMIFLAG);

return ret;
}

-int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 *bssid, u16 channel)
+int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid,
+ u16 channel)
{
struct sk_buff *skb;
struct wmi_reconnect_cmd *cc;
@@ -1713,13 +1720,13 @@ int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 *bssid, u16 channel)
if (bssid != NULL)
memcpy(cc->bssid, bssid, ETH_ALEN);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_RECONNECT_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_RECONNECT_CMDID,
NO_SYNC_WMIFLAG);

return ret;
}

-int ath6kl_wmi_disconnect_cmd(struct wmi *wmi)
+int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx)
{
int ret;

@@ -1728,12 +1735,13 @@ int ath6kl_wmi_disconnect_cmd(struct wmi *wmi)
wmi->traffic_class = 100;

/* Disconnect command does not need to do a SYNC before. */
- ret = ath6kl_wmi_simple_cmd(wmi, WMI_DISCONNECT_CMDID);
+ ret = ath6kl_wmi_simple_cmd(wmi, if_idx, WMI_DISCONNECT_CMDID);

return ret;
}

-int ath6kl_wmi_startscan_cmd(struct wmi *wmi, enum wmi_scan_type scan_type,
+int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx,
+ enum wmi_scan_type scan_type,
u32 force_fgscan, u32 is_legacy,
u32 home_dwell_time, u32 force_scan_interval,
s8 num_chan, u16 *ch_list)
@@ -1769,13 +1777,14 @@ int ath6kl_wmi_startscan_cmd(struct wmi *wmi, enum wmi_scan_type scan_type,
for (i = 0; i < num_chan; i++)
sc->ch_list[i] = cpu_to_le16(ch_list[i]);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_START_SCAN_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_START_SCAN_CMDID,
NO_SYNC_WMIFLAG);

return ret;
}

-int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u16 fg_start_sec,
+int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx,
+ u16 fg_start_sec,
u16 fg_end_sec, u16 bg_sec,
u16 minact_chdw_msec, u16 maxact_chdw_msec,
u16 pas_chdw_msec, u8 short_scan_ratio,
@@ -1802,7 +1811,7 @@ int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u16 fg_start_sec,
sc->max_dfsch_act_time = cpu_to_le32(max_dfsch_act_time);
sc->maxact_scan_per_ssid = cpu_to_le16(maxact_scan_per_ssid);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_SCAN_PARAMS_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_SCAN_PARAMS_CMDID,
NO_SYNC_WMIFLAG);
return ret;
}
@@ -1824,12 +1833,12 @@ int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 filter, u32 ie_mask)
cmd->bss_filter = filter;
cmd->ie_mask = cpu_to_le32(ie_mask);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_BSS_FILTER_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_BSS_FILTER_CMDID,
NO_SYNC_WMIFLAG);
return ret;
}

-int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 index, u8 flag,
+int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag,
u8 ssid_len, u8 *ssid)
{
struct sk_buff *skb;
@@ -1861,12 +1870,13 @@ int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 index, u8 flag,
cmd->ssid_len = ssid_len;
memcpy(cmd->ssid, ssid, ssid_len);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_PROBED_SSID_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_PROBED_SSID_CMDID,
NO_SYNC_WMIFLAG);
return ret;
}

-int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u16 listen_interval,
+int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx,
+ u16 listen_interval,
u16 listen_beacons)
{
struct sk_buff *skb;
@@ -1881,12 +1891,12 @@ int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u16 listen_interval,
cmd->listen_intvl = cpu_to_le16(listen_interval);
cmd->num_beacons = cpu_to_le16(listen_beacons);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_LISTEN_INT_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_LISTEN_INT_CMDID,
NO_SYNC_WMIFLAG);
return ret;
}

-int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 pwr_mode)
+int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode)
{
struct sk_buff *skb;
struct wmi_power_mode_cmd *cmd;
@@ -1900,7 +1910,7 @@ int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 pwr_mode)
cmd->pwr_mode = pwr_mode;
wmi->pwr_mode = pwr_mode;

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_POWER_MODE_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_POWER_MODE_CMDID,
NO_SYNC_WMIFLAG);
return ret;
}
@@ -1926,7 +1936,7 @@ int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u16 idle_period,
pm->num_tx_to_wakeup = cpu_to_le16(num_tx_to_wakeup);
pm->ps_fail_event_policy = cpu_to_le16(ps_fail_event_policy);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_POWER_PARAMS_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_POWER_PARAMS_CMDID,
NO_SYNC_WMIFLAG);
return ret;
}
@@ -1944,14 +1954,16 @@ int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 timeout)
cmd = (struct wmi_disc_timeout_cmd *) skb->data;
cmd->discon_timeout = timeout;

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_DISC_TIMEOUT_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_DISC_TIMEOUT_CMDID,
NO_SYNC_WMIFLAG);
+
if (ret == 0)
ath6kl_debug_set_disconnect_timeout(wmi->parent_dev, timeout);
+
return ret;
}

-int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,
+int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index,
enum crypto_type key_type,
u8 key_usage, u8 key_len,
u8 *key_rsc, u8 *key_material,
@@ -1992,7 +2004,7 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,
if (mac_addr)
memcpy(cmd->key_mac_addr, mac_addr, ETH_ALEN);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_ADD_CIPHER_KEY_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_ADD_CIPHER_KEY_CMDID,
sync_flag);

return ret;
@@ -2011,12 +2023,13 @@ int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 *krk)
cmd = (struct wmi_add_krk_cmd *) skb->data;
memcpy(cmd->krk, krk, WMI_KRK_LEN);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG);
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_ADD_KRK_CMDID,
+ NO_SYNC_WMIFLAG);

return ret;
}

-int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 key_index)
+int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index)
{
struct sk_buff *skb;
struct wmi_delete_cipher_key_cmd *cmd;
@@ -2032,13 +2045,13 @@ int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 key_index)
cmd = (struct wmi_delete_cipher_key_cmd *) skb->data;
cmd->key_index = key_index;

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_DELETE_CIPHER_KEY_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_DELETE_CIPHER_KEY_CMDID,
NO_SYNC_WMIFLAG);

return ret;
}

-int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, const u8 *bssid,
+int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, u8 if_idx, const u8 *bssid,
const u8 *pmkid, bool set)
{
struct sk_buff *skb;
@@ -2065,7 +2078,7 @@ int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, const u8 *bssid,
cmd->enable = PMKID_DISABLE;
}

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_PMKID_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_PMKID_CMDID,
NO_SYNC_WMIFLAG);

return ret;
@@ -2147,7 +2160,7 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi)
* Send sync cmd followed by sync data messages on all
* endpoints being used
*/
- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SYNCHRONIZE_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SYNCHRONIZE_CMDID,
NO_SYNC_WMIFLAG);

if (ret)
@@ -2278,7 +2291,7 @@ int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi,
ath6kl_indicate_tx_activity(wmi->parent_dev,
params->traffic_class, true);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_CREATE_PSTREAM_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_CREATE_PSTREAM_CMDID,
NO_SYNC_WMIFLAG);
return ret;
}
@@ -2319,7 +2332,7 @@ int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 traffic_class, u8 tsid)
"sending delete_pstream_cmd: traffic class: %d tsid=%d\n",
traffic_class, tsid);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_DELETE_PSTREAM_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_DELETE_PSTREAM_CMDID,
SYNC_BEFORE_WMIFLAG);

spin_lock_bh(&wmi->lock);
@@ -2358,7 +2371,8 @@ int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd)
cmd = (struct wmi_set_ip_cmd *) skb->data;
memcpy(cmd, ip_cmd, sizeof(struct wmi_set_ip_cmd));

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_IP_CMDID, NO_SYNC_WMIFLAG);
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_IP_CMDID,
+ NO_SYNC_WMIFLAG);
return ret;
}

@@ -2383,7 +2397,7 @@ static int ath6kl_wmi_cmd_send_xtnd(struct wmi *wmi, struct sk_buff *skb,
cmd_hdr = (struct wmix_cmd_hdr *) skb->data;
cmd_hdr->cmd_id = cpu_to_le32(cmd_id);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_EXTENSION_CMDID, sync_flag);
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_EXTENSION_CMDID, sync_flag);

return ret;
}
@@ -2426,9 +2440,9 @@ int ath6kl_wmi_config_debug_module_cmd(struct wmi *wmi, u32 valid, u32 config)
return ret;
}

-int ath6kl_wmi_get_stats_cmd(struct wmi *wmi)
+int ath6kl_wmi_get_stats_cmd(struct wmi *wmi, u8 if_idx)
{
- return ath6kl_wmi_simple_cmd(wmi, WMI_GET_STATISTICS_CMDID);
+ return ath6kl_wmi_simple_cmd(wmi, if_idx, WMI_GET_STATISTICS_CMDID);
}

int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM)
@@ -2444,7 +2458,7 @@ int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM)
cmd = (struct wmi_set_tx_pwr_cmd *) skb->data;
cmd->dbM = dbM;

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_TX_PWR_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_TX_PWR_CMDID,
NO_SYNC_WMIFLAG);

return ret;
@@ -2452,12 +2466,12 @@ int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM)

int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi)
{
- return ath6kl_wmi_simple_cmd(wmi, WMI_GET_TX_PWR_CMDID);
+ return ath6kl_wmi_simple_cmd(wmi, 0, WMI_GET_TX_PWR_CMDID);
}

int ath6kl_wmi_get_roam_tbl_cmd(struct wmi *wmi)
{
- return ath6kl_wmi_simple_cmd(wmi, WMI_GET_ROAM_TBL_CMDID);
+ return ath6kl_wmi_simple_cmd(wmi, 0, WMI_GET_ROAM_TBL_CMDID);
}

int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status, u8 preamble_policy)
@@ -2474,7 +2488,7 @@ int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status, u8 preamble_policy)
cmd->status = status;
cmd->preamble_policy = preamble_policy;

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_LPREAMBLE_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_LPREAMBLE_CMDID,
NO_SYNC_WMIFLAG);
return ret;
}
@@ -2492,7 +2506,8 @@ int ath6kl_wmi_set_rts_cmd(struct wmi *wmi, u16 threshold)
cmd = (struct wmi_set_rts_cmd *) skb->data;
cmd->threshold = cpu_to_le16(threshold);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_RTS_CMDID, NO_SYNC_WMIFLAG);
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_RTS_CMDID,
+ NO_SYNC_WMIFLAG);
return ret;
}

@@ -2512,7 +2527,7 @@ int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg)
cmd = (struct wmi_set_wmm_txop_cmd *) skb->data;
cmd->txop_enable = cfg;

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_WMM_TXOP_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_WMM_TXOP_CMDID,
NO_SYNC_WMIFLAG);
return ret;
}
@@ -2530,10 +2545,12 @@ int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl)
cmd = (struct wmi_set_keepalive_cmd *) skb->data;
cmd->keep_alive_intvl = keep_alive_intvl;

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_KEEPALIVE_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_KEEPALIVE_CMDID,
NO_SYNC_WMIFLAG);
+
if (ret == 0)
ath6kl_debug_set_keepalive(wmi->parent_dev, keep_alive_intvl);
+
return ret;
}

@@ -2548,7 +2565,7 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len)

memcpy(skb->data, buf, len);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_TEST_CMDID, NO_SYNC_WMIFLAG);
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_TEST_CMDID, NO_SYNC_WMIFLAG);

return ret;
}
@@ -2602,7 +2619,8 @@ static int ath6kl_wmi_delba_req_event_rx(struct wmi *wmi, u8 *datap, int len)

/* AP mode functions */

-int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, struct wmi_connect_cmd *p)
+int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx,
+ struct wmi_connect_cmd *p)
{
struct sk_buff *skb;
struct wmi_connect_cmd *cm;
@@ -2615,7 +2633,7 @@ int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, struct wmi_connect_cmd *p)
cm = (struct wmi_connect_cmd *) skb->data;
memcpy(cm, p, sizeof(*cm));

- res = ath6kl_wmi_cmd_send(wmip, skb, WMI_AP_CONFIG_COMMIT_CMDID,
+ res = ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_CONFIG_COMMIT_CMDID,
NO_SYNC_WMIFLAG);
ath6kl_dbg(ATH6KL_DBG_WMI, "%s: nw_type=%u auth_mode=%u ch=%u "
"ctrl_flags=0x%x-> res=%d\n",
@@ -2624,7 +2642,8 @@ int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, struct wmi_connect_cmd *p)
return res;
}

-int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 cmd, const u8 *mac, u16 reason)
+int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac,
+ u16 reason)
{
struct sk_buff *skb;
struct wmi_ap_set_mlme_cmd *cm;
@@ -2638,7 +2657,7 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 cmd, const u8 *mac, u16 reason)
cm->reason = cpu_to_le16(reason);
cm->cmd = cmd;

- return ath6kl_wmi_cmd_send(wmip, skb, WMI_AP_SET_MLME_CMDID,
+ return ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_SET_MLME_CMDID,
NO_SYNC_WMIFLAG);
}

@@ -2663,7 +2682,8 @@ static int ath6kl_wmi_dtimexpiry_event_rx(struct wmi *wmi, u8 *datap, int len)
return 0;
}

-int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag)
+int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u8 if_idx, u16 aid,
+ bool flag)
{
struct sk_buff *skb;
struct wmi_ap_set_pvb_cmd *cmd;
@@ -2678,7 +2698,7 @@ int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag)
cmd->rsvd = cpu_to_le16(0);
cmd->flag = cpu_to_le32(flag);

- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_AP_SET_PVB_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_SET_PVB_CMDID,
NO_SYNC_WMIFLAG);

return 0;
@@ -2701,14 +2721,14 @@ int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_ver,
cmd->meta_ver = rx_meta_ver;

/* Delete the local aggr state, on host */
- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_RX_FRAME_FORMAT_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_RX_FRAME_FORMAT_CMDID,
NO_SYNC_WMIFLAG);

return ret;
}

-int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 mgmt_frm_type, const u8 *ie,
- u8 ie_len)
+int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
+ const u8 *ie, u8 ie_len)
{
struct sk_buff *skb;
struct wmi_set_appie_cmd *p;
@@ -2723,7 +2743,7 @@ int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 mgmt_frm_type, const u8 *ie,
p->mgmt_frm_type = mgmt_frm_type;
p->ie_len = ie_len;
memcpy(p->ie_info, ie, ie_len);
- return ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_APPIE_CMDID,
+ return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_APPIE_CMDID,
NO_SYNC_WMIFLAG);
}

@@ -2741,11 +2761,11 @@ int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable)
cmd = (struct wmi_disable_11b_rates_cmd *) skb->data;
cmd->disable = disable ? 1 : 0;

- return ath6kl_wmi_cmd_send(wmi, skb, WMI_DISABLE_11B_RATES_CMDID,
+ return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_DISABLE_11B_RATES_CMDID,
NO_SYNC_WMIFLAG);
}

-int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u32 freq, u32 dur)
+int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq, u32 dur)
{
struct sk_buff *skb;
struct wmi_remain_on_chnl_cmd *p;
@@ -2759,12 +2779,12 @@ int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u32 freq, u32 dur)
p = (struct wmi_remain_on_chnl_cmd *) skb->data;
p->freq = cpu_to_le32(freq);
p->duration = cpu_to_le32(dur);
- return ath6kl_wmi_cmd_send(wmi, skb, WMI_REMAIN_ON_CHNL_CMDID,
+ return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_REMAIN_ON_CHNL_CMDID,
NO_SYNC_WMIFLAG);
}

-int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u32 id, u32 freq, u32 wait,
- const u8 *data, u16 data_len)
+int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
+ u32 wait, const u8 *data, u16 data_len)
{
struct sk_buff *skb;
struct wmi_send_action_cmd *p;
@@ -2795,13 +2815,13 @@ int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u32 id, u32 freq, u32 wait,
p->wait = cpu_to_le32(wait);
p->len = cpu_to_le16(data_len);
memcpy(p->data, data, data_len);
- return ath6kl_wmi_cmd_send(wmi, skb, WMI_SEND_ACTION_CMDID,
+ return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SEND_ACTION_CMDID,
NO_SYNC_WMIFLAG);
}

-int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u32 freq,
- const u8 *dst,
- const u8 *data, u16 data_len)
+int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq,
+ const u8 *dst, const u8 *data,
+ u16 data_len)
{
struct sk_buff *skb;
struct wmi_p2p_probe_response_cmd *p;
@@ -2817,7 +2837,8 @@ int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u32 freq,
memcpy(p->destination_addr, dst, ETH_ALEN);
p->len = cpu_to_le16(data_len);
memcpy(p->data, data, data_len);
- return ath6kl_wmi_cmd_send(wmi, skb, WMI_SEND_PROBE_RESPONSE_CMDID,
+ return ath6kl_wmi_cmd_send(wmi, if_idx, skb,
+ WMI_SEND_PROBE_RESPONSE_CMDID,
NO_SYNC_WMIFLAG);
}

@@ -2834,7 +2855,7 @@ int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, bool enable)
enable);
p = (struct wmi_probe_req_report_cmd *) skb->data;
p->enable = enable ? 1 : 0;
- return ath6kl_wmi_cmd_send(wmi, skb, WMI_PROBE_REQ_REPORT_CMDID,
+ return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_PROBE_REQ_REPORT_CMDID,
NO_SYNC_WMIFLAG);
}

@@ -2851,14 +2872,15 @@ int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u32 info_req_flags)
info_req_flags);
p = (struct wmi_get_p2p_info *) skb->data;
p->info_req_flags = cpu_to_le32(info_req_flags);
- return ath6kl_wmi_cmd_send(wmi, skb, WMI_GET_P2P_INFO_CMDID,
+ return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_GET_P2P_INFO_CMDID,
NO_SYNC_WMIFLAG);
}

-int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi)
+int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx)
{
ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl_cmd\n");
- return ath6kl_wmi_simple_cmd(wmi, WMI_CANCEL_REMAIN_ON_CHNL_CMDID);
+ return ath6kl_wmi_simple_cmd(wmi, if_idx,
+ WMI_CANCEL_REMAIN_ON_CHNL_CMDID);
}

static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index f0ca899..83bf46c 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -288,6 +288,8 @@ struct wmi_rx_meta_v2 {
u8 csum_flags;
} __packed;

+#define WMI_CMD_HDR_IF_ID_MASK 0xF
+
/* Control Path */
struct wmi_cmd_hdr {
__le16 cmd_id;
@@ -2175,10 +2177,11 @@ int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb,

int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb);

-int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,
+int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb,
enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag);

-int ath6kl_wmi_connect_cmd(struct wmi *wmi, enum network_type nw_type,
+int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx,
+ enum network_type nw_type,
enum dot11_auth_mode dot11_auth_mode,
enum auth_mode auth_mode,
enum crypto_type pairwise_crypto,
@@ -2187,24 +2190,27 @@ int ath6kl_wmi_connect_cmd(struct wmi *wmi, enum network_type nw_type,
u8 group_crypto_len, int ssid_len, u8 *ssid,
u8 *bssid, u16 channel, u32 ctrl_flags);

-int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 *bssid, u16 channel);
-int ath6kl_wmi_disconnect_cmd(struct wmi *wmi);
-int ath6kl_wmi_startscan_cmd(struct wmi *wmi, enum wmi_scan_type scan_type,
+int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid,
+ u16 channel);
+int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx);
+int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx,
+ enum wmi_scan_type scan_type,
u32 force_fgscan, u32 is_legacy,
u32 home_dwell_time, u32 force_scan_interval,
s8 num_chan, u16 *ch_list);
-int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u16 fg_start_sec,
+int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx, u16 fg_start_sec,
u16 fg_end_sec, u16 bg_sec,
u16 minact_chdw_msec, u16 maxact_chdw_msec,
u16 pas_chdw_msec, u8 short_scan_ratio,
u8 scan_ctrl_flag, u32 max_dfsch_act_time,
u16 maxact_scan_per_ssid);
int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 filter, u32 ie_mask);
-int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 index, u8 flag,
+int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag,
u8 ssid_len, u8 *ssid);
-int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u16 listen_interval,
+int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx,
+ u16 listen_interval,
u16 listen_beacons);
-int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 pwr_mode);
+int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode);
int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u16 idle_period,
u16 ps_poll_num, u16 dtim_policy,
u16 tx_wakup_policy, u16 num_tx_to_wakeup,
@@ -2221,16 +2227,16 @@ int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status,
int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source);
int ath6kl_wmi_config_debug_module_cmd(struct wmi *wmi, u32 valid, u32 config);

-int ath6kl_wmi_get_stats_cmd(struct wmi *wmi);
-int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,
+int ath6kl_wmi_get_stats_cmd(struct wmi *wmi, u8 if_idx);
+int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index,
enum crypto_type key_type,
u8 key_usage, u8 key_len,
u8 *key_rsc, u8 *key_material,
u8 key_op_ctrl, u8 *mac_addr,
enum wmi_sync_flag sync_flag);
int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 *krk);
-int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 key_index);
-int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, const u8 *bssid,
+int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index);
+int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, u8 if_idx, const u8 *bssid,
const u8 *pmkid, bool set);
int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM);
int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi);
@@ -2248,38 +2254,41 @@ int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid);
int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode);

/* AP mode */
-int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, struct wmi_connect_cmd *p);
+int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx,
+ struct wmi_connect_cmd *p);

-int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 cmd, const u8 *mac, u16 reason);
+int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd,
+ const u8 *mac, u16 reason);

-int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag);
+int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u8 if_idx, u16 aid, bool flag);

int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_version,
bool rx_dot11_hdr, bool defrag_on_host);

-int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 mgmt_frm_type, const u8 *ie,
- u8 ie_len);
+int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
+ const u8 *ie, u8 ie_len);

/* P2P */
int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable);

-int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u32 freq, u32 dur);
+int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq,
+ u32 dur);

-int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u32 id, u32 freq, u32 wait,
- const u8 *data, u16 data_len);
+int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
+ u32 wait, const u8 *data, u16 data_len);

-int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u32 freq,
- const u8 *dst,
- const u8 *data, u16 data_len);
+int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq,
+ const u8 *dst, const u8 *data,
+ u16 data_len);

int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, bool enable);

int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u32 info_req_flags);

-int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi);
+int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx);

-int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 mgmt_frm_type, const u8 *ie,
- u8 ie_len);
+int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
+ const u8 *ie, u8 ie_len);

void *ath6kl_wmi_init(struct ath6kl *devt);
void ath6kl_wmi_shutdown(struct wmi *wmi);
--
1.7.0.4


Subject: Re: [PATCH V2 00/31] ath6kl Add multiple vif support

On Wed, Oct 26, 2011 at 10:22:30AM +0300, Kalle Valo wrote:
> On 10/25/2011 05:03 PM, Vasanthakumar Thiagarajan wrote:
> > This patch set adds basic infrastructure for multiple
> > virtual interface. As configuring the firmware with more than one
> > vif causes random target assert, the number of supported vifs is
> > restricted to 1 for now. I would like to thank Vivek Natarajan
> > ([email protected]) for his inital work in this area and
> > Arthi Thiruvengadam ([email protected]) for finding some
> > critical bugs.
>
> I saw the lockdep warning below after I loaded the module and connected
> to an AP. But the driver still functioned normally.

Sorry, i did not test with lockdep warning enabled, i'll look into
this. Thanks!

Vasanth