diff --git a/[refs] b/[refs] index 7b5aa26858e1..410073302727 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e3bea1c8751d297c197949db01aa1e7adbc1104d +refs/heads/master: fee005e5dd82a43546c1b1beb187e82415360940 diff --git a/trunk/drivers/net/wireless/ath/ath6kl/Makefile b/trunk/drivers/net/wireless/ath/ath6kl/Makefile index 707069303550..8f7a0d1c290c 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/Makefile +++ b/trunk/drivers/net/wireless/ath/ath6kl/Makefile @@ -23,7 +23,7 @@ obj-$(CONFIG_ATH6KL) := ath6kl.o ath6kl-y += debug.o -ath6kl-y += hif.o +ath6kl-y += htc_hif.o ath6kl-y += htc.o ath6kl-y += bmi.o ath6kl-y += cfg80211.o diff --git a/trunk/drivers/net/wireless/ath/ath6kl/bmi.c b/trunk/drivers/net/wireless/ath/ath6kl/bmi.c index a962fe4c6b7e..c5d11cc536e0 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/bmi.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/bmi.c @@ -196,6 +196,8 @@ int ath6kl_bmi_done(struct ath6kl *ar) return ret; } + ath6kl_bmi_cleanup(ar); + return 0; } @@ -670,11 +672,6 @@ int ath6kl_bmi_fast_download(struct ath6kl *ar, u32 addr, u8 *buf, u32 len) return ret; } -void ath6kl_bmi_reset(struct ath6kl *ar) -{ - ar->bmi.done_sent = false; -} - int ath6kl_bmi_init(struct ath6kl *ar) { ar->bmi.cmd_buf = kzalloc(MAX_BMI_CMDBUF_SZ, GFP_ATOMIC); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/bmi.h b/trunk/drivers/net/wireless/ath/ath6kl/bmi.h index 009e8f650ab1..96851d5df24b 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/bmi.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/bmi.h @@ -230,8 +230,6 @@ struct ath6kl_bmi_target_info { int ath6kl_bmi_init(struct ath6kl *ar); void ath6kl_bmi_cleanup(struct ath6kl *ar); -void ath6kl_bmi_reset(struct ath6kl *ar); - int ath6kl_bmi_done(struct ath6kl *ar); int ath6kl_bmi_get_target_info(struct ath6kl *ar, struct ath6kl_bmi_target_info *targ_info); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c index 4d1394a3dc19..daf444bf8d48 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -21,10 +21,8 @@ #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), \ @@ -123,19 +121,17 @@ static struct ieee80211_supported_band ath6kl_band_5ghz = { .bitrates = ath6kl_a_rates, }; -#define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */ - -static int ath6kl_set_wpa_version(struct ath6kl_vif *vif, +static int ath6kl_set_wpa_version(struct ath6kl *ar, enum nl80211_wpa_versions wpa_version) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version); if (!wpa_version) { - vif->auth_mode = NONE_AUTH; + ar->auth_mode = NONE_AUTH; } else if (wpa_version & NL80211_WPA_VERSION_2) { - vif->auth_mode = WPA2_AUTH; + ar->auth_mode = WPA2_AUTH; } else if (wpa_version & NL80211_WPA_VERSION_1) { - vif->auth_mode = WPA_AUTH; + ar->auth_mode = WPA_AUTH; } else { ath6kl_err("%s: %u not supported\n", __func__, wpa_version); return -ENOTSUPP; @@ -144,24 +140,25 @@ static int ath6kl_set_wpa_version(struct ath6kl_vif *vif, return 0; } -static int ath6kl_set_auth_type(struct ath6kl_vif *vif, +static int ath6kl_set_auth_type(struct ath6kl *ar, enum nl80211_auth_type auth_type) { + ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type); switch (auth_type) { case NL80211_AUTHTYPE_OPEN_SYSTEM: - vif->dot11_auth_mode = OPEN_AUTH; + ar->dot11_auth_mode = OPEN_AUTH; break; case NL80211_AUTHTYPE_SHARED_KEY: - vif->dot11_auth_mode = SHARED_AUTH; + ar->dot11_auth_mode = SHARED_AUTH; break; case NL80211_AUTHTYPE_NETWORK_EAP: - vif->dot11_auth_mode = LEAP_AUTH; + ar->dot11_auth_mode = LEAP_AUTH; break; case NL80211_AUTHTYPE_AUTOMATIC: - vif->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH; + ar->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH; break; default: @@ -172,11 +169,11 @@ static int ath6kl_set_auth_type(struct ath6kl_vif *vif, return 0; } -static int ath6kl_set_cipher(struct ath6kl_vif *vif, u32 cipher, bool ucast) +static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast) { - u8 *ar_cipher = ucast ? &vif->prwise_crypto : &vif->grp_crypto; - u8 *ar_cipher_len = ucast ? &vif->prwise_crypto_len : - &vif->grp_crypto_len; + u8 *ar_cipher = ucast ? &ar->prwise_crypto : &ar->grp_crypto; + u8 *ar_cipher_len = ucast ? &ar->prwise_crypto_len : + &ar->grp_crypto_len; ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n", __func__, cipher, ucast); @@ -211,35 +208,28 @@ static int ath6kl_set_cipher(struct ath6kl_vif *vif, u32 cipher, bool ucast) return 0; } -static void ath6kl_set_key_mgmt(struct ath6kl_vif *vif, u32 key_mgmt) +static void ath6kl_set_key_mgmt(struct ath6kl *ar, u32 key_mgmt) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt); if (key_mgmt == WLAN_AKM_SUITE_PSK) { - 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 (vif->auth_mode == WPA_AUTH) - vif->auth_mode = WPA_AUTH_CCKM; - else if (vif->auth_mode == WPA2_AUTH) - vif->auth_mode = WPA2_AUTH_CCKM; + 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; } else if (key_mgmt != WLAN_AKM_SUITE_8021X) { - vif->auth_mode = NONE_AUTH; + ar->auth_mode = NONE_AUTH; } } -static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif) +static bool ath6kl_cfg80211_ready(struct ath6kl *ar) { - struct ath6kl *ar = vif->ar; - if (!test_bit(WMI_READY, &ar->flag)) { ath6kl_err("wmi is not ready\n"); return false; } - if (!test_bit(WLAN_ENABLED, &vif->flags)) { + if (!test_bit(WLAN_ENABLED, &ar->flag)) { ath6kl_err("wlan disabled\n"); return false; } @@ -247,143 +237,15 @@ static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif) return true; } -static bool ath6kl_is_wpa_ie(const u8 *pos) -{ - return pos[0] == WLAN_EID_WPA && pos[1] >= 4 && - pos[2] == 0x00 && pos[3] == 0x50 && - pos[4] == 0xf2 && pos[5] == 0x01; -} - -static bool ath6kl_is_rsn_ie(const u8 *pos) -{ - return pos[0] == WLAN_EID_RSN; -} - -static bool ath6kl_is_wps_ie(const u8 *pos) -{ - return (pos[0] == WLAN_EID_VENDOR_SPECIFIC && - pos[1] >= 4 && - pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 && - pos[5] == 0x04); -} - -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; - int ret; - - /* - * Clear previously set flag - */ - - ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG; - - /* - * Filter out RSN/WPA IE(s) - */ - - if (ies && ies_len) { - buf = kmalloc(ies_len, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - pos = ies; - - while (pos + 1 < ies + ies_len) { - if (pos + 2 + pos[1] > ies + ies_len) - break; - if (!(ath6kl_is_wpa_ie(pos) || ath6kl_is_rsn_ie(pos))) { - memcpy(buf + len, pos, 2 + pos[1]); - len += 2 + pos[1]; - } - - if (ath6kl_is_wps_ie(pos)) - ar->connect_ctrl_flags |= CONNECT_WPS_FLAG; - - pos += 2 + pos[1]; - } - } - - ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, - WMI_FRAME_ASSOC_REQ, buf, len); - kfree(buf); - 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; - } - } - } - - 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; -} - 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; - vif->sme_state = SME_CONNECTING; + ar->sme_state = SME_CONNECTING; - if (!ath6kl_cfg80211_ready(vif)) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) { @@ -423,19 +285,12 @@ 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(vif, sme->ie, sme->ie_len); - if (status) - return status; - } - - if (test_bit(CONNECTED, &vif->flags) && - 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->fw_vif_idx, - vif->req_bssid, - vif->ch_hint); + if (test_bit(CONNECTED, &ar->flag) && + ar->ssid_len == sme->ssid_len && + !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) { + ar->reconnect_flag = true; + status = ath6kl_wmi_reconnect_cmd(ar->wmi, ar->req_bssid, + ar->ch_hint); up(&ar->sem); if (status) { @@ -443,43 +298,42 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, return -EIO; } return 0; - } else if (vif->ssid_len == sme->ssid_len && - !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) { - ath6kl_disconnect(vif); + } else if (ar->ssid_len == sme->ssid_len && + !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) { + ath6kl_disconnect(ar); } - memset(vif->ssid, 0, sizeof(vif->ssid)); - vif->ssid_len = sme->ssid_len; - memcpy(vif->ssid, sme->ssid, sme->ssid_len); + memset(ar->ssid, 0, sizeof(ar->ssid)); + ar->ssid_len = sme->ssid_len; + memcpy(ar->ssid, sme->ssid, sme->ssid_len); if (sme->channel) - vif->ch_hint = sme->channel->center_freq; + ar->ch_hint = sme->channel->center_freq; - memset(vif->req_bssid, 0, sizeof(vif->req_bssid)); + memset(ar->req_bssid, 0, sizeof(ar->req_bssid)); if (sme->bssid && !is_broadcast_ether_addr(sme->bssid)) - memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid)); + memcpy(ar->req_bssid, sme->bssid, sizeof(ar->req_bssid)); - ath6kl_set_wpa_version(vif, sme->crypto.wpa_versions); + ath6kl_set_wpa_version(ar, sme->crypto.wpa_versions); - status = ath6kl_set_auth_type(vif, sme->auth_type); + status = ath6kl_set_auth_type(ar, sme->auth_type); if (status) { up(&ar->sem); return status; } if (sme->crypto.n_ciphers_pairwise) - ath6kl_set_cipher(vif, sme->crypto.ciphers_pairwise[0], true); + ath6kl_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true); else - ath6kl_set_cipher(vif, 0, true); + ath6kl_set_cipher(ar, 0, true); - ath6kl_set_cipher(vif, sme->crypto.cipher_group, false); + ath6kl_set_cipher(ar, sme->crypto.cipher_group, false); if (sme->crypto.n_akm_suites) - ath6kl_set_key_mgmt(vif, sme->crypto.akm_suites[0]); + ath6kl_set_key_mgmt(ar, sme->crypto.akm_suites[0]); if ((sme->key_len) && - (vif->auth_mode == NONE_AUTH) && - (vif->prwise_crypto == WEP_CRYPT)) { + (ar->auth_mode == NONE_AUTH) && (ar->prwise_crypto == WEP_CRYPT)) { struct ath6kl_key *key = NULL; if (sme->key_idx < WMI_MIN_KEY_INDEX || @@ -490,57 +344,56 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, return -ENOENT; } - key = &vif->keys[sme->key_idx]; + key = &ar->keys[sme->key_idx]; key->key_len = sme->key_len; memcpy(key->key, sme->key, key->key_len); - key->cipher = vif->prwise_crypto; - vif->def_txkey_index = sme->key_idx; + key->cipher = ar->prwise_crypto; + ar->def_txkey_index = sme->key_idx; - ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, sme->key_idx, - vif->prwise_crypto, + ath6kl_wmi_addkey_cmd(ar->wmi, sme->key_idx, + ar->prwise_crypto, GROUP_USAGE | TX_USAGE, key->key_len, - NULL, 0, + NULL, key->key, KEY_OP_INIT_VAL, NULL, NO_SYNC_WMIFLAG); } if (!ar->usr_bss_filter) { - clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); - if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, - ALL_BSS_FILTER, 0) != 0) { + clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag); + if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) { ath6kl_err("couldn't set bss filtering\n"); up(&ar->sem); return -EIO; } } - vif->nw_type = vif->next_mode; + ar->nw_type = ar->next_mode; ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: connect called with authmode %d dot11 auth %d" " PW crypto %d PW crypto len %d GRP crypto %d" " GRP crypto len %d channel hint %u\n", __func__, - vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto, - vif->prwise_crypto_len, vif->grp_crypto, - vif->grp_crypto_len, vif->ch_hint); - - vif->reconnect_flag = 0; - 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, - vif->grp_crypto, vif->grp_crypto_len, - vif->ssid_len, vif->ssid, - vif->req_bssid, vif->ch_hint, + ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto, + ar->prwise_crypto_len, ar->grp_crypto, + ar->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, + ar->req_bssid, ar->ch_hint, ar->connect_ctrl_flags); up(&ar->sem); if (status == -EINVAL) { - memset(vif->ssid, 0, sizeof(vif->ssid)); - vif->ssid_len = 0; + memset(ar->ssid, 0, sizeof(ar->ssid)); + ar->ssid_len = 0; ath6kl_err("invalid request\n"); return -ENOENT; } else if (status) { @@ -549,28 +402,27 @@ 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(&vif->disconnect_timer, + ((ar->auth_mode == WPA_PSK_AUTH) + || (ar->auth_mode == WPA2_PSK_AUTH))) { + mod_timer(&ar->disconnect_timer, jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL)); } ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD; - set_bit(CONNECT_PEND, &vif->flags); + set_bit(CONNECT_PEND, &ar->flag); return 0; } -static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, const u8 *bssid, +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) { - struct ath6kl *ar = vif->ar; struct cfg80211_bss *bss; u8 *ie; - bss = cfg80211_get_bss(ar->wiphy, chan, bssid, - vif->ssid, vif->ssid_len, WLAN_CAPABILITY_ESS, + bss = cfg80211_get_bss(ar->wdev->wiphy, chan, bssid, + ar->ssid, ar->ssid_len, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); if (bss == NULL) { /* @@ -581,16 +433,16 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, const u8 *bssid, * Prepend SSID element since it is not included in the Beacon * IEs from the target. */ - ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL); + ie = kmalloc(2 + ar->ssid_len + beacon_ie_len, GFP_KERNEL); if (ie == NULL) return -ENOMEM; ie[0] = WLAN_EID_SSID; - 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, + 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, bssid, 0, WLAN_CAPABILITY_ESS, 100, - ie, 2 + vif->ssid_len + beacon_ie_len, + ie, 2 + ar->ssid_len + beacon_ie_len, 0, GFP_KERNEL); if (bss) ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added dummy bss for " @@ -609,7 +461,7 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, const u8 *bssid, return 0; } -void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, +void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid, u16 listen_intvl, u16 beacon_intvl, enum network_type nw_type, @@ -617,7 +469,6 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, u8 assoc_resp_len, u8 *assoc_info) { struct ieee80211_channel *chan; - struct ath6kl *ar = vif->ar; /* capinfo + listen interval */ u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16); @@ -636,11 +487,11 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, * Store Beacon interval here; DTIM period will be available only once * a Beacon frame from the AP is seen. */ - vif->assoc_bss_beacon_int = beacon_intvl; - clear_bit(DTIM_PERIOD_AVAIL, &vif->flags); + ar->assoc_bss_beacon_int = beacon_intvl; + clear_bit(DTIM_PERIOD_AVAIL, &ar->flag); if (nw_type & ADHOC_NETWORK) { - if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) { + if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: ath6k not in ibss mode\n", __func__); return; @@ -648,39 +499,39 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, } if (nw_type & INFRA_NETWORK) { - if (vif->wdev.iftype != NL80211_IFTYPE_STATION && - vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) { + if (ar->wdev->iftype != NL80211_IFTYPE_STATION && + ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: ath6k not in station mode\n", __func__); return; } } - chan = ieee80211_get_channel(ar->wiphy, (int) channel); + chan = ieee80211_get_channel(ar->wdev->wiphy, (int) channel); if (nw_type & ADHOC_NETWORK) { - cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); + cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL); return; } - if (ath6kl_add_bss_if_needed(vif, bssid, chan, assoc_info, + if (ath6kl_add_bss_if_needed(ar, bssid, chan, assoc_info, beacon_ie_len) < 0) { ath6kl_err("could not add cfg80211 bss entry for " "connect/roamed notification\n"); return; } - if (vif->sme_state == SME_CONNECTING) { + if (ar->sme_state == SME_CONNECTING) { /* inform connect result to cfg80211 */ - vif->sme_state = SME_CONNECTED; - cfg80211_connect_result(vif->ndev, bssid, + ar->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 (vif->sme_state == SME_CONNECTED) { + } else if (ar->sme_state == SME_CONNECTED) { /* inform roam event to cfg80211 */ - cfg80211_roamed(vif->ndev, chan, bssid, + cfg80211_roamed(ar->net_dev, chan, bssid, assoc_req_ie, assoc_req_len, assoc_resp_ie, assoc_resp_len, GFP_KERNEL); } @@ -690,12 +541,11 @@ 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); - if (!ath6kl_cfg80211_ready(vif)) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) { @@ -708,46 +558,44 @@ static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy, return -ERESTARTSYS; } - vif->reconnect_flag = 0; - ath6kl_disconnect(vif); - memset(vif->ssid, 0, sizeof(vif->ssid)); - vif->ssid_len = 0; + ar->reconnect_flag = 0; + ath6kl_disconnect(ar); + memset(ar->ssid, 0, sizeof(ar->ssid)); + ar->ssid_len = 0; if (!test_bit(SKIP_SCAN, &ar->flag)) - memset(vif->req_bssid, 0, sizeof(vif->req_bssid)); + memset(ar->req_bssid, 0, sizeof(ar->req_bssid)); up(&ar->sem); - vif->sme_state = SME_DISCONNECTED; + ar->sme_state = SME_DISCONNECTED; return 0; } -void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason, +void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid, u8 assoc_resp_len, u8 *assoc_info, u16 proto_reason) { - struct ath6kl *ar = vif->ar; - - if (vif->scan_req) { - cfg80211_scan_done(vif->scan_req, true); - vif->scan_req = NULL; + if (ar->scan_req) { + cfg80211_scan_done(ar->scan_req, true); + ar->scan_req = NULL; } - if (vif->nw_type & ADHOC_NETWORK) { - if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) { + if (ar->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__); return; } memset(bssid, 0, ETH_ALEN); - cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); + cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL); return; } - if (vif->nw_type & INFRA_NETWORK) { - if (vif->wdev.iftype != NL80211_IFTYPE_STATION && - vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) { + if (ar->nw_type & INFRA_NETWORK) { + if (ar->wdev->iftype != NL80211_IFTYPE_STATION && + ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: ath6k not in station mode\n", __func__); return; @@ -764,44 +612,42 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason, */ if (reason != DISCONNECT_CMD) { - ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx); + ath6kl_wmi_disconnect_cmd(ar->wmi); return; } - clear_bit(CONNECT_PEND, &vif->flags); + clear_bit(CONNECT_PEND, &ar->flag); - if (vif->sme_state == SME_CONNECTING) { - cfg80211_connect_result(vif->ndev, + if (ar->sme_state == SME_CONNECTING) { + cfg80211_connect_result(ar->net_dev, bssid, NULL, 0, NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); - } else if (vif->sme_state == SME_CONNECTED) { - cfg80211_disconnected(vif->ndev, reason, + } else if (ar->sme_state == SME_CONNECTED) { + cfg80211_disconnected(ar->net_dev, reason, NULL, 0, GFP_KERNEL); } - vif->sme_state = SME_DISCONNECTED; + ar->sme_state = SME_DISCONNECTED; } 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; - u32 force_fg_scan = 0; - if (!ath6kl_cfg80211_ready(vif)) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; if (!ar->usr_bss_filter) { - clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); + clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag); ret = ath6kl_wmi_bssfilter_cmd( - ar->wmi, vif->fw_vif_idx, - (test_bit(CONNECTED, &vif->flags) ? + ar->wmi, + (test_bit(CONNECTED, &ar->flag) ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0); if (ret) { ath6kl_err("couldn't set bss filtering\n"); @@ -816,15 +662,14 @@ 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, vif->fw_vif_idx, - i + 1, SPECIFIC_SSID_FLAG, + ath6kl_wmi_probedssid_cmd(ar->wmi, 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, vif->fw_vif_idx, - WMI_FRAME_PROBE_REQ, + ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_REQ, request->ie, request->ie_len); if (ret) { ath6kl_err("failed to set Probe Request appie for " @@ -855,47 +700,44 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, channels[i] = request->channels[i]->center_freq; } - if (test_bit(CONNECTED, &vif->flags)) - force_fg_scan = 1; - - ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx, WMI_LONG_SCAN, - force_fg_scan, false, 0, 0, n_channels, - channels); + ret = ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, 0, + false, 0, 0, n_channels, channels); if (ret) ath6kl_err("wmi_startscan_cmd failed\n"); else - vif->scan_req = request; + ar->scan_req = request; kfree(channels); return ret; } -void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted) +void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status) { - struct ath6kl *ar = vif->ar; int i; - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__, - aborted ? " aborted" : ""); + ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status %d\n", __func__, status); - if (!vif->scan_req) + if (!ar->scan_req) return; - if (aborted) + if ((status == -ECANCELED) || (status == -EBUSY)) { + cfg80211_scan_done(ar->scan_req, true); goto out; + } + + cfg80211_scan_done(ar->scan_req, false); - 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, vif->fw_vif_idx, - i + 1, DISABLE_SSID_FLAG, + if (ar->scan_req->n_ssids && ar->scan_req->ssids[0].ssid_len) { + for (i = 0; i < ar->scan_req->n_ssids; i++) { + ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1, + DISABLE_SSID_FLAG, 0, NULL); } } out: - cfg80211_scan_done(vif->scan_req, aborted); - vif->scan_req = NULL; + ar->scan_req = NULL; } static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, @@ -904,21 +746,14 @@ 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; + int status = 0; - if (!ath6kl_cfg80211_ready(vif)) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; - if (params->cipher == CCKM_KRK_CIPHER_SUITE) { - if (params->key_len != WMI_KRK_LEN) - return -EINVAL; - 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) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: key index %d out of bounds\n", __func__, @@ -926,7 +761,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, return -ENOENT; } - key = &vif->keys[key_index]; + key = &ar->keys[key_index]; memset(key, 0, sizeof(struct ath6kl_key)); if (pairwise) @@ -964,26 +799,26 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, return -ENOTSUPP; } - if (((vif->auth_mode == WPA_PSK_AUTH) - || (vif->auth_mode == WPA2_PSK_AUTH)) + if (((ar->auth_mode == WPA_PSK_AUTH) + || (ar->auth_mode == WPA2_PSK_AUTH)) && (key_usage & GROUP_USAGE)) - del_timer(&vif->disconnect_timer); + del_timer(&ar->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", __func__, key_index, key->key_len, key_type, key_usage, key->seq_len); - vif->def_txkey_index = key_index; + ar->def_txkey_index = key_index; - if (vif->nw_type == AP_NETWORK && !pairwise && + if (ar->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; 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, &vif->flags)) { + if (!test_bit(CONNECTED, &ar->flag)) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group " "key configuration until AP mode has been " "started\n"); @@ -995,8 +830,8 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, } } - if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT && - !test_bit(CONNECTED, &vif->flags)) { + if (ar->next_mode == AP_NETWORK && key_type == WEP_CRYPT && + !test_bit(CONNECTED, &ar->flag)) { /* * Store the key locally so that it can be re-configured after * the AP mode has properly started @@ -1004,18 +839,20 @@ 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"); - vif->wep_key_list[key_index].key_len = key->key_len; - memcpy(vif->wep_key_list[key_index].key, key->key, - key->key_len); + ar->wep_key_list[key_index].key_len = key->key_len; + memcpy(ar->wep_key_list[key_index].key, key->key, key->key_len); return 0; } - return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, - vif->def_txkey_index, - key_type, key_usage, key->key_len, - key->seq, key->seq_len, key->key, - KEY_OP_INIT_VAL, - (u8 *) mac_addr, SYNC_BOTH_WMIFLAG); + status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index, + key_type, key_usage, key->key_len, + key->seq, key->key, KEY_OP_INIT_VAL, + (u8 *) mac_addr, SYNC_BOTH_WMIFLAG); + + if (status) + return -EIO; + + return 0; } static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, @@ -1023,11 +860,10 @@ 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); - if (!ath6kl_cfg80211_ready(vif)) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { @@ -1037,15 +873,15 @@ static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, return -ENOENT; } - if (!vif->keys[key_index].key_len) { + if (!ar->keys[key_index].key_len) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d is empty\n", __func__, key_index); return 0; } - vif->keys[key_index].key_len = 0; + ar->keys[key_index].key_len = 0; - return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index); + return ath6kl_wmi_deletekey_cmd(ar->wmi, key_index); } static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, @@ -1054,13 +890,13 @@ static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, void (*callback) (void *cookie, struct key_params *)) { - struct ath6kl_vif *vif = netdev_priv(ndev); + struct ath6kl *ar = (struct ath6kl *)ath6kl_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(vif)) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { @@ -1070,7 +906,7 @@ static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, return -ENOENT; } - key = &vif->keys[key_index]; + key = &ar->keys[key_index]; memset(¶ms, 0, sizeof(params)); params.cipher = key->cipher; params.key_len = key->key_len; @@ -1089,14 +925,14 @@ 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; enum crypto_type key_type = NONE_CRYPT; ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index); - if (!ath6kl_cfg80211_ready(vif)) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { @@ -1106,41 +942,43 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy, return -ENOENT; } - if (!vif->keys[key_index].key_len) { + if (!ar->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 = &vif->keys[vif->def_txkey_index]; + ar->def_txkey_index = key_index; + key = &ar->keys[ar->def_txkey_index]; key_usage = GROUP_USAGE; - if (vif->prwise_crypto == WEP_CRYPT) + if (ar->prwise_crypto == WEP_CRYPT) key_usage |= TX_USAGE; if (unicast) - key_type = vif->prwise_crypto; + key_type = ar->prwise_crypto; if (multicast) - key_type = vif->grp_crypto; + key_type = ar->grp_crypto; - if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags)) + if (ar->next_mode == AP_NETWORK && !test_bit(CONNECTED, &ar->flag)) return 0; /* Delay until AP mode has been started */ - return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, - vif->def_txkey_index, - key_type, key_usage, - key->key_len, key->seq, key->seq_len, - key->key, - KEY_OP_INIT_VAL, NULL, - SYNC_BOTH_WMIFLAG); + status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index, + key_type, key_usage, + key->key_len, key->seq, key->key, + KEY_OP_INIT_VAL, NULL, + SYNC_BOTH_WMIFLAG); + if (status) + return -EIO; + + return 0; } -void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid, +void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast); - cfg80211_michael_mic_failure(vif->ndev, vif->bssid, + cfg80211_michael_mic_failure(ar->net_dev, ar->bssid, (ismcast ? NL80211_KEYTYPE_GROUP : NL80211_KEYTYPE_PAIRWISE), keyid, NULL, GFP_KERNEL); @@ -1149,17 +987,12 @@ 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); - vif = ath6kl_vif_first(ar); - if (!vif) - return -EIO; - - if (!ath6kl_cfg80211_ready(vif)) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; if (changed & WIPHY_PARAM_RTS_THRESHOLD) { @@ -1182,17 +1015,12 @@ 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); - vif = ath6kl_vif_first(ar); - if (!vif) - return -EIO; - - if (!ath6kl_cfg80211_ready(vif)) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; switch (type) { @@ -1207,7 +1035,7 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, return -EOPNOTSUPP; } - ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, ath6kl_dbm); + ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, ath6kl_dbm); return 0; } @@ -1215,19 +1043,14 @@ 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; - vif = ath6kl_vif_first(ar); - if (!vif) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; - if (!ath6kl_cfg80211_ready(vif)) - return -EIO; - - if (test_bit(CONNECTED, &vif->flags)) { + if (test_bit(CONNECTED, &ar->flag)) { ar->tx_pwr = 0; - if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) { + if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi) != 0) { ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n"); return -EIO; } @@ -1251,12 +1074,11 @@ 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); - if (!ath6kl_cfg80211_ready(vif)) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; if (pmgmt) { @@ -1267,8 +1089,7 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy, mode.pwr_mode = MAX_PERF_POWER; } - if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx, - mode.pwr_mode) != 0) { + if (ath6kl_wmi_powermode_cmd(ar->wmi, mode.pwr_mode) != 0) { ath6kl_err("wmi_powermode_cmd failed\n"); return -EIO; } @@ -1276,86 +1097,41 @@ 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_bh(&ar->list_lock); - list_del(&vif->list); - spin_unlock_bh(&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, struct vif_params *params) { - struct ath6kl_vif *vif = netdev_priv(ndev); + struct ath6kl *ar = ath6kl_priv(ndev); + struct wireless_dev *wdev = ar->wdev; ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type); - if (!ath6kl_cfg80211_ready(vif)) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; switch (type) { case NL80211_IFTYPE_STATION: - vif->next_mode = INFRA_NETWORK; + ar->next_mode = INFRA_NETWORK; break; case NL80211_IFTYPE_ADHOC: - vif->next_mode = ADHOC_NETWORK; + ar->next_mode = ADHOC_NETWORK; break; case NL80211_IFTYPE_AP: - vif->next_mode = AP_NETWORK; + ar->next_mode = AP_NETWORK; break; case NL80211_IFTYPE_P2P_CLIENT: - vif->next_mode = INFRA_NETWORK; + ar->next_mode = INFRA_NETWORK; break; case NL80211_IFTYPE_P2P_GO: - vif->next_mode = AP_NETWORK; + ar->next_mode = AP_NETWORK; break; default: ath6kl_err("invalid interface type %u\n", type); return -EOPNOTSUPP; } - vif->wdev.iftype = type; + wdev->iftype = type; return 0; } @@ -1365,17 +1141,16 @@ 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(vif)) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; - vif->ssid_len = ibss_param->ssid_len; - memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len); + ar->ssid_len = ibss_param->ssid_len; + memcpy(ar->ssid, ibss_param->ssid, ar->ssid_len); if (ibss_param->channel) - vif->ch_hint = ibss_param->channel->center_freq; + ar->ch_hint = ibss_param->channel->center_freq; if (ibss_param->channel_fixed) { /* @@ -1387,45 +1162,44 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy, return -EOPNOTSUPP; } - memset(vif->req_bssid, 0, sizeof(vif->req_bssid)); + memset(ar->req_bssid, 0, sizeof(ar->req_bssid)); if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid)) - memcpy(vif->req_bssid, ibss_param->bssid, - sizeof(vif->req_bssid)); + memcpy(ar->req_bssid, ibss_param->bssid, sizeof(ar->req_bssid)); - ath6kl_set_wpa_version(vif, 0); + ath6kl_set_wpa_version(ar, 0); - status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM); + status = ath6kl_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM); if (status) return status; if (ibss_param->privacy) { - ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true); - ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false); + ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true); + ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false); } else { - ath6kl_set_cipher(vif, 0, true); - ath6kl_set_cipher(vif, 0, false); + ath6kl_set_cipher(ar, 0, true); + ath6kl_set_cipher(ar, 0, false); } - vif->nw_type = vif->next_mode; + ar->nw_type = ar->next_mode; ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: connect called with authmode %d dot11 auth %d" " PW crypto %d PW crypto len %d GRP crypto %d" " GRP crypto len %d channel hint %u\n", __func__, - vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto, - vif->prwise_crypto_len, vif->grp_crypto, - vif->grp_crypto_len, vif->ch_hint); - - 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, - vif->grp_crypto, vif->grp_crypto_len, - vif->ssid_len, vif->ssid, - vif->req_bssid, vif->ch_hint, + ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto, + ar->prwise_crypto_len, ar->grp_crypto, + ar->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, + ar->req_bssid, ar->ch_hint, ar->connect_ctrl_flags); - set_bit(CONNECT_PEND, &vif->flags); + set_bit(CONNECT_PEND, &ar->flag); return 0; } @@ -1433,14 +1207,14 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy, static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) { - struct ath6kl_vif *vif = netdev_priv(dev); + struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev); - if (!ath6kl_cfg80211_ready(vif)) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; - ath6kl_disconnect(vif); - memset(vif->ssid, 0, sizeof(vif->ssid)); - vif->ssid_len = 0; + ath6kl_disconnect(ar); + memset(ar->ssid, 0, sizeof(ar->ssid)); + ar->ssid_len = 0; return 0; } @@ -1450,7 +1224,6 @@ static const u32 cipher_suites[] = { WLAN_CIPHER_SUITE_WEP104, WLAN_CIPHER_SUITE_TKIP, WLAN_CIPHER_SUITE_CCMP, - CCKM_KRK_CIPHER_SUITE, }; static bool is_rate_legacy(s32 rate) @@ -1518,22 +1291,21 @@ 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; int ret; u8 mcs; - if (memcmp(mac, vif->bssid, ETH_ALEN) != 0) + if (memcmp(mac, ar->bssid, ETH_ALEN) != 0) return -ENOENT; if (down_interruptible(&ar->sem)) return -EBUSY; - set_bit(STATS_UPDATE_PEND, &vif->flags); + set_bit(STATS_UPDATE_PEND, &ar->flag); - ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx); + ret = ath6kl_wmi_get_stats_cmd(ar->wmi); if (ret != 0) { up(&ar->sem); @@ -1542,7 +1314,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, - &vif->flags), + &ar->flag), WMI_TIMEOUT); up(&ar->sem); @@ -1552,24 +1324,24 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev, else if (left < 0) return left; - if (vif->target_stats.rx_byte) { - sinfo->rx_bytes = vif->target_stats.rx_byte; + if (ar->target_stats.rx_byte) { + sinfo->rx_bytes = ar->target_stats.rx_byte; sinfo->filled |= STATION_INFO_RX_BYTES; - sinfo->rx_packets = vif->target_stats.rx_pkt; + sinfo->rx_packets = ar->target_stats.rx_pkt; sinfo->filled |= STATION_INFO_RX_PACKETS; } - if (vif->target_stats.tx_byte) { - sinfo->tx_bytes = vif->target_stats.tx_byte; + if (ar->target_stats.tx_byte) { + sinfo->tx_bytes = ar->target_stats.tx_byte; sinfo->filled |= STATION_INFO_TX_BYTES; - sinfo->tx_packets = vif->target_stats.tx_pkt; + sinfo->tx_packets = ar->target_stats.tx_pkt; sinfo->filled |= STATION_INFO_TX_PACKETS; } - sinfo->signal = vif->target_stats.cs_rssi; + sinfo->signal = ar->target_stats.cs_rssi; sinfo->filled |= STATION_INFO_SIGNAL; - rate = vif->target_stats.tx_ucast_rate; + rate = ar->target_stats.tx_ucast_rate; if (is_rate_legacy(rate)) { sinfo->txrate.legacy = rate / 100; @@ -1601,13 +1373,13 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev, sinfo->filled |= STATION_INFO_TX_BITRATE; - if (test_bit(CONNECTED, &vif->flags) && - test_bit(DTIM_PERIOD_AVAIL, &vif->flags) && - vif->nw_type == INFRA_NETWORK) { + if (test_bit(CONNECTED, &ar->flag) && + test_bit(DTIM_PERIOD_AVAIL, &ar->flag) && + ar->nw_type == INFRA_NETWORK) { sinfo->filled |= STATION_INFO_BSS_PARAM; sinfo->bss_param.flags = 0; - sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period; - sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int; + sinfo->bss_param.dtim_period = ar->assoc_bss_dtim_period; + sinfo->bss_param.beacon_interval = ar->assoc_bss_beacon_int; } return 0; @@ -1617,9 +1389,7 @@ static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev, struct cfg80211_pmksa *pmksa) { struct ath6kl *ar = ath6kl_priv(netdev); - struct ath6kl_vif *vif = netdev_priv(netdev); - - return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid, + return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid, pmksa->pmkid, true); } @@ -1627,292 +1397,25 @@ static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, struct cfg80211_pmksa *pmksa) { struct ath6kl *ar = ath6kl_priv(netdev); - struct ath6kl_vif *vif = netdev_priv(netdev); - - return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid, + return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid, pmksa->pmkid, false); } static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) { struct ath6kl *ar = ath6kl_priv(netdev); - struct ath6kl_vif *vif = netdev_priv(netdev); - - if (test_bit(CONNECTED, &vif->flags)) - return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, - vif->bssid, NULL, false); - return 0; -} - -static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) -{ - struct ath6kl_vif *vif; - int ret, pos, left; - u32 filter = 0; - u16 i; - u8 mask[WOW_MASK_SIZE]; - - vif = ath6kl_vif_first(ar); - if (!vif) - return -EIO; - - if (!ath6kl_cfg80211_ready(vif)) - return -EIO; - - if (!test_bit(CONNECTED, &vif->flags)) - return -EINVAL; - - /* Clear existing WOW patterns */ - for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++) - ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx, - WOW_LIST_ID, i); - /* Configure new WOW patterns */ - for (i = 0; i < wow->n_patterns; i++) { - - /* - * Convert given nl80211 specific mask value to equivalent - * driver specific mask value and send it to the chip along - * with patterns. For example, If the mask value defined in - * struct cfg80211_wowlan is 0xA (equivalent binary is 1010), - * then equivalent driver specific mask value is - * "0xFF 0x00 0xFF 0x00". - */ - memset(&mask, 0, sizeof(mask)); - for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) { - if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8))) - mask[pos] = 0xFF; - } - /* - * Note: Pattern's offset is not passed as part of wowlan - * parameter from CFG layer. So it's always passed as ZERO - * to the firmware. It means, given WOW patterns are always - * matched from the first byte of received pkt in the firmware. - */ - ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, - vif->fw_vif_idx, WOW_LIST_ID, - wow->patterns[i].pattern_len, - 0 /* pattern offset */, - wow->patterns[i].pattern, mask); - if (ret) - return ret; - } - - if (wow->disconnect) - filter |= WOW_FILTER_OPTION_NWK_DISASSOC; - - if (wow->magic_pkt) - filter |= WOW_FILTER_OPTION_MAGIC_PACKET; - - if (wow->gtk_rekey_failure) - filter |= WOW_FILTER_OPTION_GTK_ERROR; - - if (wow->eap_identity_req) - filter |= WOW_FILTER_OPTION_EAP_REQ; - - if (wow->four_way_handshake) - filter |= WOW_FILTER_OPTION_8021X_4WAYHS; - - ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, - ATH6KL_WOW_MODE_ENABLE, - filter, - WOW_HOST_REQ_DELAY); - if (ret) - return ret; - - ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, - ATH6KL_HOST_MODE_ASLEEP); - if (ret) - return ret; - - if (ar->tx_pending[ar->ctrl_ep]) { - left = wait_event_interruptible_timeout(ar->event_wq, - ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT); - if (left == 0) { - ath6kl_warn("clear wmi ctrl data timeout\n"); - ret = -ETIMEDOUT; - } else if (left < 0) { - ath6kl_warn("clear wmi ctrl data failed: %d\n", left); - ret = left; - } - } - - return ret; -} - -static int ath6kl_wow_resume(struct ath6kl *ar) -{ - struct ath6kl_vif *vif; - int ret; - - vif = ath6kl_vif_first(ar); - if (!vif) - return -EIO; - - ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, - ATH6KL_HOST_MODE_AWAKE); - return ret; -} - -int ath6kl_cfg80211_suspend(struct ath6kl *ar, - enum ath6kl_cfg_suspend_mode mode, - struct cfg80211_wowlan *wow) -{ - int ret; - - switch (mode) { - case ATH6KL_CFG_SUSPEND_WOW: - - ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n"); - - /* Flush all non control pkts in TX path */ - ath6kl_tx_data_cleanup(ar); - - ret = ath6kl_wow_suspend(ar, wow); - if (ret) { - ath6kl_err("wow suspend failed: %d\n", ret); - return ret; - } - ar->state = ATH6KL_STATE_WOW; - break; - - case ATH6KL_CFG_SUSPEND_DEEPSLEEP: - - ath6kl_cfg80211_stop(ar); - - /* save the current power mode before enabling power save */ - ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode; - - ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER); - if (ret) { - ath6kl_warn("wmi powermode command failed during suspend: %d\n", - ret); - } - - ar->state = ATH6KL_STATE_DEEPSLEEP; - - break; - - case ATH6KL_CFG_SUSPEND_CUTPOWER: - - ath6kl_cfg80211_stop(ar); - - if (ar->state == ATH6KL_STATE_OFF) { - ath6kl_dbg(ATH6KL_DBG_SUSPEND, - "suspend hw off, no action for cutpower\n"); - break; - } - - ath6kl_dbg(ATH6KL_DBG_SUSPEND, "suspend cutting power\n"); - - ret = ath6kl_init_hw_stop(ar); - if (ret) { - ath6kl_warn("failed to stop hw during suspend: %d\n", - ret); - } - - ar->state = ATH6KL_STATE_CUTPOWER; - - break; - - default: - break; - } - - return 0; -} - -int ath6kl_cfg80211_resume(struct ath6kl *ar) -{ - int ret; - - switch (ar->state) { - case ATH6KL_STATE_WOW: - ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n"); - - ret = ath6kl_wow_resume(ar); - if (ret) { - ath6kl_warn("wow mode resume failed: %d\n", ret); - return ret; - } - - ar->state = ATH6KL_STATE_ON; - break; - - case ATH6KL_STATE_DEEPSLEEP: - if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) { - ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, - ar->wmi->saved_pwr_mode); - if (ret) { - ath6kl_warn("wmi powermode command failed during resume: %d\n", - ret); - } - } - - ar->state = ATH6KL_STATE_ON; - - break; - - case ATH6KL_STATE_CUTPOWER: - ath6kl_dbg(ATH6KL_DBG_SUSPEND, "resume restoring power\n"); - - ret = ath6kl_init_hw_start(ar); - if (ret) { - ath6kl_warn("Failed to boot hw in resume: %d\n", ret); - return ret; - } - break; - - default: - break; - } - + if (test_bit(CONNECTED, &ar->flag)) + return ath6kl_wmi_setpmkid_cmd(ar->wmi, ar->bssid, NULL, false); return 0; } #ifdef CONFIG_PM - -/* hif layer decides what suspend mode to use */ -static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy, +static int ar6k_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) { struct ath6kl *ar = wiphy_priv(wiphy); - return ath6kl_hif_suspend(ar, wow); -} - -static int __ath6kl_cfg80211_resume(struct wiphy *wiphy) -{ - struct ath6kl *ar = wiphy_priv(wiphy); - - return ath6kl_hif_resume(ar); -} - -/* - * FIXME: WOW suspend mode is selected if the host sdio controller supports - * both sdio irq wake up and keep power. The target pulls sdio data line to - * wake up the host when WOW pattern matches. This causes sdio irq handler - * is being called in the host side which internally hits ath6kl's RX path. - * - * Since sdio interrupt is not disabled, RX path executes even before - * the host executes the actual resume operation from PM module. - * - * In the current scenario, WOW resume should happen before start processing - * any data from the target. So It's required to perform WOW resume in RX path. - * Ideally we should perform WOW resume only in the actual platform - * resume path. This area needs bit rework to avoid WOW resume in RX path. - * - * ath6kl_check_wow_status() is called from ath6kl_rx(). - */ -void ath6kl_check_wow_status(struct ath6kl *ar) -{ - if (ar->state == ATH6KL_STATE_WOW) - ath6kl_cfg80211_resume(ar); -} - -#else - -void ath6kl_check_wow_status(struct ath6kl *ar) -{ + return ath6kl_hif_suspend(ar); } #endif @@ -1920,14 +1423,14 @@ static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { - struct ath6kl_vif *vif = netdev_priv(dev); + struct ath6kl *ar = ath6kl_priv(dev); - if (!ath6kl_cfg80211_ready(vif)) + 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); - vif->next_chan = chan->center_freq; + ar->next_chan = chan->center_freq; return 0; } @@ -1939,10 +1442,9 @@ 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_vif *vif, - const u8 *ies, size_t ies_len) +static int ath6kl_set_ap_probe_resp_ies(struct ath6kl *ar, const u8 *ies, + size_t ies_len) { - struct ath6kl *ar = vif->ar; const u8 *pos; u8 *buf = NULL; size_t len = 0; @@ -1969,8 +1471,8 @@ static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif, } } - ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, - WMI_FRAME_PROBE_RESP, buf, len); + ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_RESP, + buf, len); kfree(buf); return ret; } @@ -1979,7 +1481,6 @@ 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; @@ -1989,29 +1490,27 @@ 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(vif)) + if (!ath6kl_cfg80211_ready(ar)) return -EIO; - if (vif->next_mode != AP_NETWORK) + if (ar->next_mode != AP_NETWORK) return -EOPNOTSUPP; if (info->beacon_ies) { - res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, - WMI_FRAME_BEACON, + res = ath6kl_wmi_set_appie_cmd(ar->wmi, 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(vif, info->proberesp_ies, + res = ath6kl_set_ap_probe_resp_ies(ar, info->proberesp_ies, info->proberesp_ies_len); if (res) return res; } if (info->assocresp_ies) { - res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, - WMI_FRAME_ASSOC_RESP, + res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_ASSOC_RESP, info->assocresp_ies, info->assocresp_ies_len); if (res) @@ -2038,12 +1537,12 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, if (info->ssid == NULL) return -EINVAL; - memcpy(vif->ssid, info->ssid, info->ssid_len); - vif->ssid_len = info->ssid_len; + memcpy(ar->ssid, info->ssid, info->ssid_len); + ar->ssid_len = info->ssid_len; if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE) return -EOPNOTSUPP; /* TODO */ - vif->dot11_auth_mode = OPEN_AUTH; + ar->dot11_auth_mode = OPEN_AUTH; memset(&p, 0, sizeof(p)); @@ -2065,7 +1564,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, } if (p.auth_mode == 0) p.auth_mode = NONE_AUTH; - vif->auth_mode = p.auth_mode; + ar->auth_mode = p.auth_mode; for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) { switch (info->crypto.ciphers_pairwise[i]) { @@ -2083,9 +1582,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(vif, 0, true); + ath6kl_set_cipher(ar, 0, true); } else if (info->crypto.n_ciphers_pairwise == 1) - ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true); + ath6kl_set_cipher(ar, info->crypto.ciphers_pairwise[0], true); switch (info->crypto.cipher_group) { case WLAN_CIPHER_SUITE_WEP40: @@ -2102,17 +1601,17 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, p.grp_crypto_type = NONE_CRYPT; break; } - ath6kl_set_cipher(vif, info->crypto.cipher_group, false); + ath6kl_set_cipher(ar, info->crypto.cipher_group, false); p.nw_type = AP_NETWORK; - vif->nw_type = vif->next_mode; + ar->nw_type = ar->next_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(vif->next_chan); + p.ssid_len = ar->ssid_len; + memcpy(p.ssid, ar->ssid, ar->ssid_len); + p.dot11_auth_mode = ar->dot11_auth_mode; + p.ch = cpu_to_le16(ar->next_chan); - res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p); + res = ath6kl_wmi_ap_profile_commit(ar->wmi, &p); if (res < 0) return res; @@ -2134,15 +1633,14 @@ 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 (vif->nw_type != AP_NETWORK) + if (ar->nw_type != AP_NETWORK) return -EOPNOTSUPP; - if (!test_bit(CONNECTED, &vif->flags)) + if (!test_bit(CONNECTED, &ar->flag)) return -ENOTCONN; - ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx); - clear_bit(CONNECTED, &vif->flags); + ath6kl_wmi_disconnect_cmd(ar->wmi); + clear_bit(CONNECTED, &ar->flag); return 0; } @@ -2151,9 +1649,8 @@ 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 (vif->nw_type != AP_NETWORK) + if (ar->nw_type != AP_NETWORK) return -EOPNOTSUPP; /* Use this only for authorizing/unauthorizing a station */ @@ -2161,10 +1658,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, 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); + 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); } static int ath6kl_remain_on_channel(struct wiphy *wiphy, @@ -2175,20 +1672,13 @@ static int ath6kl_remain_on_channel(struct wiphy *wiphy, u64 *cookie) { struct ath6kl *ar = ath6kl_priv(dev); - struct ath6kl_vif *vif = netdev_priv(dev); - u32 id; /* TODO: if already pending or ongoing remain-on-channel, * return -EBUSY */ - id = ++vif->last_roc_id; - if (id == 0) { - /* Do not use 0 as the cookie value */ - id = ++vif->last_roc_id; - } - *cookie = id; + *cookie = 1; /* only a single pending request is supported */ - return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx, - chan->center_freq, duration); + return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, chan->center_freq, + duration); } static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy, @@ -2196,20 +1686,16 @@ 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 != vif->last_roc_id) + if (cookie != 1) return -ENOENT; - vif->last_cancel_roc_id = cookie; - return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx); + return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi); } -static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif, - const u8 *buf, size_t len, - unsigned int freq) +static int ath6kl_send_go_probe_resp(struct ath6kl *ar, const u8 *buf, + size_t len, unsigned int freq) { - struct ath6kl *ar = vif->ar; const u8 *pos; u8 *p2p; int p2p_len; @@ -2236,8 +1722,8 @@ static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif, pos += 2 + pos[1]; } - ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq, - mgmt->da, p2p, p2p_len); + ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, freq, mgmt->da, + p2p, p2p_len); kfree(p2p); return ret; } @@ -2250,35 +1736,33 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, bool dont_wait_for_ack, 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 && - vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) && + ar->nw_type == AP_NETWORK && test_bit(CONNECTED, &ar->flag) && ieee80211_is_probe_resp(mgmt->frame_control)) { /* * Send Probe Response frame in AP mode using a separate WMI * command to allow the target to fill in the generic IEs. */ *cookie = 0; /* TX status not supported */ - return ath6kl_send_go_probe_resp(vif, buf, len, + return ath6kl_send_go_probe_resp(ar, buf, len, chan->center_freq); } - id = vif->send_action_id++; + id = ar->send_action_id++; if (id == 0) { /* * 0 is a reserved value in the WMI command and shall not be * used for the command. */ - id = vif->send_action_id++; + id = ar->send_action_id++; } *cookie = id; - return ath6kl_wmi_send_action_cmd(ar->wmi, vif->fw_vif_idx, id, - chan->center_freq, wait, + return ath6kl_wmi_send_action_cmd(ar->wmi, id, chan->center_freq, wait, buf, len); } @@ -2286,7 +1770,7 @@ static void ath6kl_mgmt_frame_register(struct wiphy *wiphy, struct net_device *dev, u16 frame_type, bool reg) { - struct ath6kl_vif *vif = netdev_priv(dev); + struct ath6kl *ar = ath6kl_priv(dev); ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n", __func__, frame_type, reg); @@ -2296,7 +1780,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. */ - vif->probe_req_report = reg; + ar->probe_req_report = reg; } } @@ -2323,8 +1807,6 @@ 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, @@ -2345,8 +1827,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { .flush_pmksa = ath6kl_flush_pmksa, CFG80211_TESTMODE_CMD(ath6kl_tm_cmd) #ifdef CONFIG_PM - .suspend = __ath6kl_cfg80211_suspend, - .resume = __ath6kl_cfg80211_resume, + .suspend = ar6k_cfg80211_suspend, #endif .set_channel = ath6kl_set_channel, .add_beacon = ath6kl_add_beacon, @@ -2359,269 +1840,76 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { .mgmt_frame_register = ath6kl_mgmt_frame_register, }; -void ath6kl_cfg80211_stop(struct ath6kl *ar) +struct wireless_dev *ath6kl_cfg80211_init(struct device *dev) { - 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; - } + int ret = 0; + struct wireless_dev *wdev; + struct ath6kl *ar; - switch (vif->sme_state) { - case SME_CONNECTING: - cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0, - NULL, 0, - WLAN_STATUS_UNSPECIFIED_FAILURE, - GFP_KERNEL); - break; - case SME_CONNECTED: - default: - /* - * FIXME: oddly enough smeState is in DISCONNECTED during - * suspend, why? Need to send disconnected event in that - * state. - */ - cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL); - break; + wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); + if (!wdev) { + ath6kl_err("couldn't allocate wireless device\n"); + return NULL; } - if (test_bit(CONNECTED, &vif->flags) || - test_bit(CONNECT_PEND, &vif->flags)) - ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx); - - vif->sme_state = SME_DISCONNECTED; - clear_bit(CONNECTED, &vif->flags); - clear_bit(CONNECT_PEND, &vif->flags); - - /* disable scanning */ - 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"); - - ath6kl_cfg80211_scan_complete_event(vif, true); -} - -struct ath6kl *ath6kl_core_alloc(struct device *dev) -{ - struct ath6kl *ar; - struct wiphy *wiphy; - u8 ctr; - /* create a new wiphy for use with cfg80211 */ - wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl)); - - if (!wiphy) { + wdev->wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl)); + if (!wdev->wiphy) { ath6kl_err("couldn't allocate wiphy device\n"); + kfree(wdev); return NULL; } - ar = wiphy_priv(wiphy); - 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); + ar = wiphy_priv(wdev->wiphy); + ar->p2p = !!ath6kl_p2p; - init_waitqueue_head(&ar->event_wq); - sema_init(&ar->sem, 1); + wdev->wiphy->mgmt_stypes = ath6kl_mgmt_stypes; - 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); - 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; - - ar->state = ATH6KL_STATE_OFF; - - 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; + wdev->wiphy->max_remain_on_channel_duration = 5000; /* set device pointer for wiphy */ - set_wiphy_dev(wiphy, ar->dev); + set_wiphy_dev(wdev->wiphy, dev); - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_AP); + wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); if (ar->p2p) { - wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) | - BIT(NL80211_IFTYPE_P2P_CLIENT); + wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) | + 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? */ - wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; - wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz; - wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - - wiphy->cipher_suites = cipher_suites; - wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); - - wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | - WIPHY_WOWLAN_DISCONNECT | - WIPHY_WOWLAN_GTK_REKEY_FAILURE | - WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | - WIPHY_WOWLAN_EAP_IDENTITY_REQ | - WIPHY_WOWLAN_4WAY_HANDSHAKE; - wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST; - wiphy->wowlan.pattern_min_len = 1; - wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; - - ret = wiphy_register(wiphy); - if (ret < 0) { - ath6kl_err("couldn't register wiphy device\n"); - return ret; - } + 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; - return 0; -} + wdev->wiphy->cipher_suites = cipher_suites; + wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); -static int ath6kl_init_if_data(struct ath6kl_vif *vif) -{ - vif->aggr_cntxt = aggr_init(vif->ndev); - if (!vif->aggr_cntxt) { - ath6kl_err("failed to initialize aggr\n"); - return -ENOMEM; + ret = wiphy_register(wdev->wiphy); + if (ret < 0) { + ath6kl_err("couldn't register wiphy device\n"); + wiphy_free(wdev->wiphy); + kfree(wdev); + return NULL; } - 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; -} - -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--; + return wdev; } -struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, - enum nl80211_iftype type, u8 fw_vif_idx, - u8 nw_type) +void ath6kl_cfg80211_deinit(struct ath6kl *ar) { - struct net_device *ndev; - struct ath6kl_vif *vif; - - ndev = alloc_netdev(sizeof(*vif), name, ether_setup); - if (!ndev) - return NULL; - - vif = netdev_priv(ndev); - ndev->ieee80211_ptr = &vif->wdev; - vif->wdev.wiphy = ar->wiphy; - vif->ar = ar; - vif->ndev = ndev; - SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy)); - vif->wdev.netdev = ndev; - vif->wdev.iftype = type; - vif->fw_vif_idx = fw_vif_idx; - vif->nw_type = vif->next_mode = nw_type; - - 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); + struct wireless_dev *wdev = ar->wdev; - ath6kl_init_control_info(vif); - - /* TODO: Pass interface specific pointer instead of ar */ - if (ath6kl_init_if_data(vif)) - goto err; - - 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_bh(&ar->list_lock); - list_add_tail(&vif->list, &ar->vif_list); - spin_unlock_bh(&ar->list_lock); - - return ndev; + if (ar->scan_req) { + cfg80211_scan_done(ar->scan_req, true); + ar->scan_req = NULL; + } -err: - aggr_module_destroy(vif->aggr_cntxt); - free_netdev(ndev); - return NULL; -} + if (!wdev) + return; -void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar) -{ - wiphy_unregister(ar->wiphy); - wiphy_free(ar->wiphy); + wiphy_unregister(wdev->wiphy); + wiphy_free(wdev->wiphy); + kfree(wdev); } diff --git a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h index 59fa9d859def..a84adc249c61 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -17,41 +17,23 @@ #ifndef ATH6KL_CFG80211_H #define ATH6KL_CFG80211_H -enum ath6kl_cfg_suspend_mode { - ATH6KL_CFG_SUSPEND_DEEPSLEEP, - ATH6KL_CFG_SUSPEND_CUTPOWER, - ATH6KL_CFG_SUSPEND_WOW -}; +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, - 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); +void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status); -void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); - -void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, +void ath6kl_cfg80211_connect_event(struct ath6kl *ar, 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_vif *vif, u8 reason, +void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid, u8 assoc_resp_len, u8 *assoc_info, u16 proto_reason); -void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid, +void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast); -int ath6kl_cfg80211_suspend(struct ath6kl *ar, - enum ath6kl_cfg_suspend_mode mode, - struct cfg80211_wowlan *wow); - -int ath6kl_cfg80211_resume(struct ath6kl *ar); - -void ath6kl_cfg80211_stop(struct ath6kl *ar); - #endif /* ATH6KL_CFG80211_H */ diff --git a/trunk/drivers/net/wireless/ath/ath6kl/common.h b/trunk/drivers/net/wireless/ath/ath6kl/common.h index 41e465f29e63..b92f0e5d2336 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/common.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/common.h @@ -23,6 +23,8 @@ extern int ath6kl_printk(const char *level, const char *fmt, ...); +#define A_CACHE_LINE_PAD 128 + /* * Reflects the version of binary interface exposed by ATH6KL target * firmware. Needs to be incremented by 1 for any change in the firmware @@ -76,10 +78,20 @@ enum crypto_type { struct htc_endpoint_credit_dist; struct ath6kl; enum htc_credit_dist_reason; -struct ath6kl_htc_credit_info; +struct htc_credit_state_info; +int ath6k_setup_credit_dist(void *htc_handle, + struct htc_credit_state_info *cred_info); +void ath6k_credit_distribute(struct htc_credit_state_info *cred_inf, + struct list_head *epdist_list, + enum htc_credit_dist_reason reason); +void ath6k_credit_init(struct htc_credit_state_info *cred_inf, + struct list_head *ep_list, + int tot_credits); +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); -void ath6kl_core_cleanup(struct ath6kl *ar); +int ath6kl_unavail_ev(struct ath6kl *ar); struct sk_buff *ath6kl_buf_alloc(int size); #endif /* COMMON_H */ diff --git a/trunk/drivers/net/wireless/ath/ath6kl/core.h b/trunk/drivers/net/wireless/ath/ath6kl/core.h index e7e095e536a7..6d8a4845baaf 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/core.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/core.h @@ -166,7 +166,6 @@ struct ath6kl_fw_ie { #define ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN BIT(1) #define ATH6KL_CONF_ENABLE_11N BIT(2) #define ATH6KL_CONF_ENABLE_TX_BURST BIT(3) -#define ATH6KL_CONF_SUSPEND_CUTPOWER BIT(4) enum wlan_low_pwr_state { WLAN_POWER_STATE_ON, @@ -381,33 +380,40 @@ struct ath6kl_req_key { u8 key_len; }; -#define MAX_NUM_VIF 1 - -/* 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, - STATS_UPDATE_PEND, -}; +/* 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 -struct ath6kl_vif { - struct list_head list; - 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; +struct ath6kl { + struct device *dev; + struct net_device *net_dev; + struct ath6kl_bmi bmi; + const struct ath6kl_hif_ops *hif_ops; + struct wmi *wmi; + int tx_pending[ENDPOINT_MAX]; + int total_tx_data_pend; + struct htc_target *htc_target; + void *hif_priv; + 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; @@ -415,83 +421,21 @@ struct ath6kl_vif { u8 grp_crypto; u8 grp_crypto_len; u8 def_txkey_index; - 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]; 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]; - struct aggr_info *aggr_cntxt; - struct timer_list disconnect_timer; - struct cfg80211_scan_request *scan_req; - enum sme_state sme_state; - int reconnect_flag; - u32 last_roc_id; - u32 last_cancel_roc_id; - u32 send_action_id; - bool probe_req_report; - u16 next_chan; - u16 assoc_bss_beacon_int; - u8 assoc_bss_dtim_period; - struct net_device_stats net_stats; - struct target_stats target_stats; -}; - -#define WOW_LIST_ID 0 -#define WOW_HOST_REQ_DELAY 500 /* ms */ - -/* Flag info */ -enum ath6kl_dev_state { - WMI_ENABLED, - WMI_READY, - WMI_CTRL_EP_FULL, - TESTMODE, - DESTROY_IN_PROGRESS, - SKIP_SCAN, - ROAM_TBL_PEND, - FIRST_BOOT, -}; - -enum ath6kl_state { - ATH6KL_STATE_OFF, - ATH6KL_STATE_ON, - ATH6KL_STATE_DEEPSLEEP, - ATH6KL_STATE_CUTPOWER, - ATH6KL_STATE_WOW, -}; - -struct ath6kl { - struct device *dev; - struct wiphy *wiphy; - - enum ath6kl_state state; - - struct ath6kl_bmi bmi; - const struct ath6kl_hif_ops *hif_ops; - struct wmi *wmi; - int tx_pending[ENDPOINT_MAX]; - int total_tx_data_pend; - struct htc_target *htc_target; - void *hif_priv; - 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 max_norm_iface; - u8 avail_idx_map; - spinlock_t lock; - struct semaphore sem; u16 listen_intvl_b; u16 listen_intvl_t; u8 lrssi_roam_threshold; 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; - bool ibss_if_active; u8 node_num; u8 next_ep_id; struct ath6kl_cookie *cookie_list; @@ -502,7 +446,7 @@ struct ath6kl { u8 hiac_stream_active_pri; u8 ep2ac_map[ENDPOINT_MAX]; enum htc_endpoint_id ctrl_ep; - struct ath6kl_htc_credit_info credit_state_info; + struct htc_credit_state_info credit_state_info; u32 connect_ctrl_flags; u32 user_key_ctrl; u8 usr_bss_filter; @@ -512,13 +456,18 @@ 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; + struct timer_list disconnect_timer; 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; - u8 mac_addr[ETH_ALEN]; #define AR_MCAST_FILTER_MAC_ADDR_SIZE 4 struct { void *rx_report; @@ -538,6 +487,7 @@ 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; @@ -558,7 +508,13 @@ 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 { @@ -573,19 +529,23 @@ struct ath6kl { struct { unsigned int invalid_rate; } war_stats; - - u8 *roam_tbl; - unsigned int roam_tbl_len; - - u8 keepalive; - u8 disc_timeout; } debug; #endif /* CONFIG_ATH6KL_DEBUG */ }; static inline void *ath6kl_priv(struct net_device *dev) { - return ((struct ath6kl_vif *) netdev_priv(dev))->ar; + return wdev_priv(dev->ieee80211_ptr); +} + +static inline void ath6kl_deposit_credit_to_ep(struct htc_credit_state_info + *cred_info, + struct htc_endpoint_credit_dist + *ep_dist, int credits) +{ + ep_dist->credits += credits; + ep_dist->cred_assngd += credits; + cred_info->cur_free_credits -= credits; } static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar, @@ -601,6 +561,7 @@ 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); @@ -618,8 +579,10 @@ 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_vif *vif); +void ath6kl_init_profile_info(struct ath6kl *ar); 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); @@ -635,49 +598,40 @@ 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_vif *vif, u8 * node_addr); +struct ath6kl_sta *ath6kl_find_sta(struct ath6kl *ar, 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); int ath6kl_control_tx(void *devt, struct sk_buff *skb, enum htc_endpoint_id eid); -void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, +void ath6kl_connect_event(struct ath6kl *ar, 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_vif *vif, u16 channel); -void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, +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, u8 keymgmt, u8 ucipher, u8 auth, u8 assoc_req_len, u8 *assoc_info); -void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, +void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid, u8 assoc_resp_len, u8 *assoc_info, u16 prot_reason_status); -void ath6kl_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid, bool ismcast); +void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast); void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr); -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_scan_complete_evt(struct ath6kl *ar, int status); +void ath6kl_tgt_stats_event(struct ath6kl *ar, 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_vif *vif, u8 aid); +void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid); -void ath6kl_dtimexpiry_event(struct ath6kl_vif *vif); -void ath6kl_disconnect(struct ath6kl_vif *vif); -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, +void ath6kl_dtimexpiry_event(struct ath6kl *ar); +void ath6kl_disconnect(struct ath6kl *ar); +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, u8 win_sz); void ath6kl_wakeup_event(void *dev); - -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); -struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar); -void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready); -int ath6kl_init_hw_start(struct ath6kl *ar); -int ath6kl_init_hw_stop(struct ath6kl *ar); -void ath6kl_check_wow_status(struct ath6kl *ar); +void ath6kl_target_failure(struct ath6kl *ar); #endif /* CORE_H */ diff --git a/trunk/drivers/net/wireless/ath/ath6kl/debug.c b/trunk/drivers/net/wireless/ath/ath6kl/debug.c index 370664a7a37b..ba3f23d71150 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/debug.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/debug.c @@ -142,48 +142,49 @@ void ath6kl_dump_registers(struct ath6kl_device *dev, static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist) { - ath6kl_dbg(ATH6KL_DBG_CREDIT, + ath6kl_dbg(ATH6KL_DBG_ANY, "--- endpoint: %d svc_id: 0x%X ---\n", ep_dist->endpoint, ep_dist->svc_id); - ath6kl_dbg(ATH6KL_DBG_CREDIT, " dist_flags : 0x%X\n", + ath6kl_dbg(ATH6KL_DBG_ANY, " dist_flags : 0x%X\n", ep_dist->dist_flags); - ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_norm : %d\n", + ath6kl_dbg(ATH6KL_DBG_ANY, " cred_norm : %d\n", ep_dist->cred_norm); - ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_min : %d\n", + ath6kl_dbg(ATH6KL_DBG_ANY, " cred_min : %d\n", ep_dist->cred_min); - ath6kl_dbg(ATH6KL_DBG_CREDIT, " credits : %d\n", + ath6kl_dbg(ATH6KL_DBG_ANY, " credits : %d\n", ep_dist->credits); - ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_assngd : %d\n", + ath6kl_dbg(ATH6KL_DBG_ANY, " cred_assngd : %d\n", ep_dist->cred_assngd); - ath6kl_dbg(ATH6KL_DBG_CREDIT, " seek_cred : %d\n", + ath6kl_dbg(ATH6KL_DBG_ANY, " seek_cred : %d\n", ep_dist->seek_cred); - ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_sz : %d\n", + ath6kl_dbg(ATH6KL_DBG_ANY, " cred_sz : %d\n", ep_dist->cred_sz); - ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_per_msg : %d\n", + ath6kl_dbg(ATH6KL_DBG_ANY, " cred_per_msg : %d\n", ep_dist->cred_per_msg); - ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_to_dist : %d\n", + ath6kl_dbg(ATH6KL_DBG_ANY, " cred_to_dist : %d\n", ep_dist->cred_to_dist); - ath6kl_dbg(ATH6KL_DBG_CREDIT, " txq_depth : %d\n", - get_queue_depth(&ep_dist->htc_ep->txq)); - ath6kl_dbg(ATH6KL_DBG_CREDIT, + ath6kl_dbg(ATH6KL_DBG_ANY, " txq_depth : %d\n", + get_queue_depth(&((struct htc_endpoint *) + ep_dist->htc_rsvd)->txq)); + ath6kl_dbg(ATH6KL_DBG_ANY, "----------------------------------\n"); } -/* FIXME: move to htc.c */ void dump_cred_dist_stats(struct htc_target *target) { struct htc_endpoint_credit_dist *ep_list; - if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_CREDIT)) + if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_TRC)) return; list_for_each_entry(ep_list, &target->cred_dist_list, list) dump_cred_dist(ep_list); - ath6kl_dbg(ATH6KL_DBG_CREDIT, - "credit distribution total %d free %d\n", - target->credit_info->total_avail_credits, - target->credit_info->cur_free_credits); + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:%p dist:%p\n", + target->cred_dist_cntxt, NULL); + ath6kl_dbg(ATH6KL_DBG_TRC, "credit distribution, total : %d, free : %d\n", + target->cred_dist_cntxt->total_avail_credits, + target->cred_dist_cntxt->cur_free_credits); } static int ath6kl_debugfs_open(struct inode *inode, struct file *file) @@ -395,20 +396,13 @@ 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 ath6kl_vif *vif; - struct target_stats *tgt_stats; + struct target_stats *tgt_stats = &ar->target_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; @@ -418,9 +412,9 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, return -EBUSY; } - set_bit(STATS_UPDATE_PEND, &vif->flags); + set_bit(STATS_UPDATE_PEND, &ar->flag); - if (ath6kl_wmi_get_stats_cmd(ar->wmi, 0)) { + if (ath6kl_wmi_get_stats_cmd(ar->wmi)) { up(&ar->sem); kfree(buf); return -EIO; @@ -428,7 +422,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, - &vif->flags), WMI_TIMEOUT); + &ar->flag), WMI_TIMEOUT); up(&ar->sem); @@ -560,10 +554,10 @@ static ssize_t read_file_credit_dist_stats(struct file *file, len += scnprintf(buf + len, buf_len - len, "%25s%5d\n", "Total Avail Credits: ", - target->credit_info->total_avail_credits); + target->cred_dist_cntxt->total_avail_credits); len += scnprintf(buf + len, buf_len - len, "%25s%5d\n", "Free credits :", - target->credit_info->cur_free_credits); + target->cred_dist_cntxt->cur_free_credits); len += scnprintf(buf + len, buf_len - len, " Epid Flags Cred_norm Cred_min Credits Cred_assngd" @@ -582,7 +576,8 @@ static ssize_t read_file_credit_dist_stats(struct file *file, print_credit_info("%9d", cred_per_msg); print_credit_info("%14d", cred_to_dist); len += scnprintf(buf + len, buf_len - len, "%12d\n", - get_queue_depth(&ep_list->htc_ep->txq)); + get_queue_depth(&((struct htc_endpoint *) + ep_list->htc_rsvd)->txq)); } if (len > buf_len) @@ -600,107 +595,6 @@ static const struct file_operations fops_credit_dist_stats = { .llseek = default_llseek, }; -static unsigned int print_endpoint_stat(struct htc_target *target, char *buf, - unsigned int buf_len, unsigned int len, - int offset, const char *name) -{ - int i; - struct htc_endpoint_stats *ep_st; - u32 *counter; - - len += scnprintf(buf + len, buf_len - len, "%s:", name); - for (i = 0; i < ENDPOINT_MAX; i++) { - ep_st = &target->endpoint[i].ep_st; - counter = ((u32 *) ep_st) + (offset / 4); - len += scnprintf(buf + len, buf_len - len, " %u", *counter); - } - len += scnprintf(buf + len, buf_len - len, "\n"); - - return len; -} - -static ssize_t ath6kl_endpoint_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath6kl *ar = file->private_data; - struct htc_target *target = ar->htc_target; - char *buf; - unsigned int buf_len, len = 0; - ssize_t ret_cnt; - - buf_len = sizeof(struct htc_endpoint_stats) / sizeof(u32) * - (25 + ENDPOINT_MAX * 11); - buf = kmalloc(buf_len, GFP_KERNEL); - if (!buf) - return -ENOMEM; - -#define EPSTAT(name) \ - len = print_endpoint_stat(target, buf, buf_len, len, \ - offsetof(struct htc_endpoint_stats, name), \ - #name) - EPSTAT(cred_low_indicate); - EPSTAT(tx_issued); - EPSTAT(tx_pkt_bundled); - EPSTAT(tx_bundles); - EPSTAT(tx_dropped); - EPSTAT(tx_cred_rpt); - EPSTAT(cred_rpt_from_rx); - EPSTAT(cred_rpt_from_other); - EPSTAT(cred_rpt_ep0); - EPSTAT(cred_from_rx); - EPSTAT(cred_from_other); - EPSTAT(cred_from_ep0); - EPSTAT(cred_cosumd); - EPSTAT(cred_retnd); - EPSTAT(rx_pkts); - EPSTAT(rx_lkahds); - EPSTAT(rx_bundl); - EPSTAT(rx_bundle_lkahd); - EPSTAT(rx_bundle_from_hdr); - EPSTAT(rx_alloc_thresh_hit); - EPSTAT(rxalloc_thresh_byte); -#undef EPSTAT - - if (len > buf_len) - len = buf_len; - - ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - return ret_cnt; -} - -static ssize_t ath6kl_endpoint_stats_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath6kl *ar = file->private_data; - struct htc_target *target = ar->htc_target; - int ret, i; - u32 val; - struct htc_endpoint_stats *ep_st; - - ret = kstrtou32_from_user(user_buf, count, 0, &val); - if (ret) - return ret; - if (val == 0) { - for (i = 0; i < ENDPOINT_MAX; i++) { - ep_st = &target->endpoint[i].ep_st; - memset(ep_st, 0, sizeof(*ep_st)); - } - } - - return count; -} - -static const struct file_operations fops_endpoint_stats = { - .open = ath6kl_debugfs_open, - .read = ath6kl_endpoint_stats_read, - .write = ath6kl_endpoint_stats_write, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - static unsigned long ath6kl_get_num_reg(void) { int i; @@ -973,660 +867,6 @@ static const struct file_operations fops_diag_reg_write = { .llseek = default_llseek, }; -int ath6kl_debug_roam_tbl_event(struct ath6kl *ar, const void *buf, - size_t len) -{ - const struct wmi_target_roam_tbl *tbl; - u16 num_entries; - - if (len < sizeof(*tbl)) - return -EINVAL; - - tbl = (const struct wmi_target_roam_tbl *) buf; - num_entries = le16_to_cpu(tbl->num_entries); - if (sizeof(*tbl) + num_entries * sizeof(struct wmi_bss_roam_info) > - len) - return -EINVAL; - - if (ar->debug.roam_tbl == NULL || - ar->debug.roam_tbl_len < (unsigned int) len) { - kfree(ar->debug.roam_tbl); - ar->debug.roam_tbl = kmalloc(len, GFP_ATOMIC); - if (ar->debug.roam_tbl == NULL) - return -ENOMEM; - } - - memcpy(ar->debug.roam_tbl, buf, len); - ar->debug.roam_tbl_len = len; - - if (test_bit(ROAM_TBL_PEND, &ar->flag)) { - clear_bit(ROAM_TBL_PEND, &ar->flag); - wake_up(&ar->event_wq); - } - - return 0; -} - -static ssize_t ath6kl_roam_table_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath6kl *ar = file->private_data; - int ret; - long left; - struct wmi_target_roam_tbl *tbl; - u16 num_entries, i; - char *buf; - unsigned int len, buf_len; - ssize_t ret_cnt; - - if (down_interruptible(&ar->sem)) - return -EBUSY; - - set_bit(ROAM_TBL_PEND, &ar->flag); - - ret = ath6kl_wmi_get_roam_tbl_cmd(ar->wmi); - if (ret) { - up(&ar->sem); - return ret; - } - - left = wait_event_interruptible_timeout( - ar->event_wq, !test_bit(ROAM_TBL_PEND, &ar->flag), WMI_TIMEOUT); - up(&ar->sem); - - if (left <= 0) - return -ETIMEDOUT; - - if (ar->debug.roam_tbl == NULL) - return -ENOMEM; - - tbl = (struct wmi_target_roam_tbl *) ar->debug.roam_tbl; - num_entries = le16_to_cpu(tbl->num_entries); - - buf_len = 100 + num_entries * 100; - buf = kzalloc(buf_len, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - len = 0; - len += scnprintf(buf + len, buf_len - len, - "roam_mode=%u\n\n" - "# roam_util bssid rssi rssidt last_rssi util bias\n", - le16_to_cpu(tbl->roam_mode)); - - for (i = 0; i < num_entries; i++) { - struct wmi_bss_roam_info *info = &tbl->info[i]; - len += scnprintf(buf + len, buf_len - len, - "%d %pM %d %d %d %d %d\n", - a_sle32_to_cpu(info->roam_util), info->bssid, - info->rssi, info->rssidt, info->last_rssi, - info->util, info->bias); - } - - if (len > buf_len) - len = buf_len; - - ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); - - kfree(buf); - return ret_cnt; -} - -static const struct file_operations fops_roam_table = { - .read = ath6kl_roam_table_read, - .open = ath6kl_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -static ssize_t ath6kl_force_roam_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath6kl *ar = file->private_data; - int ret; - char buf[20]; - size_t len; - u8 bssid[ETH_ALEN]; - int i; - int addr[ETH_ALEN]; - - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - buf[len] = '\0'; - - if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", - &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) - != ETH_ALEN) - return -EINVAL; - for (i = 0; i < ETH_ALEN; i++) - bssid[i] = addr[i]; - - ret = ath6kl_wmi_force_roam_cmd(ar->wmi, bssid); - if (ret) - return ret; - - return count; -} - -static const struct file_operations fops_force_roam = { - .write = ath6kl_force_roam_write, - .open = ath6kl_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -static ssize_t ath6kl_roam_mode_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath6kl *ar = file->private_data; - int ret; - char buf[20]; - size_t len; - enum wmi_roam_mode mode; - - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - buf[len] = '\0'; - if (len > 0 && buf[len - 1] == '\n') - buf[len - 1] = '\0'; - - if (strcasecmp(buf, "default") == 0) - mode = WMI_DEFAULT_ROAM_MODE; - else if (strcasecmp(buf, "bssbias") == 0) - mode = WMI_HOST_BIAS_ROAM_MODE; - else if (strcasecmp(buf, "lock") == 0) - mode = WMI_LOCK_BSS_MODE; - else - return -EINVAL; - - ret = ath6kl_wmi_set_roam_mode_cmd(ar->wmi, mode); - if (ret) - return ret; - - return count; -} - -static const struct file_operations fops_roam_mode = { - .write = ath6kl_roam_mode_write, - .open = ath6kl_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive) -{ - ar->debug.keepalive = keepalive; -} - -static ssize_t ath6kl_keepalive_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath6kl *ar = file->private_data; - char buf[16]; - int len; - - len = snprintf(buf, sizeof(buf), "%u\n", ar->debug.keepalive); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static ssize_t ath6kl_keepalive_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath6kl *ar = file->private_data; - int ret; - u8 val; - - ret = kstrtou8_from_user(user_buf, count, 0, &val); - if (ret) - return ret; - - ret = ath6kl_wmi_set_keepalive_cmd(ar->wmi, 0, val); - if (ret) - return ret; - - return count; -} - -static const struct file_operations fops_keepalive = { - .open = ath6kl_debugfs_open, - .read = ath6kl_keepalive_read, - .write = ath6kl_keepalive_write, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, u8 timeout) -{ - ar->debug.disc_timeout = timeout; -} - -static ssize_t ath6kl_disconnect_timeout_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath6kl *ar = file->private_data; - char buf[16]; - int len; - - len = snprintf(buf, sizeof(buf), "%u\n", ar->debug.disc_timeout); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static ssize_t ath6kl_disconnect_timeout_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath6kl *ar = file->private_data; - int ret; - u8 val; - - ret = kstrtou8_from_user(user_buf, count, 0, &val); - if (ret) - return ret; - - ret = ath6kl_wmi_disctimeout_cmd(ar->wmi, 0, val); - if (ret) - return ret; - - return count; -} - -static const struct file_operations fops_disconnect_timeout = { - .open = ath6kl_debugfs_open, - .read = ath6kl_disconnect_timeout_read, - .write = ath6kl_disconnect_timeout_write, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -static ssize_t ath6kl_create_qos_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - - struct ath6kl *ar = file->private_data; - struct ath6kl_vif *vif; - char buf[200]; - ssize_t len; - char *sptr, *token; - struct wmi_create_pstream_cmd pstream; - 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; - buf[len] = '\0'; - sptr = buf; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou8(token, 0, &pstream.user_pri)) - return -EINVAL; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou8(token, 0, &pstream.traffic_direc)) - return -EINVAL; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou8(token, 0, &pstream.traffic_class)) - return -EINVAL; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou8(token, 0, &pstream.traffic_type)) - return -EINVAL; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou8(token, 0, &pstream.voice_psc_cap)) - return -EINVAL; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &val32)) - return -EINVAL; - pstream.min_service_int = cpu_to_le32(val32); - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &val32)) - return -EINVAL; - pstream.max_service_int = cpu_to_le32(val32); - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &val32)) - return -EINVAL; - pstream.inactivity_int = cpu_to_le32(val32); - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &val32)) - return -EINVAL; - pstream.suspension_int = cpu_to_le32(val32); - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &val32)) - return -EINVAL; - pstream.service_start_time = cpu_to_le32(val32); - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou8(token, 0, &pstream.tsid)) - return -EINVAL; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou16(token, 0, &val16)) - return -EINVAL; - pstream.nominal_msdu = cpu_to_le16(val16); - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou16(token, 0, &val16)) - return -EINVAL; - pstream.max_msdu = cpu_to_le16(val16); - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &val32)) - return -EINVAL; - pstream.min_data_rate = cpu_to_le32(val32); - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &val32)) - return -EINVAL; - pstream.mean_data_rate = cpu_to_le32(val32); - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &val32)) - return -EINVAL; - pstream.peak_data_rate = cpu_to_le32(val32); - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &val32)) - return -EINVAL; - pstream.max_burst_size = cpu_to_le32(val32); - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &val32)) - return -EINVAL; - pstream.delay_bound = cpu_to_le32(val32); - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &val32)) - return -EINVAL; - pstream.min_phy_rate = cpu_to_le32(val32); - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &val32)) - return -EINVAL; - pstream.sba = cpu_to_le32(val32); - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &val32)) - return -EINVAL; - pstream.medium_time = cpu_to_le32(val32); - - ath6kl_wmi_create_pstream_cmd(ar->wmi, vif->fw_vif_idx, &pstream); - - return count; -} - -static const struct file_operations fops_create_qos = { - .write = ath6kl_create_qos_write, - .open = ath6kl_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -static ssize_t ath6kl_delete_qos_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - - struct ath6kl *ar = file->private_data; - 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; - buf[len] = '\0'; - sptr = buf; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou8(token, 0, &traffic_class)) - return -EINVAL; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou8(token, 0, &tsid)) - return -EINVAL; - - ath6kl_wmi_delete_pstream_cmd(ar->wmi, vif->fw_vif_idx, - traffic_class, tsid); - - return count; -} - -static const struct file_operations fops_delete_qos = { - .write = ath6kl_delete_qos_write, - .open = ath6kl_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -static ssize_t ath6kl_bgscan_int_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath6kl *ar = file->private_data; - u16 bgscan_int; - char buf[32]; - ssize_t len; - - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - - buf[len] = '\0'; - if (kstrtou16(buf, 0, &bgscan_int)) - return -EINVAL; - - if (bgscan_int == 0) - bgscan_int = 0xffff; - - ath6kl_wmi_scanparams_cmd(ar->wmi, 0, 0, 0, bgscan_int, 0, 0, 0, 3, - 0, 0, 0); - - return count; -} - -static const struct file_operations fops_bgscan_int = { - .write = ath6kl_bgscan_int_write, - .open = ath6kl_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -static ssize_t ath6kl_listen_int_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath6kl *ar = file->private_data; - u16 listen_int_t, listen_int_b; - char buf[32]; - char *sptr, *token; - ssize_t len; - - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - - buf[len] = '\0'; - sptr = buf; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - - if (kstrtou16(token, 0, &listen_int_t)) - return -EINVAL; - - if (kstrtou16(sptr, 0, &listen_int_b)) - return -EINVAL; - - if ((listen_int_t < 15) || (listen_int_t > 5000)) - return -EINVAL; - - if ((listen_int_b < 1) || (listen_int_b > 50)) - return -EINVAL; - - ar->listen_intvl_t = listen_int_t; - ar->listen_intvl_b = listen_int_b; - - ath6kl_wmi_listeninterval_cmd(ar->wmi, 0, ar->listen_intvl_t, - ar->listen_intvl_b); - - return count; -} - -static ssize_t ath6kl_listen_int_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath6kl *ar = file->private_data; - char buf[16]; - int len; - - len = snprintf(buf, sizeof(buf), "%u %u\n", ar->listen_intvl_t, - ar->listen_intvl_b); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static const struct file_operations fops_listen_int = { - .read = ath6kl_listen_int_read, - .write = ath6kl_listen_int_write, - .open = ath6kl_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -static ssize_t ath6kl_power_params_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath6kl *ar = file->private_data; - u8 buf[100]; - unsigned int len = 0; - char *sptr, *token; - u16 idle_period, ps_poll_num, dtim, - tx_wakeup, num_tx; - - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - buf[len] = '\0'; - sptr = buf; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou16(token, 0, &idle_period)) - return -EINVAL; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou16(token, 0, &ps_poll_num)) - return -EINVAL; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou16(token, 0, &dtim)) - return -EINVAL; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou16(token, 0, &tx_wakeup)) - return -EINVAL; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou16(token, 0, &num_tx)) - return -EINVAL; - - ath6kl_wmi_pmparams_cmd(ar->wmi, 0, idle_period, ps_poll_num, - dtim, tx_wakeup, num_tx, 0); - - return count; -} - -static const struct file_operations fops_power_params = { - .write = ath6kl_power_params_write, - .open = ath6kl_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - int ath6kl_debug_init(struct ath6kl *ar) { ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE); @@ -1648,7 +888,7 @@ int ath6kl_debug_init(struct ath6kl *ar) ar->debug.fwlog_mask = 0; ar->debugfs_phy = debugfs_create_dir("ath6kl", - ar->wiphy->debugfsdir); + ar->wdev->wiphy->debugfsdir); if (!ar->debugfs_phy) { vfree(ar->debug.fwlog_buf.buf); kfree(ar->debug.fwlog_tmp); @@ -1661,9 +901,6 @@ int ath6kl_debug_init(struct ath6kl *ar) debugfs_create_file("credit_dist_stats", S_IRUSR, ar->debugfs_phy, ar, &fops_credit_dist_stats); - debugfs_create_file("endpoint_stats", S_IRUSR | S_IWUSR, - ar->debugfs_phy, ar, &fops_endpoint_stats); - debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar, &fops_fwlog); @@ -1685,33 +922,6 @@ int ath6kl_debug_init(struct ath6kl *ar) debugfs_create_file("war_stats", S_IRUSR, ar->debugfs_phy, ar, &fops_war_stats); - debugfs_create_file("roam_table", S_IRUSR, ar->debugfs_phy, ar, - &fops_roam_table); - - debugfs_create_file("force_roam", S_IWUSR, ar->debugfs_phy, ar, - &fops_force_roam); - - debugfs_create_file("roam_mode", S_IWUSR, ar->debugfs_phy, ar, - &fops_roam_mode); - - debugfs_create_file("keepalive", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar, - &fops_keepalive); - - debugfs_create_file("disconnect_timeout", S_IRUSR | S_IWUSR, - ar->debugfs_phy, ar, &fops_disconnect_timeout); - - debugfs_create_file("create_qos", S_IWUSR, ar->debugfs_phy, ar, - &fops_create_qos); - - debugfs_create_file("delete_qos", S_IWUSR, ar->debugfs_phy, ar, - &fops_delete_qos); - - debugfs_create_file("bgscan_interval", S_IWUSR, - ar->debugfs_phy, ar, &fops_bgscan_int); - - debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar, - &fops_power_params); - return 0; } @@ -1719,7 +929,6 @@ void ath6kl_debug_cleanup(struct ath6kl *ar) { vfree(ar->debug.fwlog_buf.buf); kfree(ar->debug.fwlog_tmp); - kfree(ar->debug.roam_tbl); } #endif diff --git a/trunk/drivers/net/wireless/ath/ath6kl/debug.h b/trunk/drivers/net/wireless/ath/ath6kl/debug.h index c24d120615ad..9288a3ce1e39 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/debug.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/debug.h @@ -17,19 +17,19 @@ #ifndef DEBUG_H #define DEBUG_H -#include "hif.h" +#include "htc_hif.h" enum ATH6K_DEBUG_MASK { - ATH6KL_DBG_CREDIT = BIT(0), - /* hole */ + ATH6KL_DBG_WLAN_CONNECT = BIT(0), /* wlan connect */ + ATH6KL_DBG_WLAN_SCAN = BIT(1), /* wlan scan */ ATH6KL_DBG_WLAN_TX = BIT(2), /* wlan tx */ ATH6KL_DBG_WLAN_RX = BIT(3), /* wlan rx */ ATH6KL_DBG_BMI = BIT(4), /* bmi tracing */ - ATH6KL_DBG_HTC = BIT(5), - ATH6KL_DBG_HIF = BIT(6), + ATH6KL_DBG_HTC_SEND = BIT(5), /* htc send */ + ATH6KL_DBG_HTC_RECV = BIT(6), /* htc recv */ ATH6KL_DBG_IRQ = BIT(7), /* interrupt processing */ - /* hole */ - /* hole */ + ATH6KL_DBG_PM = BIT(8), /* power management */ + ATH6KL_DBG_WLAN_NODE = BIT(9), /* general wlan node tracing */ ATH6KL_DBG_WMI = BIT(10), /* wmi tracing */ ATH6KL_DBG_TRC = BIT(11), /* generic func tracing */ ATH6KL_DBG_SCATTER = BIT(12), /* hif scatter tracing */ @@ -40,7 +40,6 @@ enum ATH6K_DEBUG_MASK { ATH6KL_DBG_SDIO_DUMP = BIT(17), ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */ ATH6KL_DBG_WMI_DUMP = BIT(19), - ATH6KL_DBG_SUSPEND = BIT(20), ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ }; @@ -91,10 +90,6 @@ void ath6kl_dump_registers(struct ath6kl_device *dev, void dump_cred_dist_stats(struct htc_target *target); void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len); void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war); -int ath6kl_debug_roam_tbl_event(struct ath6kl *ar, const void *buf, - size_t len); -void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive); -void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, u8 timeout); int ath6kl_debug_init(struct ath6kl *ar); void ath6kl_debug_cleanup(struct ath6kl *ar); @@ -130,21 +125,6 @@ static inline void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war) { } -static inline int ath6kl_debug_roam_tbl_event(struct ath6kl *ar, - const void *buf, size_t len) -{ - return 0; -} - -static inline void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive) -{ -} - -static inline void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, - u8 timeout) -{ -} - static inline int ath6kl_debug_init(struct ath6kl *ar) { return 0; diff --git a/trunk/drivers/net/wireless/ath/ath6kl/hif-ops.h b/trunk/drivers/net/wireless/ath/ath6kl/hif-ops.h index eed22870448b..d6c898f3d0b3 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/hif-ops.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/hif-ops.h @@ -18,16 +18,10 @@ #define HIF_OPS_H #include "hif.h" -#include "debug.h" static inline int hif_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf, u32 len, u32 request) { - ath6kl_dbg(ATH6KL_DBG_HIF, - "hif %s sync addr 0x%x buf 0x%p len %d request 0x%x\n", - (request & HIF_WRITE) ? "write" : "read", - addr, buf, len, request); - return ar->hif_ops->read_write_sync(ar, addr, buf, len, request); } @@ -35,24 +29,16 @@ static inline int hif_write_async(struct ath6kl *ar, u32 address, u8 *buffer, u32 length, u32 request, struct htc_packet *packet) { - ath6kl_dbg(ATH6KL_DBG_HIF, - "hif write async addr 0x%x buf 0x%p len %d request 0x%x\n", - address, buffer, length, request); - return ar->hif_ops->write_async(ar, address, buffer, length, request, packet); } static inline void ath6kl_hif_irq_enable(struct ath6kl *ar) { - ath6kl_dbg(ATH6KL_DBG_HIF, "hif irq enable\n"); - return ar->hif_ops->irq_enable(ar); } static inline void ath6kl_hif_irq_disable(struct ath6kl *ar) { - ath6kl_dbg(ATH6KL_DBG_HIF, "hif irq disable\n"); - return ar->hif_ops->irq_disable(ar); } @@ -83,40 +69,9 @@ static inline void ath6kl_hif_cleanup_scatter(struct ath6kl *ar) return ar->hif_ops->cleanup_scatter(ar); } -static inline int ath6kl_hif_suspend(struct ath6kl *ar, - struct cfg80211_wowlan *wow) +static inline int ath6kl_hif_suspend(struct ath6kl *ar) { - ath6kl_dbg(ATH6KL_DBG_HIF, "hif suspend\n"); - - return ar->hif_ops->suspend(ar, wow); -} - -static inline int ath6kl_hif_resume(struct ath6kl *ar) -{ - ath6kl_dbg(ATH6KL_DBG_HIF, "hif resume\n"); - - return ar->hif_ops->resume(ar); -} - -static inline int ath6kl_hif_power_on(struct ath6kl *ar) -{ - ath6kl_dbg(ATH6KL_DBG_HIF, "hif power on\n"); - - return ar->hif_ops->power_on(ar); -} - -static inline int ath6kl_hif_power_off(struct ath6kl *ar) -{ - ath6kl_dbg(ATH6KL_DBG_HIF, "hif power off\n"); - - return ar->hif_ops->power_off(ar); -} - -static inline void ath6kl_hif_stop(struct ath6kl *ar) -{ - ath6kl_dbg(ATH6KL_DBG_HIF, "hif stop\n"); - - ar->hif_ops->stop(ar); + return ar->hif_ops->suspend(ar); } #endif diff --git a/trunk/drivers/net/wireless/ath/ath6kl/hif.h b/trunk/drivers/net/wireless/ath/ath6kl/hif.h index f2dc3bcdae4a..797e2d1d9bf9 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/hif.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/hif.h @@ -59,18 +59,6 @@ /* mode to enable special 4-bit interrupt assertion without clock */ #define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ (1 << 0) -/* HTC runs over mailbox 0 */ -#define HTC_MAILBOX 0 - -#define ATH6KL_TARGET_DEBUG_INTR_MASK 0x01 - -/* FIXME: are these duplicates with MAX_SCATTER_ values in hif.h? */ -#define ATH6KL_SCATTER_ENTRIES_PER_REQ 16 -#define ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER (16 * 1024) -#define ATH6KL_SCATTER_REQS 4 - -#define ATH6KL_HIF_COMMUNICATION_TIMEOUT 1000 - struct bus_request { struct list_head list; @@ -198,34 +186,6 @@ struct hif_scatter_req { struct hif_scatter_item scat_list[1]; }; -struct ath6kl_irq_proc_registers { - u8 host_int_status; - u8 cpu_int_status; - u8 error_int_status; - u8 counter_int_status; - u8 mbox_frame; - u8 rx_lkahd_valid; - u8 host_int_status2; - u8 gmbox_rx_avail; - __le32 rx_lkahd[2]; - __le32 rx_gmbox_lkahd_alias[2]; -} __packed; - -struct ath6kl_irq_enable_reg { - u8 int_status_en; - u8 cpu_int_status_en; - u8 err_int_status_en; - u8 cntr_int_status_en; -} __packed; - -struct ath6kl_device { - spinlock_t lock; - struct ath6kl_irq_proc_registers irq_proc_reg; - struct ath6kl_irq_enable_reg irq_en_reg; - struct htc_target *htc_cnxt; - struct ath6kl *ar; -}; - struct ath6kl_hif_ops { int (*read_write_sync)(struct ath6kl *ar, u32 addr, u8 *buf, u32 len, u32 request); @@ -242,26 +202,7 @@ struct ath6kl_hif_ops { int (*scat_req_rw) (struct ath6kl *ar, struct hif_scatter_req *scat_req); void (*cleanup_scatter)(struct ath6kl *ar); - int (*suspend)(struct ath6kl *ar, struct cfg80211_wowlan *wow); - int (*resume)(struct ath6kl *ar); - int (*power_on)(struct ath6kl *ar); - int (*power_off)(struct ath6kl *ar); - void (*stop)(struct ath6kl *ar); + int (*suspend)(struct ath6kl *ar); }; -int ath6kl_hif_setup(struct ath6kl_device *dev); -int ath6kl_hif_unmask_intrs(struct ath6kl_device *dev); -int ath6kl_hif_mask_intrs(struct ath6kl_device *dev); -int ath6kl_hif_poll_mboxmsg_rx(struct ath6kl_device *dev, - u32 *lk_ahd, int timeout); -int ath6kl_hif_rx_control(struct ath6kl_device *dev, bool enable_rx); -int ath6kl_hif_disable_intrs(struct ath6kl_device *dev); - -int ath6kl_hif_rw_comp_handler(void *context, int status); -int ath6kl_hif_intr_bh_handler(struct ath6kl *ar); - -/* Scatter Function and Definitions */ -int ath6kl_hif_submit_scat_req(struct ath6kl_device *dev, - struct hif_scatter_req *scat_req, bool read); - #endif diff --git a/trunk/drivers/net/wireless/ath/ath6kl/htc.c b/trunk/drivers/net/wireless/ath/ath6kl/htc.c index f3b63ca25c7e..f88a7c9e4148 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/htc.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/htc.c @@ -15,321 +15,13 @@ */ #include "core.h" -#include "hif.h" +#include "htc_hif.h" #include "debug.h" #include "hif-ops.h" #include #define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask)) -/* Functions for Tx credit handling */ -static void ath6kl_credit_deposit(struct ath6kl_htc_credit_info *cred_info, - struct htc_endpoint_credit_dist *ep_dist, - int credits) -{ - ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit deposit ep %d credits %d\n", - ep_dist->endpoint, credits); - - ep_dist->credits += credits; - ep_dist->cred_assngd += credits; - cred_info->cur_free_credits -= credits; -} - -static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info, - struct list_head *ep_list, - int tot_credits) -{ - struct htc_endpoint_credit_dist *cur_ep_dist; - int count; - - ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit init total %d\n", tot_credits); - - cred_info->cur_free_credits = tot_credits; - cred_info->total_avail_credits = tot_credits; - - list_for_each_entry(cur_ep_dist, ep_list, list) { - if (cur_ep_dist->endpoint == ENDPOINT_0) - continue; - - cur_ep_dist->cred_min = cur_ep_dist->cred_per_msg; - - if (tot_credits > 4) { - if ((cur_ep_dist->svc_id == WMI_DATA_BK_SVC) || - (cur_ep_dist->svc_id == WMI_DATA_BE_SVC)) { - ath6kl_credit_deposit(cred_info, - cur_ep_dist, - cur_ep_dist->cred_min); - cur_ep_dist->dist_flags |= HTC_EP_ACTIVE; - } - } - - if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) { - ath6kl_credit_deposit(cred_info, cur_ep_dist, - cur_ep_dist->cred_min); - /* - * Control service is always marked active, it - * never goes inactive EVER. - */ - cur_ep_dist->dist_flags |= HTC_EP_ACTIVE; - } else if (cur_ep_dist->svc_id == WMI_DATA_BK_SVC) - /* this is the lowest priority data endpoint */ - /* FIXME: this looks fishy, check */ - cred_info->lowestpri_ep_dist = cur_ep_dist->list; - - /* - * Streams have to be created (explicit | implicit) for all - * kinds of traffic. BE endpoints are also inactive in the - * beginning. When BE traffic starts it creates implicit - * streams that redistributes credits. - * - * Note: all other endpoints have minimums set but are - * initially given NO credits. credits will be distributed - * as traffic activity demands - */ - } - - WARN_ON(cred_info->cur_free_credits <= 0); - - list_for_each_entry(cur_ep_dist, ep_list, list) { - if (cur_ep_dist->endpoint == ENDPOINT_0) - continue; - - if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) - cur_ep_dist->cred_norm = cur_ep_dist->cred_per_msg; - else { - /* - * For the remaining data endpoints, we assume that - * each cred_per_msg are the same. We use a simple - * calculation here, we take the remaining credits - * and determine how many max messages this can - * cover and then set each endpoint's normal value - * equal to 3/4 this amount. - */ - count = (cred_info->cur_free_credits / - cur_ep_dist->cred_per_msg) - * cur_ep_dist->cred_per_msg; - count = (count * 3) >> 2; - count = max(count, cur_ep_dist->cred_per_msg); - cur_ep_dist->cred_norm = count; - - } - - ath6kl_dbg(ATH6KL_DBG_CREDIT, - "credit ep %d svc_id %d credits %d per_msg %d norm %d min %d\n", - cur_ep_dist->endpoint, - cur_ep_dist->svc_id, - cur_ep_dist->credits, - cur_ep_dist->cred_per_msg, - cur_ep_dist->cred_norm, - cur_ep_dist->cred_min); - } -} - -/* initialize and setup credit distribution */ -int ath6kl_credit_setup(void *htc_handle, - struct ath6kl_htc_credit_info *cred_info) -{ - u16 servicepriority[5]; - - memset(cred_info, 0, sizeof(struct ath6kl_htc_credit_info)); - - servicepriority[0] = WMI_CONTROL_SVC; /* highest */ - servicepriority[1] = WMI_DATA_VO_SVC; - servicepriority[2] = WMI_DATA_VI_SVC; - servicepriority[3] = WMI_DATA_BE_SVC; - servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */ - - /* set priority list */ - ath6kl_htc_set_credit_dist(htc_handle, cred_info, servicepriority, 5); - - return 0; -} - -/* reduce an ep's credits back to a set limit */ -static void ath6kl_credit_reduce(struct ath6kl_htc_credit_info *cred_info, - struct htc_endpoint_credit_dist *ep_dist, - int limit) -{ - int credits; - - ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit reduce ep %d limit %d\n", - ep_dist->endpoint, limit); - - ep_dist->cred_assngd = limit; - - if (ep_dist->credits <= limit) - return; - - credits = ep_dist->credits - limit; - ep_dist->credits -= credits; - cred_info->cur_free_credits += credits; -} - -static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info, - struct list_head *epdist_list) -{ - struct htc_endpoint_credit_dist *cur_dist_list; - - list_for_each_entry(cur_dist_list, epdist_list, list) { - if (cur_dist_list->endpoint == ENDPOINT_0) - continue; - - if (cur_dist_list->cred_to_dist > 0) { - cur_dist_list->credits += - cur_dist_list->cred_to_dist; - cur_dist_list->cred_to_dist = 0; - if (cur_dist_list->credits > - cur_dist_list->cred_assngd) - ath6kl_credit_reduce(cred_info, - cur_dist_list, - cur_dist_list->cred_assngd); - - if (cur_dist_list->credits > - cur_dist_list->cred_norm) - ath6kl_credit_reduce(cred_info, cur_dist_list, - cur_dist_list->cred_norm); - - if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) { - if (cur_dist_list->txq_depth == 0) - ath6kl_credit_reduce(cred_info, - cur_dist_list, 0); - } - } - } -} - -/* - * HTC has an endpoint that needs credits, ep_dist is the endpoint in - * question. - */ -static void ath6kl_credit_seek(struct ath6kl_htc_credit_info *cred_info, - struct htc_endpoint_credit_dist *ep_dist) -{ - struct htc_endpoint_credit_dist *curdist_list; - int credits = 0; - int need; - - if (ep_dist->svc_id == WMI_CONTROL_SVC) - goto out; - - if ((ep_dist->svc_id == WMI_DATA_VI_SVC) || - (ep_dist->svc_id == WMI_DATA_VO_SVC)) - if ((ep_dist->cred_assngd >= ep_dist->cred_norm)) - goto out; - - /* - * For all other services, we follow a simple algorithm of: - * - * 1. checking the free pool for credits - * 2. checking lower priority endpoints for credits to take - */ - - credits = min(cred_info->cur_free_credits, ep_dist->seek_cred); - - if (credits >= ep_dist->seek_cred) - goto out; - - /* - * We don't have enough in the free pool, try taking away from - * lower priority services The rule for taking away credits: - * - * 1. Only take from lower priority endpoints - * 2. Only take what is allocated above the minimum (never - * starve an endpoint completely) - * 3. Only take what you need. - */ - - list_for_each_entry_reverse(curdist_list, - &cred_info->lowestpri_ep_dist, - list) { - if (curdist_list == ep_dist) - break; - - need = ep_dist->seek_cred - cred_info->cur_free_credits; - - if ((curdist_list->cred_assngd - need) >= - curdist_list->cred_min) { - /* - * The current one has been allocated more than - * it's minimum and it has enough credits assigned - * above it's minimum to fulfill our need try to - * take away just enough to fulfill our need. - */ - ath6kl_credit_reduce(cred_info, curdist_list, - curdist_list->cred_assngd - need); - - if (cred_info->cur_free_credits >= - ep_dist->seek_cred) - break; - } - - if (curdist_list->endpoint == ENDPOINT_0) - break; - } - - credits = min(cred_info->cur_free_credits, ep_dist->seek_cred); - -out: - /* did we find some credits? */ - if (credits) - ath6kl_credit_deposit(cred_info, ep_dist, credits); - - ep_dist->seek_cred = 0; -} - -/* redistribute credits based on activity change */ -static void ath6kl_credit_redistribute(struct ath6kl_htc_credit_info *info, - struct list_head *ep_dist_list) -{ - struct htc_endpoint_credit_dist *curdist_list; - - list_for_each_entry(curdist_list, ep_dist_list, list) { - if (curdist_list->endpoint == ENDPOINT_0) - continue; - - if ((curdist_list->svc_id == WMI_DATA_BK_SVC) || - (curdist_list->svc_id == WMI_DATA_BE_SVC)) - curdist_list->dist_flags |= HTC_EP_ACTIVE; - - if ((curdist_list->svc_id != WMI_CONTROL_SVC) && - !(curdist_list->dist_flags & HTC_EP_ACTIVE)) { - if (curdist_list->txq_depth == 0) - ath6kl_credit_reduce(info, curdist_list, 0); - else - ath6kl_credit_reduce(info, - curdist_list, - curdist_list->cred_min); - } - } -} - -/* - * - * This function is invoked whenever endpoints require credit - * distributions. A lock is held while this function is invoked, this - * function shall NOT block. The ep_dist_list is a list of distribution - * structures in prioritized order as defined by the call to the - * htc_set_credit_dist() api. - */ -static void ath6kl_credit_distribute(struct ath6kl_htc_credit_info *cred_info, - struct list_head *ep_dist_list, - enum htc_credit_dist_reason reason) -{ - switch (reason) { - case HTC_CREDIT_DIST_SEND_COMPLETE: - ath6kl_credit_update(cred_info, ep_dist_list); - break; - case HTC_CREDIT_DIST_ACTIVITY_CHANGE: - ath6kl_credit_redistribute(cred_info, ep_dist_list); - break; - default: - break; - } - - WARN_ON(cred_info->cur_free_credits > cred_info->total_avail_credits); - WARN_ON(cred_info->cur_free_credits < 0); -} - static void ath6kl_htc_tx_buf_align(u8 **buf, unsigned long len) { u8 *align_addr; @@ -410,12 +102,12 @@ static void htc_tx_comp_update(struct htc_target *target, packet->info.tx.cred_used; endpoint->cred_dist.txq_depth = get_queue_depth(&endpoint->txq); - ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx ctxt 0x%p dist 0x%p\n", - target->credit_info, &target->cred_dist_list); + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n", + target->cred_dist_cntxt, &target->cred_dist_list); - ath6kl_credit_distribute(target->credit_info, - &target->cred_dist_list, - HTC_CREDIT_DIST_SEND_COMPLETE); + ath6k_credit_distribute(target->cred_dist_cntxt, + &target->cred_dist_list, + HTC_CREDIT_DIST_SEND_COMPLETE); spin_unlock_bh(&target->tx_lock); } @@ -426,8 +118,8 @@ static void htc_tx_complete(struct htc_endpoint *endpoint, if (list_empty(txq)) return; - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx complete ep %d pkts %d\n", + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, + "send complete ep %d, (%d pkts)\n", endpoint->eid, get_queue_depth(txq)); ath6kl_tx_complete(endpoint->target->dev->ar, txq); @@ -439,9 +131,6 @@ static void htc_tx_comp_handler(struct htc_target *target, struct htc_endpoint *endpoint = &target->endpoint[packet->endpoint]; struct list_head container; - ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx complete seqno %d\n", - packet->info.tx.seqno); - htc_tx_comp_update(target, endpoint, packet); INIT_LIST_HEAD(&container); list_add_tail(&packet->list, &container); @@ -459,8 +148,8 @@ static void htc_async_tx_scat_complete(struct htc_target *target, INIT_LIST_HEAD(&tx_compq); - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx scat complete len %d entries %d\n", + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, + "htc_async_tx_scat_complete total len: %d entries: %d\n", scat_req->len, scat_req->scat_entries); if (scat_req->status) @@ -501,13 +190,16 @@ static int ath6kl_htc_tx_issue(struct htc_target *target, send_len = packet->act_len + HTC_HDR_LENGTH; + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "%s: transmit len : %d (%s)\n", + __func__, send_len, sync ? "sync" : "async"); + padded_len = CALC_TXRX_PADDED_LEN(target, send_len); - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx issue len %d seqno %d padded_len %d mbox 0x%X %s\n", - send_len, packet->info.tx.seqno, padded_len, - target->dev->ar->mbox_info.htc_addr, - sync ? "sync" : "async"); + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, + "DevSendPacket, padded len: %d mbox:0x%X (mode:%s)\n", + padded_len, + target->dev->ar->mbox_info.htc_addr, + sync ? "sync" : "async"); if (sync) { status = hif_read_write_sync(target->dev->ar, @@ -535,7 +227,7 @@ static int htc_check_credits(struct htc_target *target, *req_cred = (len > target->tgt_cred_sz) ? DIV_ROUND_UP(len, target->tgt_cred_sz) : 1; - ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit check need %d got %d\n", + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "creds required:%d got:%d\n", *req_cred, ep->cred_dist.credits); if (ep->cred_dist.credits < *req_cred) { @@ -545,13 +237,16 @@ static int htc_check_credits(struct htc_target *target, /* Seek more credits */ ep->cred_dist.seek_cred = *req_cred - ep->cred_dist.credits; - ath6kl_credit_seek(target->credit_info, &ep->cred_dist); + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n", + target->cred_dist_cntxt, &ep->cred_dist); + + ath6k_seek_credits(target->cred_dist_cntxt, &ep->cred_dist); ep->cred_dist.seek_cred = 0; if (ep->cred_dist.credits < *req_cred) { - ath6kl_dbg(ATH6KL_DBG_CREDIT, - "credit not found for ep %d\n", + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, + "not enough credits for ep %d - leaving packet in queue\n", eid); return -EINVAL; } @@ -565,15 +260,17 @@ static int htc_check_credits(struct htc_target *target, ep->cred_dist.seek_cred = ep->cred_dist.cred_per_msg - ep->cred_dist.credits; - ath6kl_credit_seek(target->credit_info, &ep->cred_dist); + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n", + target->cred_dist_cntxt, &ep->cred_dist); + + ath6k_seek_credits(target->cred_dist_cntxt, &ep->cred_dist); /* see if we were successful in getting more */ if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) { /* tell the target we need credits ASAP! */ *flags |= HTC_FLAGS_NEED_CREDIT_UPDATE; ep->ep_st.cred_low_indicate += 1; - ath6kl_dbg(ATH6KL_DBG_CREDIT, - "credit we need credits asap\n"); + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "host needs credits\n"); } } @@ -598,8 +295,8 @@ static void ath6kl_htc_tx_pkts_get(struct htc_target *target, packet = list_first_entry(&endpoint->txq, struct htc_packet, list); - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx got packet 0x%p queue depth %d\n", + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, + "got head pkt:0x%p , queue depth: %d\n", packet, get_queue_depth(&endpoint->txq)); len = CALC_TXRX_PADDED_LEN(target, @@ -707,9 +404,9 @@ static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target, scat_req->len += len; scat_req->scat_entries++; - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx adding (%d) pkt 0x%p seqno %d len %d remaining %d\n", - i, packet, packet->info.tx.seqno, len, rem_scat); + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, + "%d, adding pkt : 0x%p len:%d (remaining space:%d)\n", + i, packet, len, rem_scat); } /* Roll back scatter setup in case of any failure */ @@ -758,12 +455,12 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, if (!scat_req) { /* no scatter resources */ - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx no more scatter resources\n"); + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, + "no more scatter resources\n"); break; } - ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n", + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "pkts to scatter: %d\n", n_scat); scat_req->len = 0; @@ -782,10 +479,10 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, n_sent_bundle++; tot_pkts_bundle += scat_req->scat_entries; - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx scatter bytes %d entries %d\n", + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, + "send scatter total bytes: %d , entries: %d\n", scat_req->len, scat_req->scat_entries); - ath6kl_hif_submit_scat_req(target->dev, scat_req, false); + ath6kldev_submit_scat_req(target->dev, scat_req, false); if (status) break; @@ -793,8 +490,8 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, *sent_bundle = n_sent_bundle; *n_bundle_pkts = tot_pkts_bundle; - ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx bundle sent %d pkts\n", - n_sent_bundle); + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "%s (sent:%d)\n", + __func__, n_sent_bundle); return; } @@ -813,7 +510,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, if (endpoint->tx_proc_cnt > 1) { endpoint->tx_proc_cnt--; spin_unlock_bh(&target->tx_lock); - ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx busy\n"); + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "htc_try_send (busy)\n"); return; } @@ -891,12 +588,15 @@ static bool ath6kl_htc_tx_try(struct htc_target *target, overflow = true; if (overflow) - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx overflow ep %d depth %d max %d\n", - endpoint->eid, txq_depth, + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, + "ep %d, tx queue will overflow :%d , tx depth:%d, max:%d\n", + endpoint->eid, overflow, txq_depth, endpoint->max_txq_depth); if (overflow && ep_cb.tx_full) { + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, + "indicating overflowed tx packet: 0x%p\n", tx_pkt); + if (ep_cb.tx_full(endpoint->target, tx_pkt) == HTC_SEND_FULL_DROP) { endpoint->ep_st.tx_dropped += 1; @@ -925,12 +625,12 @@ static void htc_chk_ep_txq(struct htc_target *target) * are not modifying any state. */ list_for_each_entry(cred_dist, &target->cred_dist_list, list) { - endpoint = cred_dist->htc_ep; + endpoint = (struct htc_endpoint *)cred_dist->htc_rsvd; spin_lock_bh(&target->tx_lock); if (!list_empty(&endpoint->txq)) { - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc creds ep %d credits %d pkts %d\n", + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, + "ep %d has %d credits and %d packets in tx queue\n", cred_dist->endpoint, endpoint->cred_dist.credits, get_queue_depth(&endpoint->txq)); @@ -1004,13 +704,13 @@ static int htc_setup_tx_complete(struct htc_target *target) } void ath6kl_htc_set_credit_dist(struct htc_target *target, - struct ath6kl_htc_credit_info *credit_info, + struct htc_credit_state_info *cred_dist_cntxt, u16 srvc_pri_order[], int list_len) { struct htc_endpoint *endpoint; int i, ep; - target->credit_info = credit_info; + target->cred_dist_cntxt = cred_dist_cntxt; list_add_tail(&target->endpoint[ENDPOINT_0].cred_dist.list, &target->cred_dist_list); @@ -1036,8 +736,8 @@ int ath6kl_htc_tx(struct htc_target *target, struct htc_packet *packet) struct htc_endpoint *endpoint; struct list_head queue; - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx ep id %d buf 0x%p len %d\n", + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, + "htc_tx: ep id: %d, buf: 0x%p, len: %d\n", packet->endpoint, packet->buf, packet->act_len); if (packet->endpoint >= ENDPOINT_MAX) { @@ -1087,8 +787,8 @@ void ath6kl_htc_flush_txep(struct htc_target *target, list_for_each_entry_safe(packet, tmp_pkt, &discard_q, list) { packet->status = -ECANCELED; list_del(&packet->list); - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx flushing pkt 0x%p len %d ep %d tag 0x%x\n", + ath6kl_dbg(ATH6KL_DBG_TRC, + "flushing tx pkt:0x%p, len:%d, ep:%d tag:0x%X\n", packet, packet->act_len, packet->endpoint, packet->info.tx.tag); @@ -1144,13 +844,12 @@ void ath6kl_htc_indicate_activity_change(struct htc_target *target, endpoint->cred_dist.txq_depth = get_queue_depth(&endpoint->txq); - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx activity ctxt 0x%p dist 0x%p\n", - target->credit_info, &target->cred_dist_list); + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n", + target->cred_dist_cntxt, &target->cred_dist_list); - ath6kl_credit_distribute(target->credit_info, - &target->cred_dist_list, - HTC_CREDIT_DIST_ACTIVITY_CHANGE); + ath6k_credit_distribute(target->cred_dist_cntxt, + &target->cred_dist_list, + HTC_CREDIT_DIST_ACTIVITY_CHANGE); } spin_unlock_bh(&target->tx_lock); @@ -1220,15 +919,15 @@ static int ath6kl_htc_rx_packet(struct htc_target *target, padded_len = CALC_TXRX_PADDED_LEN(target, rx_len); if (padded_len > packet->buf_len) { - ath6kl_err("not enough receive space for packet - padlen %d recvlen %d bufferlen %d\n", + ath6kl_err("not enough receive space for packet - padlen:%d recvlen:%d bufferlen:%d\n", padded_len, rx_len, packet->buf_len); return -ENOMEM; } - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx 0x%p hdr x%x len %d mbox 0x%x\n", + ath6kl_dbg(ATH6KL_DBG_HTC_RECV, + "dev_rx_pkt (0x%p : hdr:0x%X) padded len: %d mbox:0x%X (mode:%s)\n", packet, packet->info.rx.exp_hdr, - padded_len, dev->ar->mbox_info.htc_addr); + padded_len, dev->ar->mbox_info.htc_addr, "sync"); status = hif_read_write_sync(dev->ar, dev->ar->mbox_info.htc_addr, @@ -1438,8 +1137,8 @@ static int ath6kl_htc_rx_alloc(struct htc_target *target, } endpoint->ep_st.rx_bundle_from_hdr += 1; - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx bundle pkts %d\n", + ath6kl_dbg(ATH6KL_DBG_HTC_RECV, + "htc hdr indicates :%d msg can be fetched as a bundle\n", n_msg); } else /* HTC header only indicates 1 message to fetch */ @@ -1492,8 +1191,8 @@ static void htc_ctrl_rx(struct htc_target *context, struct htc_packet *packets) ath6kl_err("htc_ctrl_rx, got message with len:%zu\n", packets->act_len + HTC_HDR_LENGTH); - ath6kl_dbg_dump(ATH6KL_DBG_HTC, - "htc rx unexpected endpoint 0 message", "", + ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, + "Unexpected ENDPOINT 0 Message", "", packets->buf - HTC_HDR_LENGTH, packets->act_len + HTC_HDR_LENGTH); } @@ -1510,6 +1209,9 @@ static void htc_proc_cred_rpt(struct htc_target *target, int tot_credits = 0, i; bool dist = false; + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, + "htc_proc_cred_rpt, credit report entries:%d\n", n_entries); + spin_lock_bh(&target->tx_lock); for (i = 0; i < n_entries; i++, rpt++) { @@ -1521,9 +1223,8 @@ static void htc_proc_cred_rpt(struct htc_target *target, endpoint = &target->endpoint[rpt->eid]; - ath6kl_dbg(ATH6KL_DBG_CREDIT, - "credit report ep %d credits %d\n", - rpt->eid, rpt->credits); + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, " ep %d got %d credits\n", + rpt->eid, rpt->credits); endpoint->ep_st.tx_cred_rpt += 1; endpoint->ep_st.cred_retnd += rpt->credits; @@ -1563,14 +1264,21 @@ static void htc_proc_cred_rpt(struct htc_target *target, tot_credits += rpt->credits; } + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, + "report indicated %d credits to distribute\n", + tot_credits); + if (dist) { /* * This was a credit return based on a completed send * operations note, this is done with the lock held */ - ath6kl_credit_distribute(target->credit_info, - &target->cred_dist_list, - HTC_CREDIT_DIST_SEND_COMPLETE); + ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n", + target->cred_dist_cntxt, &target->cred_dist_list); + + ath6k_credit_distribute(target->cred_dist_cntxt, + &target->cred_dist_list, + HTC_CREDIT_DIST_SEND_COMPLETE); } spin_unlock_bh(&target->tx_lock); @@ -1612,15 +1320,14 @@ static int htc_parse_trailer(struct htc_target *target, if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) && next_lk_ahds) { - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n", + ath6kl_dbg(ATH6KL_DBG_HTC_RECV, + "lk_ahd report found (pre valid:0x%X, post valid:0x%X)\n", lk_ahd->pre_valid, lk_ahd->post_valid); /* look ahead bytes are valid, copy them over */ memcpy((u8 *)&next_lk_ahds[0], lk_ahd->lk_ahd, 4); - ath6kl_dbg_dump(ATH6KL_DBG_HTC, - "htc rx next look ahead", + ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Next Look Ahead", "", next_lk_ahds, 4); *n_lk_ahds = 1; @@ -1639,7 +1346,7 @@ static int htc_parse_trailer(struct htc_target *target, bundle_lkahd_rpt = (struct htc_bundle_lkahd_rpt *) record_buf; - ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx bundle lk_ahd", + ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Bundle lk_ahd", "", record_buf, record->len); for (i = 0; i < len; i++) { @@ -1671,8 +1378,10 @@ static int htc_proc_trailer(struct htc_target *target, u8 *record_buf; u8 *orig_buf; - ath6kl_dbg(ATH6KL_DBG_HTC, "htc rx trailer len %d\n", len); - ath6kl_dbg_dump(ATH6KL_DBG_HTC, NULL, "", buf, len); + ath6kl_dbg(ATH6KL_DBG_HTC_RECV, "+htc_proc_trailer (len:%d)\n", len); + + ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Recv Trailer", "", + buf, len); orig_buf = buf; orig_len = len; @@ -1709,7 +1418,7 @@ static int htc_proc_trailer(struct htc_target *target, } if (status) - ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx bad trailer", + ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "BAD Recv Trailer", "", orig_buf, orig_len); return status; @@ -1727,6 +1436,9 @@ static int ath6kl_htc_rx_process_hdr(struct htc_target *target, if (n_lkahds != NULL) *n_lkahds = 0; + ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "HTC Recv PKT", "htc ", + packet->buf, packet->act_len); + /* * NOTE: we cannot assume the alignment of buf, so we use the safe * macros to retrieve 16 bit fields. @@ -1768,9 +1480,9 @@ static int ath6kl_htc_rx_process_hdr(struct htc_target *target, if (lk_ahd != packet->info.rx.exp_hdr) { ath6kl_err("%s(): lk_ahd mismatch! (pPkt:0x%p flags:0x%X)\n", __func__, packet, packet->info.rx.rx_flags); - ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx expected lk_ahd", + ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Expected Message lk_ahd", "", &packet->info.rx.exp_hdr, 4); - ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx current header", + ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Current Frame Header", "", (u8 *)&lk_ahd, sizeof(lk_ahd)); status = -ENOMEM; goto fail_rx; @@ -1806,8 +1518,15 @@ static int ath6kl_htc_rx_process_hdr(struct htc_target *target, fail_rx: if (status) - ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx bad packet", - "", packet->buf, packet->act_len); + ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "BAD HTC Recv PKT", + "", packet->buf, + packet->act_len < 256 ? packet->act_len : 256); + else { + if (packet->act_len > 0) + ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, + "HTC - Application Msg", "", + packet->buf, packet->act_len); + } return status; } @@ -1815,8 +1534,8 @@ static int ath6kl_htc_rx_process_hdr(struct htc_target *target, static void ath6kl_htc_rx_complete(struct htc_endpoint *endpoint, struct htc_packet *packet) { - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx complete ep %d packet 0x%p\n", + ath6kl_dbg(ATH6KL_DBG_HTC_RECV, + "htc calling ep %d recv callback on packet 0x%p\n", endpoint->eid, packet); endpoint->ep_cb.rx(endpoint->target, packet); } @@ -1852,9 +1571,9 @@ static int ath6kl_htc_rx_bundle(struct htc_target *target, len = 0; - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx bundle depth %d pkts %d\n", - get_queue_depth(rxq), n_scat_pkt); + ath6kl_dbg(ATH6KL_DBG_HTC_RECV, + "%s(): (numpackets: %d , actual : %d)\n", + __func__, get_queue_depth(rxq), n_scat_pkt); scat_req = hif_scatter_req_get(target->dev->ar); @@ -1901,7 +1620,7 @@ static int ath6kl_htc_rx_bundle(struct htc_target *target, scat_req->len = len; scat_req->scat_entries = i; - status = ath6kl_hif_submit_scat_req(target->dev, scat_req, true); + status = ath6kldev_submit_scat_req(target->dev, scat_req, true); if (!status) *n_pkt_fetched = i; @@ -1924,6 +1643,7 @@ static int ath6kl_htc_rx_process_packets(struct htc_target *target, int status = 0; list_for_each_entry_safe(packet, tmp_pkt, comp_pktq, list) { + list_del(&packet->list); ep = &target->endpoint[packet->endpoint]; /* process header for each of the recv packet */ @@ -1932,8 +1652,6 @@ static int ath6kl_htc_rx_process_packets(struct htc_target *target, if (status) return status; - list_del(&packet->list); - if (list_empty(comp_pktq)) { /* * Last packet's more packet flag is set @@ -1968,15 +1686,11 @@ static int ath6kl_htc_rx_fetch(struct htc_target *target, int fetched_pkts; bool part_bundle = false; int status = 0; - struct list_head tmp_rxq; - struct htc_packet *packet, *tmp_pkt; /* now go fetch the list of HTC packets */ while (!list_empty(rx_pktq)) { fetched_pkts = 0; - INIT_LIST_HEAD(&tmp_rxq); - if (target->rx_bndl_enable && (get_queue_depth(rx_pktq) > 1)) { /* * There are enough packets to attempt a @@ -1984,27 +1698,28 @@ static int ath6kl_htc_rx_fetch(struct htc_target *target, * allowed. */ status = ath6kl_htc_rx_bundle(target, rx_pktq, - &tmp_rxq, + comp_pktq, &fetched_pkts, part_bundle); if (status) - goto fail_rx; + return status; if (!list_empty(rx_pktq)) part_bundle = true; - - list_splice_tail_init(&tmp_rxq, comp_pktq); } if (!fetched_pkts) { + struct htc_packet *packet; packet = list_first_entry(rx_pktq, struct htc_packet, list); + list_del(&packet->list); + /* fully synchronous */ packet->completion = NULL; - if (!list_is_singular(rx_pktq)) + if (!list_empty(rx_pktq)) /* * look_aheads in all packet * except the last one in the @@ -2016,42 +1731,18 @@ static int ath6kl_htc_rx_fetch(struct htc_target *target, /* go fetch the packet */ status = ath6kl_htc_rx_packet(target, packet, packet->act_len); - - list_move_tail(&packet->list, &tmp_rxq); - if (status) - goto fail_rx; + return status; - list_splice_tail_init(&tmp_rxq, comp_pktq); + list_add_tail(&packet->list, comp_pktq); } } - return 0; - -fail_rx: - - /* - * Cleanup any packets we allocated but didn't use to - * actually fetch any packets. - */ - - list_for_each_entry_safe(packet, tmp_pkt, rx_pktq, list) { - list_del(&packet->list); - htc_reclaim_rxbuf(target, packet, - &target->endpoint[packet->endpoint]); - } - - list_for_each_entry_safe(packet, tmp_pkt, &tmp_rxq, list) { - list_del(&packet->list); - htc_reclaim_rxbuf(target, packet, - &target->endpoint[packet->endpoint]); - } - return status; } int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target, - u32 msg_look_ahead, int *num_pkts) + u32 msg_look_ahead[], int *num_pkts) { struct htc_packet *packets, *tmp_pkt; struct htc_endpoint *endpoint; @@ -2068,7 +1759,7 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target, * On first entry copy the look_aheads into our temp array for * processing */ - look_aheads[0] = msg_look_ahead; + memcpy(look_aheads, msg_look_ahead, sizeof(look_aheads)); while (true) { @@ -2136,6 +1827,15 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target, if (status) { ath6kl_err("failed to get pending recv messages: %d\n", status); + /* + * Cleanup any packets we allocated but didn't use to + * actually fetch any packets. + */ + list_for_each_entry_safe(packets, tmp_pkt, &rx_pktq, list) { + list_del(&packets->list); + htc_reclaim_rxbuf(target, packets, + &target->endpoint[packets->endpoint]); + } /* cleanup any packets in sync completion queue */ list_for_each_entry_safe(packets, tmp_pkt, &comp_pktq, list) { @@ -2146,7 +1846,7 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target, if (target->htc_flags & HTC_OP_STATE_STOPPING) { ath6kl_warn("host is going to stop blocking receiver for htc_stop\n"); - ath6kl_hif_rx_control(target->dev, false); + ath6kldev_rx_control(target->dev, false); } } @@ -2156,7 +1856,7 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target, */ if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) { ath6kl_warn("host has no rx buffers blocking receiver to prevent overrun\n"); - ath6kl_hif_rx_control(target->dev, false); + ath6kldev_rx_control(target->dev, false); } *num_pkts = n_fetched; @@ -2174,12 +1874,12 @@ static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target) struct htc_frame_hdr *htc_hdr; u32 look_ahead; - if (ath6kl_hif_poll_mboxmsg_rx(target->dev, &look_ahead, + if (ath6kldev_poll_mboxmsg_rx(target->dev, &look_ahead, HTC_TARGET_RESPONSE_TIMEOUT)) return NULL; - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx wait ctrl look_ahead 0x%X\n", look_ahead); + ath6kl_dbg(ATH6KL_DBG_HTC_RECV, + "htc_wait_for_ctrl_msg: look_ahead : 0x%X\n", look_ahead); htc_hdr = (struct htc_frame_hdr *)&look_ahead; @@ -2243,8 +1943,8 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target, depth = get_queue_depth(pkt_queue); - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx add multiple ep id %d cnt %d len %d\n", + ath6kl_dbg(ATH6KL_DBG_HTC_RECV, + "htc_add_rxbuf_multiple: ep id: %d, cnt:%d, len: %d\n", first_pkt->endpoint, depth, first_pkt->buf_len); endpoint = &target->endpoint[first_pkt->endpoint]; @@ -2269,8 +1969,8 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target, /* check if we are blocked waiting for a new buffer */ if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) { if (target->ep_waiting == first_pkt->endpoint) { - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx blocked on ep %d, unblocking\n", + ath6kl_dbg(ATH6KL_DBG_HTC_RECV, + "receiver was blocked on ep:%d, unblocking.\n", target->ep_waiting); target->rx_st_flags &= ~HTC_RECV_WAIT_BUFFERS; target->ep_waiting = ENDPOINT_MAX; @@ -2282,7 +1982,7 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target, if (rx_unblock && !(target->htc_flags & HTC_OP_STATE_STOPPING)) /* TODO : implement a buffer threshold count? */ - ath6kl_hif_rx_control(target->dev, true); + ath6kldev_rx_control(target->dev, true); return status; } @@ -2304,8 +2004,8 @@ void ath6kl_htc_flush_rx_buf(struct htc_target *target) &endpoint->rx_bufq, list) { list_del(&packet->list); spin_unlock_bh(&target->rx_lock); - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx flush pkt 0x%p len %d ep %d\n", + ath6kl_dbg(ATH6KL_DBG_HTC_RECV, + "flushing rx pkt:0x%p, len:%d, ep:%d\n", packet, packet->buf_len, packet->endpoint); dev_kfree_skb(packet->pkt_cntxt); @@ -2328,8 +2028,8 @@ int ath6kl_htc_conn_service(struct htc_target *target, unsigned int max_msg_sz = 0; int status = 0; - ath6kl_dbg(ATH6KL_DBG_HTC, - "htc connect service target 0x%p service id 0x%x\n", + ath6kl_dbg(ATH6KL_DBG_TRC, + "htc_conn_service, target:0x%p service id:0x%X\n", target, conn_req->svc_id); if (conn_req->svc_id == HTC_CTRL_RSVD_SVC) { @@ -2415,7 +2115,7 @@ int ath6kl_htc_conn_service(struct htc_target *target, endpoint->len_max = max_msg_sz; endpoint->ep_cb = conn_req->ep_cb; endpoint->cred_dist.svc_id = conn_req->svc_id; - endpoint->cred_dist.htc_ep = endpoint; + endpoint->cred_dist.htc_rsvd = endpoint; endpoint->cred_dist.endpoint = assigned_ep; endpoint->cred_dist.cred_sz = target->tgt_cred_sz; @@ -2472,7 +2172,6 @@ static void reset_ep_state(struct htc_target *target) } /* reset distribution list */ - /* FIXME: free existing entries */ INIT_LIST_HEAD(&target->cred_dist_list); } @@ -2502,8 +2201,8 @@ static void htc_setup_msg_bndl(struct htc_target *target) target->msg_per_bndl_max = min(target->max_scat_entries, target->msg_per_bndl_max); - ath6kl_dbg(ATH6KL_DBG_BOOT, - "htc bundling allowed msg_per_bndl_max %d\n", + ath6kl_dbg(ATH6KL_DBG_TRC, + "htc bundling allowed. max msg per htc bundle: %d\n", target->msg_per_bndl_max); /* Max rx bundle size is limited by the max tx bundle size */ @@ -2512,7 +2211,7 @@ static void htc_setup_msg_bndl(struct htc_target *target) target->max_tx_bndl_sz = min(HIF_MBOX0_EXT_WIDTH, target->max_xfer_szper_scatreq); - ath6kl_dbg(ATH6KL_DBG_BOOT, "htc max_rx_bndl_sz %d max_tx_bndl_sz %d\n", + ath6kl_dbg(ATH6KL_DBG_ANY, "max recv: %d max send: %d\n", target->max_rx_bndl_sz, target->max_tx_bndl_sz); if (target->max_tx_bndl_sz) @@ -2566,8 +2265,8 @@ int ath6kl_htc_wait_target(struct htc_target *target) target->tgt_creds = le16_to_cpu(rdy_msg->ver2_0_info.cred_cnt); target->tgt_cred_sz = le16_to_cpu(rdy_msg->ver2_0_info.cred_sz); - ath6kl_dbg(ATH6KL_DBG_BOOT, - "htc target ready credits %d size %d\n", + ath6kl_dbg(ATH6KL_DBG_HTC_RECV, + "target ready: credits: %d credit size: %d\n", target->tgt_creds, target->tgt_cred_sz); /* check if this is an extended ready message */ @@ -2581,7 +2280,7 @@ int ath6kl_htc_wait_target(struct htc_target *target) target->msg_per_bndl_max = 0; } - ath6kl_dbg(ATH6KL_DBG_BOOT, "htc using protocol %s (%d)\n", + ath6kl_dbg(ATH6KL_DBG_TRC, "using htc protocol version : %s (%d)\n", (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1", target->htc_tgt_ver); @@ -2601,10 +2300,6 @@ int ath6kl_htc_wait_target(struct htc_target *target) status = ath6kl_htc_conn_service((void *)target, &connect, &resp); if (status) - /* - * FIXME: this call doesn't make sense, the caller should - * call ath6kl_htc_cleanup() when it wants remove htc - */ ath6kl_hif_cleanup_scatter(target->dev->ar); fail_wait_target: @@ -2625,11 +2320,8 @@ int ath6kl_htc_start(struct htc_target *target) struct htc_packet *packet; int status; - memset(&target->dev->irq_proc_reg, 0, - sizeof(target->dev->irq_proc_reg)); - /* Disable interrupts at the chip level */ - ath6kl_hif_disable_intrs(target->dev); + ath6kldev_disable_intrs(target->dev); target->htc_flags = 0; target->rx_st_flags = 0; @@ -2642,8 +2334,8 @@ int ath6kl_htc_start(struct htc_target *target) } /* NOTE: the first entry in the distribution list is ENDPOINT_0 */ - ath6kl_credit_init(target->credit_info, &target->cred_dist_list, - target->tgt_creds); + ath6k_credit_init(target->cred_dist_cntxt, &target->cred_dist_list, + target->tgt_creds); dump_cred_dist_stats(target); @@ -2654,7 +2346,7 @@ int ath6kl_htc_start(struct htc_target *target) return status; /* unmask interrupts */ - status = ath6kl_hif_unmask_intrs(target->dev); + status = ath6kldev_unmask_intrs(target->dev); if (status) ath6kl_htc_stop(target); @@ -2662,44 +2354,6 @@ int ath6kl_htc_start(struct htc_target *target) return status; } -static int ath6kl_htc_reset(struct htc_target *target) -{ - u32 block_size, ctrl_bufsz; - struct htc_packet *packet; - int i; - - reset_ep_state(target); - - block_size = target->dev->ar->mbox_info.block_size; - - ctrl_bufsz = (block_size > HTC_MAX_CTRL_MSG_LEN) ? - (block_size + HTC_HDR_LENGTH) : - (HTC_MAX_CTRL_MSG_LEN + HTC_HDR_LENGTH); - - for (i = 0; i < NUM_CONTROL_BUFFERS; i++) { - packet = kzalloc(sizeof(*packet), GFP_KERNEL); - if (!packet) - return -ENOMEM; - - packet->buf_start = kzalloc(ctrl_bufsz, GFP_KERNEL); - if (!packet->buf_start) { - kfree(packet); - return -ENOMEM; - } - - packet->buf_len = ctrl_bufsz; - if (i < NUM_CONTROL_RX_BUFFERS) { - packet->act_len = 0; - packet->buf = packet->buf_start; - packet->endpoint = ENDPOINT_0; - list_add_tail(&packet->list, &target->free_ctrl_rxbuf); - } else - list_add_tail(&packet->list, &target->free_ctrl_txbuf); - } - - return 0; -} - /* htc_stop: stop interrupt reception, and flush all queued buffers */ void ath6kl_htc_stop(struct htc_target *target) { @@ -2712,19 +2366,21 @@ void ath6kl_htc_stop(struct htc_target *target) * function returns all pending HIF I/O has completed, we can * safely flush the queues. */ - ath6kl_hif_mask_intrs(target->dev); + ath6kldev_mask_intrs(target->dev); ath6kl_htc_flush_txep_all(target); ath6kl_htc_flush_rx_buf(target); - ath6kl_htc_reset(target); + reset_ep_state(target); } void *ath6kl_htc_create(struct ath6kl *ar) { struct htc_target *target = NULL; - int status = 0; + struct htc_packet *packet; + int status = 0, i = 0; + u32 block_size, ctrl_bufsz; target = kzalloc(sizeof(*target), GFP_KERNEL); if (!target) { @@ -2736,7 +2392,7 @@ void *ath6kl_htc_create(struct ath6kl *ar) if (!target->dev) { ath6kl_err("unable to allocate memory\n"); status = -ENOMEM; - goto err_htc_cleanup; + goto fail_create_htc; } spin_lock_init(&target->htc_lock); @@ -2751,20 +2407,49 @@ void *ath6kl_htc_create(struct ath6kl *ar) target->dev->htc_cnxt = target; target->ep_waiting = ENDPOINT_MAX; - status = ath6kl_hif_setup(target->dev); - if (status) - goto err_htc_cleanup; + reset_ep_state(target); + + status = ath6kldev_setup(target->dev); - status = ath6kl_htc_reset(target); if (status) - goto err_htc_cleanup; + goto fail_create_htc; - return target; + block_size = ar->mbox_info.block_size; + + ctrl_bufsz = (block_size > HTC_MAX_CTRL_MSG_LEN) ? + (block_size + HTC_HDR_LENGTH) : + (HTC_MAX_CTRL_MSG_LEN + HTC_HDR_LENGTH); + + for (i = 0; i < NUM_CONTROL_BUFFERS; i++) { + packet = kzalloc(sizeof(*packet), GFP_KERNEL); + if (!packet) + break; -err_htc_cleanup: - ath6kl_htc_cleanup(target); + packet->buf_start = kzalloc(ctrl_bufsz, GFP_KERNEL); + if (!packet->buf_start) { + kfree(packet); + break; + } - return NULL; + packet->buf_len = ctrl_bufsz; + if (i < NUM_CONTROL_RX_BUFFERS) { + packet->act_len = 0; + packet->buf = packet->buf_start; + packet->endpoint = ENDPOINT_0; + list_add_tail(&packet->list, &target->free_ctrl_rxbuf); + } else + list_add_tail(&packet->list, &target->free_ctrl_txbuf); + } + +fail_create_htc: + if (i != NUM_CONTROL_BUFFERS || status) { + if (target) { + ath6kl_htc_cleanup(target); + target = NULL; + } + } + + return target; } /* cleanup the HTC instance */ diff --git a/trunk/drivers/net/wireless/ath/ath6kl/htc.h b/trunk/drivers/net/wireless/ath/ath6kl/htc.h index 57672e1ed1a6..8ce0c2c07ded 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/htc.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/htc.h @@ -393,7 +393,7 @@ struct htc_endpoint_credit_dist { int cred_per_msg; /* reserved for HTC use */ - struct htc_endpoint *htc_ep; + void *htc_rsvd; /* * current depth of TX queue , i.e. messages waiting for credits @@ -414,11 +414,9 @@ enum htc_credit_dist_reason { HTC_CREDIT_DIST_SEEK_CREDITS, }; -struct ath6kl_htc_credit_info { +struct htc_credit_state_info { int total_avail_credits; int cur_free_credits; - - /* list of lowest priority endpoints */ struct list_head lowestpri_ep_dist; }; @@ -510,13 +508,10 @@ struct ath6kl_device; /* our HTC target state */ struct htc_target { struct htc_endpoint endpoint[ENDPOINT_MAX]; - - /* contains struct htc_endpoint_credit_dist */ struct list_head cred_dist_list; - struct list_head free_ctrl_txbuf; struct list_head free_ctrl_rxbuf; - struct ath6kl_htc_credit_info *credit_info; + struct htc_credit_state_info *cred_dist_cntxt; int tgt_creds; unsigned int tgt_cred_sz; spinlock_t htc_lock; @@ -547,7 +542,7 @@ struct htc_target { void *ath6kl_htc_create(struct ath6kl *ar); void ath6kl_htc_set_credit_dist(struct htc_target *target, - struct ath6kl_htc_credit_info *cred_info, + struct htc_credit_state_info *cred_info, u16 svc_pri_order[], int len); int ath6kl_htc_wait_target(struct htc_target *target); int ath6kl_htc_start(struct htc_target *target); @@ -568,10 +563,7 @@ int ath6kl_htc_get_rxbuf_num(struct htc_target *target, int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target, struct list_head *pktq); int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target, - u32 msg_look_ahead, int *n_pkts); - -int ath6kl_credit_setup(void *htc_handle, - struct ath6kl_htc_credit_info *cred_info); + u32 msg_look_ahead[], int *n_pkts); static inline void set_htc_pkt_info(struct htc_packet *packet, void *context, u8 *buf, unsigned int len, diff --git a/trunk/drivers/net/wireless/ath/ath6kl/hif.c b/trunk/drivers/net/wireless/ath/ath6kl/htc_hif.c similarity index 80% rename from trunk/drivers/net/wireless/ath/ath6kl/hif.c rename to trunk/drivers/net/wireless/ath/ath6kl/htc_hif.c index e57da35e59fa..86b1cc7409c2 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/hif.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/htc_hif.c @@ -13,19 +13,18 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "hif.h" #include "core.h" #include "target.h" #include "hif-ops.h" +#include "htc_hif.h" #include "debug.h" #define MAILBOX_FOR_BLOCK_SIZE 1 #define ATH6KL_TIME_QUANTUM 10 /* in ms */ -static int ath6kl_hif_cp_scat_dma_buf(struct hif_scatter_req *req, - bool from_dma) +static int ath6kldev_cp_scat_dma_buf(struct hif_scatter_req *req, bool from_dma) { u8 *buf; int i; @@ -47,11 +46,12 @@ static int ath6kl_hif_cp_scat_dma_buf(struct hif_scatter_req *req, return 0; } -int ath6kl_hif_rw_comp_handler(void *context, int status) +int ath6kldev_rw_comp_handler(void *context, int status) { struct htc_packet *packet = context; - ath6kl_dbg(ATH6KL_DBG_HIF, "hif rw completion pkt 0x%p status %d\n", + ath6kl_dbg(ATH6KL_DBG_HTC_RECV, + "ath6kldev_rw_comp_handler (pkt:0x%p , status: %d\n", packet, status); packet->status = status; @@ -59,83 +59,30 @@ int ath6kl_hif_rw_comp_handler(void *context, int status) return 0; } -#define REG_DUMP_COUNT_AR6003 60 -#define REGISTER_DUMP_LEN_MAX 60 -static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar) -{ - __le32 regdump_val[REGISTER_DUMP_LEN_MAX]; - u32 i, address, regdump_addr = 0; - int ret; - - if (ar->target_type != TARGET_TYPE_AR6003) - return; - - /* the reg dump pointer is copied to the host interest area */ - address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state)); - address = TARG_VTOP(ar->target_type, address); - - /* read RAM location through diagnostic window */ - ret = ath6kl_diag_read32(ar, address, ®dump_addr); - - if (ret || !regdump_addr) { - ath6kl_warn("failed to get ptr to register dump area: %d\n", - ret); - return; - } - - ath6kl_dbg(ATH6KL_DBG_IRQ, "register dump data address 0x%x\n", - regdump_addr); - regdump_addr = TARG_VTOP(ar->target_type, regdump_addr); - - /* fetch register dump data */ - ret = ath6kl_diag_read(ar, regdump_addr, (u8 *)®dump_val[0], - REG_DUMP_COUNT_AR6003 * (sizeof(u32))); - if (ret) { - ath6kl_warn("failed to get register dump: %d\n", ret); - return; - } - - ath6kl_info("crash dump:\n"); - ath6kl_info("hw 0x%x fw %s\n", ar->wiphy->hw_version, - ar->wiphy->fw_version); - - BUILD_BUG_ON(REG_DUMP_COUNT_AR6003 % 4); - - for (i = 0; i < REG_DUMP_COUNT_AR6003 / 4; i++) { - ath6kl_info("%d: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n", - 4 * i, - le32_to_cpu(regdump_val[i]), - le32_to_cpu(regdump_val[i + 1]), - le32_to_cpu(regdump_val[i + 2]), - le32_to_cpu(regdump_val[i + 3])); - } - -} - -static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev) +static int ath6kldev_proc_dbg_intr(struct ath6kl_device *dev) { u32 dummy; - int ret; + int status; + + ath6kl_err("target debug interrupt\n"); - ath6kl_warn("firmware crashed\n"); + ath6kl_target_failure(dev->ar); /* * read counter to clear the interrupt, the debug error interrupt is * counter 0. */ - ret = hif_read_write_sync(dev->ar, COUNT_DEC_ADDRESS, + status = hif_read_write_sync(dev->ar, COUNT_DEC_ADDRESS, (u8 *)&dummy, 4, HIF_RD_SYNC_BYTE_INC); - if (ret) - ath6kl_warn("Failed to clear debug interrupt: %d\n", ret); - - ath6kl_hif_dump_fw_crash(dev->ar); + if (status) + WARN_ON(1); - return ret; + return status; } /* mailbox recv message polling */ -int ath6kl_hif_poll_mboxmsg_rx(struct ath6kl_device *dev, u32 *lk_ahd, +int ath6kldev_poll_mboxmsg_rx(struct ath6kl_device *dev, u32 *lk_ahd, int timeout) { struct ath6kl_irq_proc_registers *rg; @@ -171,7 +118,7 @@ int ath6kl_hif_poll_mboxmsg_rx(struct ath6kl_device *dev, u32 *lk_ahd, /* delay a little */ mdelay(ATH6KL_TIME_QUANTUM); - ath6kl_dbg(ATH6KL_DBG_HIF, "hif retry mbox poll try %d\n", i); + ath6kl_dbg(ATH6KL_DBG_HTC_RECV, "retry mbox poll : %d\n", i); } if (i == 0) { @@ -184,7 +131,7 @@ int ath6kl_hif_poll_mboxmsg_rx(struct ath6kl_device *dev, u32 *lk_ahd, * Target failure handler will be called in case of * an assert. */ - ath6kl_hif_proc_dbg_intr(dev); + ath6kldev_proc_dbg_intr(dev); } return status; @@ -194,14 +141,11 @@ int ath6kl_hif_poll_mboxmsg_rx(struct ath6kl_device *dev, u32 *lk_ahd, * Disable packet reception (used in case the host runs out of buffers) * using the interrupt enable registers through the host I/F */ -int ath6kl_hif_rx_control(struct ath6kl_device *dev, bool enable_rx) +int ath6kldev_rx_control(struct ath6kl_device *dev, bool enable_rx) { struct ath6kl_irq_enable_reg regs; int status = 0; - ath6kl_dbg(ATH6KL_DBG_HIF, "hif rx %s\n", - enable_rx ? "enable" : "disable"); - /* take the lock to protect interrupt enable shadows */ spin_lock_bh(&dev->lock); @@ -224,7 +168,7 @@ int ath6kl_hif_rx_control(struct ath6kl_device *dev, bool enable_rx) return status; } -int ath6kl_hif_submit_scat_req(struct ath6kl_device *dev, +int ath6kldev_submit_scat_req(struct ath6kl_device *dev, struct hif_scatter_req *scat_req, bool read) { int status = 0; @@ -241,14 +185,14 @@ int ath6kl_hif_submit_scat_req(struct ath6kl_device *dev, dev->ar->mbox_info.htc_addr; } - ath6kl_dbg(ATH6KL_DBG_HIF, - "hif submit scatter request entries %d len %d mbox 0x%x %s %s\n", + ath6kl_dbg((ATH6KL_DBG_HTC_RECV | ATH6KL_DBG_HTC_SEND), + "ath6kldev_submit_scat_req, entries: %d, total len: %d mbox:0x%X (mode: %s : %s)\n", scat_req->scat_entries, scat_req->len, scat_req->addr, !read ? "async" : "sync", (read) ? "rd" : "wr"); if (!read && scat_req->virt_scat) { - status = ath6kl_hif_cp_scat_dma_buf(scat_req, false); + status = ath6kldev_cp_scat_dma_buf(scat_req, false); if (status) { scat_req->status = status; scat_req->complete(dev->ar->htc_target, scat_req); @@ -263,13 +207,13 @@ int ath6kl_hif_submit_scat_req(struct ath6kl_device *dev, scat_req->status = status; if (!status && scat_req->virt_scat) scat_req->status = - ath6kl_hif_cp_scat_dma_buf(scat_req, true); + ath6kldev_cp_scat_dma_buf(scat_req, true); } return status; } -static int ath6kl_hif_proc_counter_intr(struct ath6kl_device *dev) +static int ath6kldev_proc_counter_intr(struct ath6kl_device *dev) { u8 counter_int_status; @@ -288,12 +232,12 @@ static int ath6kl_hif_proc_counter_intr(struct ath6kl_device *dev) * the debug assertion counter interrupt. */ if (counter_int_status & ATH6KL_TARGET_DEBUG_INTR_MASK) - return ath6kl_hif_proc_dbg_intr(dev); + return ath6kldev_proc_dbg_intr(dev); return 0; } -static int ath6kl_hif_proc_err_intr(struct ath6kl_device *dev) +static int ath6kldev_proc_err_intr(struct ath6kl_device *dev) { int status; u8 error_int_status; @@ -338,7 +282,7 @@ static int ath6kl_hif_proc_err_intr(struct ath6kl_device *dev) return status; } -static int ath6kl_hif_proc_cpu_intr(struct ath6kl_device *dev) +static int ath6kldev_proc_cpu_intr(struct ath6kl_device *dev) { int status; u8 cpu_int_status; @@ -473,7 +417,7 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done) * we rapidly pull packets. */ status = ath6kl_htc_rxmsg_pending_handler(dev->htc_cnxt, - lk_ahd, &fetched); + &lk_ahd, &fetched); if (status) goto out; @@ -492,21 +436,21 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done) if (MS(HOST_INT_STATUS_CPU, host_int_status)) { /* CPU Interrupt */ - status = ath6kl_hif_proc_cpu_intr(dev); + status = ath6kldev_proc_cpu_intr(dev); if (status) goto out; } if (MS(HOST_INT_STATUS_ERROR, host_int_status)) { /* Error Interrupt */ - status = ath6kl_hif_proc_err_intr(dev); + status = ath6kldev_proc_err_intr(dev); if (status) goto out; } if (MS(HOST_INT_STATUS_COUNTER, host_int_status)) /* Counter Interrupt */ - status = ath6kl_hif_proc_counter_intr(dev); + status = ath6kldev_proc_counter_intr(dev); out: /* @@ -535,10 +479,9 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done) } /* interrupt handler, kicks off all interrupt processing */ -int ath6kl_hif_intr_bh_handler(struct ath6kl *ar) +int ath6kldev_intr_bh_handler(struct ath6kl *ar) { struct ath6kl_device *dev = ar->htc_target->dev; - unsigned long timeout; int status = 0; bool done = false; @@ -552,8 +495,7 @@ int ath6kl_hif_intr_bh_handler(struct ath6kl *ar) * IRQ processing is synchronous, interrupt status registers can be * re-read. */ - timeout = jiffies + msecs_to_jiffies(ATH6KL_HIF_COMMUNICATION_TIMEOUT); - while (time_before(jiffies, timeout) && !done) { + while (!done) { status = proc_pending_irqs(dev, &done); if (status) break; @@ -562,7 +504,7 @@ int ath6kl_hif_intr_bh_handler(struct ath6kl *ar) return status; } -static int ath6kl_hif_enable_intrs(struct ath6kl_device *dev) +static int ath6kldev_enable_intrs(struct ath6kl_device *dev) { struct ath6kl_irq_enable_reg regs; int status; @@ -610,7 +552,7 @@ static int ath6kl_hif_enable_intrs(struct ath6kl_device *dev) return status; } -int ath6kl_hif_disable_intrs(struct ath6kl_device *dev) +int ath6kldev_disable_intrs(struct ath6kl_device *dev) { struct ath6kl_irq_enable_reg regs; @@ -629,7 +571,7 @@ int ath6kl_hif_disable_intrs(struct ath6kl_device *dev) } /* enable device interrupts */ -int ath6kl_hif_unmask_intrs(struct ath6kl_device *dev) +int ath6kldev_unmask_intrs(struct ath6kl_device *dev) { int status = 0; @@ -641,29 +583,29 @@ int ath6kl_hif_unmask_intrs(struct ath6kl_device *dev) * target "soft" resets. The ATH6KL interrupt enables reset back to an * "enabled" state when this happens. */ - ath6kl_hif_disable_intrs(dev); + ath6kldev_disable_intrs(dev); /* unmask the host controller interrupts */ ath6kl_hif_irq_enable(dev->ar); - status = ath6kl_hif_enable_intrs(dev); + status = ath6kldev_enable_intrs(dev); return status; } /* disable all device interrupts */ -int ath6kl_hif_mask_intrs(struct ath6kl_device *dev) +int ath6kldev_mask_intrs(struct ath6kl_device *dev) { /* * Mask the interrupt at the HIF layer to avoid any stray interrupt * taken while we zero out our shadow registers in - * ath6kl_hif_disable_intrs(). + * ath6kldev_disable_intrs(). */ ath6kl_hif_irq_disable(dev->ar); - return ath6kl_hif_disable_intrs(dev); + return ath6kldev_disable_intrs(dev); } -int ath6kl_hif_setup(struct ath6kl_device *dev) +int ath6kldev_setup(struct ath6kl_device *dev) { int status = 0; @@ -679,17 +621,19 @@ int ath6kl_hif_setup(struct ath6kl_device *dev) /* must be a power of 2 */ if ((dev->htc_cnxt->block_sz & (dev->htc_cnxt->block_sz - 1)) != 0) { WARN_ON(1); - status = -EINVAL; goto fail_setup; } /* assemble mask, used for padding to a block */ dev->htc_cnxt->block_mask = dev->htc_cnxt->block_sz - 1; - ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n", + ath6kl_dbg(ATH6KL_DBG_TRC, "block size: %d, mbox addr:0x%X\n", dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr); - status = ath6kl_hif_disable_intrs(dev); + ath6kl_dbg(ATH6KL_DBG_TRC, + "hif interrupt processing is sync only\n"); + + status = ath6kldev_disable_intrs(dev); fail_setup: return status; diff --git a/trunk/drivers/net/wireless/ath/ath6kl/htc_hif.h b/trunk/drivers/net/wireless/ath/ath6kl/htc_hif.h new file mode 100644 index 000000000000..171ad63d89b0 --- /dev/null +++ b/trunk/drivers/net/wireless/ath/ath6kl/htc_hif.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2007-2011 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HTC_HIF_H +#define HTC_HIF_H + +#include "htc.h" +#include "hif.h" + +#define ATH6KL_MAILBOXES 4 + +/* HTC runs over mailbox 0 */ +#define HTC_MAILBOX 0 + +#define ATH6KL_TARGET_DEBUG_INTR_MASK 0x01 + +#define OTHER_INTS_ENABLED (INT_STATUS_ENABLE_ERROR_MASK | \ + INT_STATUS_ENABLE_CPU_MASK | \ + INT_STATUS_ENABLE_COUNTER_MASK) + +#define ATH6KL_REG_IO_BUFFER_SIZE 32 +#define ATH6KL_MAX_REG_IO_BUFFERS 8 +#define ATH6KL_SCATTER_ENTRIES_PER_REQ 16 +#define ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER (16 * 1024) +#define ATH6KL_SCATTER_REQS 4 + +#ifndef A_CACHE_LINE_PAD +#define A_CACHE_LINE_PAD 128 +#endif +#define ATH6KL_MIN_SCATTER_ENTRIES_PER_REQ 2 +#define ATH6KL_MIN_TRANSFER_SIZE_PER_SCATTER (4 * 1024) + +struct ath6kl_irq_proc_registers { + u8 host_int_status; + u8 cpu_int_status; + u8 error_int_status; + u8 counter_int_status; + u8 mbox_frame; + u8 rx_lkahd_valid; + u8 host_int_status2; + u8 gmbox_rx_avail; + __le32 rx_lkahd[2]; + __le32 rx_gmbox_lkahd_alias[2]; +} __packed; + +struct ath6kl_irq_enable_reg { + u8 int_status_en; + u8 cpu_int_status_en; + u8 err_int_status_en; + u8 cntr_int_status_en; +} __packed; + +struct ath6kl_device { + spinlock_t lock; + u8 pad1[A_CACHE_LINE_PAD]; + struct ath6kl_irq_proc_registers irq_proc_reg; + u8 pad2[A_CACHE_LINE_PAD]; + struct ath6kl_irq_enable_reg irq_en_reg; + u8 pad3[A_CACHE_LINE_PAD]; + struct htc_target *htc_cnxt; + struct ath6kl *ar; +}; + +int ath6kldev_setup(struct ath6kl_device *dev); +int ath6kldev_unmask_intrs(struct ath6kl_device *dev); +int ath6kldev_mask_intrs(struct ath6kl_device *dev); +int ath6kldev_poll_mboxmsg_rx(struct ath6kl_device *dev, + u32 *lk_ahd, int timeout); +int ath6kldev_rx_control(struct ath6kl_device *dev, bool enable_rx); +int ath6kldev_disable_intrs(struct ath6kl_device *dev); + +int ath6kldev_rw_comp_handler(void *context, int status); +int ath6kldev_intr_bh_handler(struct ath6kl *ar); + +/* Scatter Function and Definitions */ +int ath6kldev_submit_scat_req(struct ath6kl_device *dev, + struct hif_scatter_req *scat_req, bool read); + +#endif /*ATH6KL_H_ */ diff --git a/trunk/drivers/net/wireless/ath/ath6kl/init.c b/trunk/drivers/net/wireless/ath/ath6kl/init.c index 57529acb9144..81e0031012ca 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/init.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/init.c @@ -16,7 +16,6 @@ */ #include -#include #include #include #include "core.h" @@ -27,11 +26,9 @@ unsigned int debug_mask; static unsigned int testmode; -static bool suspend_cutpower; module_param(debug_mask, uint, 0644); module_param(testmode, uint, 0644); -module_param(suspend_cutpower, bool, 0444); /* * Include definitions here that can be used to tune the WLAN module @@ -76,21 +73,37 @@ struct sk_buff *ath6kl_buf_alloc(int size) return skb; } -void ath6kl_init_profile_info(struct ath6kl_vif *vif) +void ath6kl_init_profile_info(struct ath6kl *ar) { - 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(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; + 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; + 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)); + ar->bss_ch = 0; + 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) @@ -107,7 +120,7 @@ static int ath6kl_set_host_app_area(struct ath6kl *ar) return -EIO; address = TARG_VTOP(ar->target_type, data); - host_app_area.wmi_protocol_ver = cpu_to_le32(WMI_PROTOCOL_VERSION); + host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION; if (ath6kl_diag_write(ar, address, (u8 *) &host_app_area, sizeof(struct host_app_area))) return -EIO; @@ -245,12 +258,40 @@ static int ath6kl_init_service_ep(struct ath6kl *ar) return 0; } -void ath6kl_init_control_info(struct ath6kl_vif *vif) +static void ath6kl_init_control_info(struct ath6kl *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; + 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); } /* @@ -300,7 +341,62 @@ static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val, return status; } -static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) +#define REG_DUMP_COUNT_AR6003 60 +#define REGISTER_DUMP_LEN_MAX 60 + +static void ath6kl_dump_target_assert_info(struct ath6kl *ar) +{ + u32 address; + u32 regdump_loc = 0; + int status; + u32 regdump_val[REGISTER_DUMP_LEN_MAX]; + u32 i; + + if (ar->target_type != TARGET_TYPE_AR6003) + return; + + /* the reg dump pointer is copied to the host interest area */ + address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state)); + address = TARG_VTOP(ar->target_type, address); + + /* read RAM location through diagnostic window */ + status = ath6kl_diag_read32(ar, address, ®dump_loc); + + if (status || !regdump_loc) { + ath6kl_err("failed to get ptr to register dump area\n"); + return; + } + + ath6kl_dbg(ATH6KL_DBG_TRC, "location of register dump data: 0x%X\n", + regdump_loc); + regdump_loc = TARG_VTOP(ar->target_type, regdump_loc); + + /* fetch register dump data */ + status = ath6kl_diag_read(ar, regdump_loc, (u8 *)®dump_val[0], + REG_DUMP_COUNT_AR6003 * (sizeof(u32))); + + if (status) { + ath6kl_err("failed to get register dump\n"); + return; + } + ath6kl_dbg(ATH6KL_DBG_TRC, "Register Dump:\n"); + + for (i = 0; i < REG_DUMP_COUNT_AR6003; i++) + ath6kl_dbg(ATH6KL_DBG_TRC, " %d : 0x%8.8X\n", + i, regdump_val[i]); + +} + +void ath6kl_target_failure(struct ath6kl *ar) +{ + ath6kl_err("target asserted\n"); + + /* try dumping target assertion information (if any) */ + ath6kl_dump_target_assert_info(ar); + +} + +static int ath6kl_target_config_wlan_params(struct ath6kl *ar) { int status = 0; int ret; @@ -310,50 +406,46 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) * default values. Required if checksum offload is needed. Set * RxMetaVersion to 2. */ - if (ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, idx, + if (ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, 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, idx, 0, 1, 0, 0, 1, + if ((ath6kl_wmi_pmparams_cmd(ar->wmi, 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, idx, 0, + if ((ath6kl_wmi_set_lpreamble_cmd(ar->wmi, 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, idx, + if (ath6kl_wmi_set_keepalive_cmd(ar->wmi, WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) { ath6kl_err("unable to set keep alive interval\n"); status = -EIO; } - if (ath6kl_wmi_disctimeout_cmd(ar->wmi, idx, + if (ath6kl_wmi_disctimeout_cmd(ar->wmi, 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, idx, WMI_TXOP_DISABLED)) { + if (ath6kl_wmi_set_wmm_txop(ar->wmi, 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, idx, + ret = ath6kl_wmi_info_req_cmd(ar->wmi, P2P_FLAG_CAPABILITIES_REQ | P2P_FLAG_MACADDR_REQ | P2P_FLAG_HMODEL_REQ); @@ -365,13 +457,9 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) } } - /* - * 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, idx, true); + ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, true); if (ret) { ath6kl_dbg(ATH6KL_DBG_TRC, "failed to enable Probe " "Request reporting (%d)\n", ret); @@ -384,44 +472,13 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) int ath6kl_configure_target(struct ath6kl *ar) { u32 param, ram_reserved_size; - u8 fw_iftype, fw_mode = 0, fw_submode = 0; - int i; + u8 fw_iftype; - /* - * 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; - - for (i = 0; i < MAX_NUM_VIF; i++) - fw_mode |= fw_iftype << (i * HI_OPTION_FW_MODE_BITS); - - /* - * By default, submodes : - * vif[0] - AP/STA/IBSS - * vif[1] - "P2P dev"/"P2P GO"/"P2P Client" - * vif[2] - "P2P dev"/"P2P GO"/"P2P Client" - */ - - 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 - * support is enabled. - */ - if (ar->p2p) - fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV; + fw_iftype = ath6kl_get_fw_iftype(ar); + if (fw_iftype == 0xff) + return -EINVAL; + /* Tell target which HTC version it is used*/ param = HTC_PROTOCOL_VERSION; if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar, @@ -442,10 +499,12 @@ int ath6kl_configure_target(struct ath6kl *ar) return -EIO; } - 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 |= (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 |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT); param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT); @@ -494,34 +553,68 @@ int ath6kl_configure_target(struct ath6kl *ar) return 0; } -void ath6kl_core_free(struct ath6kl *ar) +struct ath6kl *ath6kl_core_alloc(struct device *sdev) { - wiphy_free(ar->wiphy); -} + struct net_device *dev; + struct ath6kl *ar; + struct wireless_dev *wdev; -void ath6kl_core_cleanup(struct ath6kl *ar) -{ - ath6kl_hif_power_off(ar); + wdev = ath6kl_cfg80211_init(sdev); + if (!wdev) { + ath6kl_err("ath6kl_cfg80211_init failed\n"); + return NULL; + } - destroy_workqueue(ar->ath6kl_wq); + ar = wdev_priv(wdev); + ar->dev = sdev; + ar->wdev = wdev; + wdev->iftype = NL80211_IFTYPE_STATION; - if (ar->htc_target) - ath6kl_htc_cleanup(ar->htc_target); + if (ath6kl_debug_init(ar)) { + ath6kl_err("Failed to initialize debugfs\n"); + ath6kl_cfg80211_deinit(ar); + return NULL; + } - ath6kl_cookie_cleanup(ar); + 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; + } - ath6kl_cleanup_amsdu_rxbufs(ar); + dev->ieee80211_ptr = wdev; + SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy)); + wdev->netdev = dev; + ar->sme_state = SME_DISCONNECTED; - ath6kl_bmi_cleanup(ar); + init_netdev(dev); - ath6kl_debug_cleanup(ar); + ar->net_dev = dev; + set_bit(WLAN_ENABLED, &ar->flag); - kfree(ar->fw_board); - kfree(ar->fw_otp); - kfree(ar->fw); - kfree(ar->fw_patch); + ar->wlan_pwr_state = WLAN_POWER_STATE_ON; + + spin_lock_init(&ar->lock); - ath6kl_deinit_ieee80211_hw(ar); + 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; +} + +int ath6kl_unavail_ev(struct ath6kl *ar) +{ + ath6kl_destroy(ar->net_dev, 1); + + return 0; } /* firmware upload */ @@ -1089,7 +1182,6 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) static int ath6kl_upload_otp(struct ath6kl *ar) { u32 address, param; - bool from_hw = false; int ret; if (WARN_ON(ar->fw_otp == NULL)) @@ -1118,20 +1210,15 @@ static int ath6kl_upload_otp(struct ath6kl *ar) return ret; } - if (ar->hw.app_start_override_addr == 0) { - ar->hw.app_start_override_addr = address; - from_hw = true; - } + ar->hw.app_start_override_addr = address; - ath6kl_dbg(ATH6KL_DBG_BOOT, "app_start_override_addr%s 0x%x\n", - from_hw ? " (from hw)" : "", + ath6kl_dbg(ATH6KL_DBG_BOOT, "app_start_override_addr 0x%x\n", ar->hw.app_start_override_addr); /* execute the OTP code */ - ath6kl_dbg(ATH6KL_DBG_BOOT, "executing OTP at 0x%x\n", - ar->hw.app_start_override_addr); + ath6kl_dbg(ATH6KL_DBG_BOOT, "executing OTP at 0x%x\n", address); param = 0; - ath6kl_bmi_execute(ar, ar->hw.app_start_override_addr, ¶m); + ath6kl_bmi_execute(ar, address, ¶m); return ret; } @@ -1333,10 +1420,6 @@ static int ath6kl_init_hw_params(struct ath6kl *ar) ar->hw.app_load_addr = AR6003_REV2_APP_LOAD_ADDRESS; ar->hw.board_ext_data_addr = AR6003_REV2_BOARD_EXT_DATA_ADDRESS; ar->hw.reserved_ram_size = AR6003_REV2_RAM_RESERVE_SIZE; - - /* hw2.0 needs override address hardcoded */ - ar->hw.app_start_override_addr = 0x944C00; - break; case AR6003_REV3_VERSION: ar->hw.dataset_patch_addr = AR6003_REV3_DATASET_PATCH_ADDRESS; @@ -1368,56 +1451,71 @@ static int ath6kl_init_hw_params(struct ath6kl *ar) return 0; } -int ath6kl_init_hw_start(struct ath6kl *ar) +static int ath6kl_init(struct net_device *dev) { - long timeleft; - int ret, i; - - ath6kl_dbg(ATH6KL_DBG_BOOT, "hw start\n"); - - ret = ath6kl_hif_power_on(ar); - if (ret) - return ret; - - ret = ath6kl_configure_target(ar); - if (ret) - goto err_power_off; + struct ath6kl *ar = ath6kl_priv(dev); + int status = 0; + s32 timeleft; - ret = ath6kl_init_upload(ar); - if (ret) - goto err_power_off; + if (!ar) + return -EIO; /* Do we need to finish the BMI phase */ - /* FIXME: return error from ath6kl_bmi_done() */ if (ath6kl_bmi_done(ar)) { - ret = -EIO; - goto err_power_off; + status = -EIO; + goto ath6kl_init_done; } + /* Indicate that WMI is enabled (although not ready yet) */ + set_bit(WMI_ENABLED, &ar->flag); + ar->wmi = ath6kl_wmi_init(ar); + if (!ar->wmi) { + ath6kl_err("failed to initialize wmi\n"); + status = -EIO; + goto ath6kl_init_done; + } + + ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi); + /* * 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 * size. */ if (ath6kl_htc_wait_target(ar->htc_target)) { - ret = -EIO; - goto err_power_off; + status = -EIO; + goto err_node_cleanup; } if (ath6kl_init_service_ep(ar)) { - ret = -EIO; + status = -EIO; goto err_cleanup_scatter; } + /* setup access class priority mappings */ + ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */ + ar->ac_stream_pri_map[WMM_AC_BE] = 1; + ar->ac_stream_pri_map[WMM_AC_VI] = 2; + ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */ + + /* give our connected endpoints some buffers */ + ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep); + ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]); + + /* allocate some buffers that handle larger AMSDU frames */ + ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS); + /* setup credit distribution */ - ath6kl_credit_setup(ar->htc_target, &ar->credit_state_info); + ath6k_setup_credit_dist(ar->htc_target, &ar->credit_state_info); + + ath6kl_cookie_init(ar); /* start HTC */ - ret = ath6kl_htc_start(ar->htc_target); - if (ret) { - /* FIXME: call this */ + status = ath6kl_htc_start(ar->htc_target); + + if (status) { ath6kl_cookie_cleanup(ar); - goto err_cleanup_scatter; + goto err_rxbuf_cleanup; } /* Wait for Wmi event to be ready */ @@ -1431,69 +1529,52 @@ int ath6kl_init_hw_start(struct ath6kl *ar) if (ar->version.abi_ver != ATH6KL_ABI_VERSION) { ath6kl_err("abi version mismatch: host(0x%x), target(0x%x)\n", ATH6KL_ABI_VERSION, ar->version.abi_ver); - ret = -EIO; + status = -EIO; goto err_htc_stop; } if (!timeleft || signal_pending(current)) { ath6kl_err("wmi is not ready or wait was interrupted\n"); - ret = -EIO; + status = -EIO; goto err_htc_stop; } ath6kl_dbg(ATH6KL_DBG_TRC, "%s: wmi is ready\n", __func__); /* communicate the wmi protocol verision to the target */ - /* FIXME: return error */ if ((ath6kl_set_host_app_area(ar)) != 0) ath6kl_err("unable to set the host app area\n"); - for (i = 0; i < MAX_NUM_VIF; i++) { - ret = ath6kl_target_config_wlan_params(ar, i); - if (ret) - goto err_htc_stop; - } + ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | + ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; - ar->state = ATH6KL_STATE_ON; + ar->wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | + WIPHY_FLAG_HAVE_AP_SME; - return 0; + status = ath6kl_target_config_wlan_params(ar); + if (!status) + goto ath6kl_init_done; err_htc_stop: ath6kl_htc_stop(ar->htc_target); +err_rxbuf_cleanup: + ath6kl_htc_flush_rx_buf(ar->htc_target); + ath6kl_cleanup_amsdu_rxbufs(ar); err_cleanup_scatter: ath6kl_hif_cleanup_scatter(ar); -err_power_off: - ath6kl_hif_power_off(ar); - - return ret; -} - -int ath6kl_init_hw_stop(struct ath6kl *ar) -{ - int ret; - - ath6kl_dbg(ATH6KL_DBG_BOOT, "hw stop\n"); - - ath6kl_htc_stop(ar->htc_target); - - ath6kl_hif_stop(ar); - - ath6kl_bmi_reset(ar); - - ret = ath6kl_hif_power_off(ar); - if (ret) - ath6kl_warn("failed to power off hif: %d\n", ret); - - ar->state = ATH6KL_STATE_OFF; +err_node_cleanup: + ath6kl_wmi_shutdown(ar->wmi); + clear_bit(WMI_ENABLED, &ar->flag); + ar->wmi = NULL; - return 0; +ath6kl_init_done: + return status; } int ath6kl_core_init(struct ath6kl *ar) { + int ret = 0; struct ath6kl_bmi_target_info targ_info; - struct net_device *ndev; - int ret = 0, i; ar->ath6kl_wq = create_singlethread_workqueue("ath6kl"); if (!ar->ath6kl_wq) @@ -1503,225 +1584,145 @@ int ath6kl_core_init(struct ath6kl *ar) if (ret) goto err_wq; - /* - * Turn on power to get hardware (target) version and leave power - * on delibrately as we will boot the hardware anyway within few - * seconds. - */ - ret = ath6kl_hif_power_on(ar); - if (ret) - goto err_bmi_cleanup; - ret = ath6kl_bmi_get_target_info(ar, &targ_info); if (ret) - goto err_power_off; + goto err_bmi_cleanup; ar->version.target_ver = le32_to_cpu(targ_info.version); ar->target_type = le32_to_cpu(targ_info.type); - ar->wiphy->hw_version = le32_to_cpu(targ_info.version); + ar->wdev->wiphy->hw_version = le32_to_cpu(targ_info.version); ret = ath6kl_init_hw_params(ar); if (ret) - goto err_power_off; + goto err_bmi_cleanup; + + ret = ath6kl_configure_target(ar); + if (ret) + goto err_bmi_cleanup; ar->htc_target = ath6kl_htc_create(ar); if (!ar->htc_target) { ret = -ENOMEM; - goto err_power_off; + 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; - /* FIXME: we should free all firmwares in the error cases below */ - - /* Indicate that WMI is enabled (although not ready yet) */ - set_bit(WMI_ENABLED, &ar->flag); - ar->wmi = ath6kl_wmi_init(ar); - if (!ar->wmi) { - ath6kl_err("failed to initialize wmi\n"); - ret = -EIO; + ret = ath6kl_init_upload(ar); + if (ret) goto err_htc_cleanup; - } - ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi); - - ret = ath6kl_register_ieee80211_hw(ar); + ret = ath6kl_init(ar->net_dev); if (ret) - goto err_node_cleanup; + goto err_htc_cleanup; - ret = ath6kl_debug_init(ar); + /* This runs the init function if registered */ + ret = register_netdev(ar->net_dev); if (ret) { - wiphy_unregister(ar->wiphy); - 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, - INFRA_NETWORK); - - rtnl_unlock(); - - if (!ndev) { - ath6kl_err("Failed to instantiate a network device\n"); - ret = -ENOMEM; - wiphy_unregister(ar->wiphy); - goto err_debug_init; + 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__, ndev->name, ndev, ar); - - /* setup access class priority mappings */ - ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */ - ar->ac_stream_pri_map[WMM_AC_BE] = 1; - ar->ac_stream_pri_map[WMM_AC_VI] = 2; - ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */ - - /* give our connected endpoints some buffers */ - ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep); - ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]); - - /* allocate some buffers that handle larger AMSDU frames */ - ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS); - - ath6kl_cookie_init(ar); - - ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | - ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; - - if (suspend_cutpower) - ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER; - - ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | - WIPHY_FLAG_HAVE_AP_SME; - - set_bit(FIRST_BOOT, &ar->flag); - - ret = ath6kl_init_hw_start(ar); - if (ret) { - ath6kl_err("Failed to start hardware: %d\n", ret); - goto err_rxbuf_cleanup; - } - - /* - * Set mac address which is received in ready event - * FIXME: Move to ath6kl_interface_add() - */ - memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); + __func__, ar->net_dev->name, ar->net_dev, ar); return ret; -err_rxbuf_cleanup: - ath6kl_htc_flush_rx_buf(ar->htc_target); - ath6kl_cleanup_amsdu_rxbufs(ar); - rtnl_lock(); - ath6kl_deinit_if_data(netdev_priv(ndev)); - rtnl_unlock(); - 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); - ar->wmi = NULL; err_htc_cleanup: ath6kl_htc_cleanup(ar->htc_target); -err_power_off: - ath6kl_hif_power_off(ar); err_bmi_cleanup: ath6kl_bmi_cleanup(ar); err_wq: destroy_workqueue(ar->ath6kl_wq); - return ret; } -void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) +void ath6kl_stop_txrx(struct ath6kl *ar) { - static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - bool discon_issued; - - netif_stop_queue(vif->ndev); + struct net_device *ndev = ar->net_dev; - clear_bit(WLAN_ENABLED, &vif->flags); + if (!ndev) + return; - if (wmi_ready) { - discon_issued = test_bit(CONNECTED, &vif->flags) || - test_bit(CONNECT_PEND, &vif->flags); - ath6kl_disconnect(vif); - del_timer(&vif->disconnect_timer); + set_bit(DESTROY_IN_PROGRESS, &ar->flag); - if (discon_issued) - ath6kl_disconnect_event(vif, DISCONNECT_CMD, - (vif->nw_type & AP_NETWORK) ? - bcast_mac : vif->bssid, - 0, NULL, 0); + if (down_interruptible(&ar->sem)) { + ath6kl_err("down_interruptible failed\n"); + return; } - if (vif->scan_req) { - cfg80211_scan_done(vif->scan_req, true); - vif->scan_req = NULL; - } + if (ar->wlan_pwr_state != WLAN_POWER_STATE_CUT_PWR) + ath6kl_stop_endpoint(ndev, false, true); + + clear_bit(WLAN_ENABLED, &ar->flag); } -void ath6kl_stop_txrx(struct ath6kl *ar) +/* + * 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_vif *vif, *tmp_vif; + struct ath6kl *ar; - set_bit(DESTROY_IN_PROGRESS, &ar->flag); - - if (down_interruptible(&ar->sem)) { - ath6kl_err("down_interruptible failed\n"); + if (!dev || !ath6kl_priv(dev)) { + ath6kl_err("failed to get device structure\n"); return; } - spin_lock_bh(&ar->list_lock); - list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) { - list_del(&vif->list); - spin_unlock_bh(&ar->list_lock); - ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag)); - rtnl_lock(); - ath6kl_deinit_if_data(vif); - rtnl_unlock(); - spin_lock_bh(&ar->list_lock); - } - spin_unlock_bh(&ar->list_lock); + ar = ath6kl_priv(dev); - clear_bit(WMI_READY, &ar->flag); + destroy_workqueue(ar->ath6kl_wq); - /* - * 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 (ar->htc_target) + ath6kl_htc_cleanup(ar->htc_target); - 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); + aggr_module_destroy(ar->aggr_cntxt); + + ath6kl_cookie_cleanup(ar); + + ath6kl_cleanup_amsdu_rxbufs(ar); + + ath6kl_bmi_cleanup(ar); + + ath6kl_debug_cleanup(ar); + + if (unregister && test_bit(NETDEV_REGISTERED, &ar->flag)) { + unregister_netdev(dev); + clear_bit(NETDEV_REGISTERED, &ar->flag); } - /* - * 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); + free_netdev(dev); - clear_bit(WLAN_ENABLED, &ar->flag); + kfree(ar->fw_board); + kfree(ar->fw_otp); + kfree(ar->fw); + kfree(ar->fw_patch); + + ath6kl_cfg80211_deinit(ar); } diff --git a/trunk/drivers/net/wireless/ath/ath6kl/main.c b/trunk/drivers/net/wireless/ath/ath6kl/main.c index 5e5f4ca8f3f0..30b5a53db9ed 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/main.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/main.c @@ -20,13 +20,12 @@ #include "target.h" #include "debug.h" -struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr) +struct ath6kl_sta *ath6kl_find_sta(struct ath6kl *ar, u8 *node_addr) { - struct ath6kl *ar = vif->ar; struct ath6kl_sta *conn = NULL; u8 i, max_conn; - max_conn = (vif->nw_type == AP_NETWORK) ? AP_MAX_NUM_STA : 0; + max_conn = (ar->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) { @@ -394,8 +393,8 @@ int ath6kl_read_fwlogs(struct ath6kl *ar) #define AR6003_RESET_CONTROL_ADDRESS 0x00004000 #define AR6004_RESET_CONTROL_ADDRESS 0x00004000 -void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, - bool wait_fot_compltn, bool cold_reset) +static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, + bool wait_fot_compltn, bool cold_reset) { int status = 0; u32 address; @@ -426,33 +425,102 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, ath6kl_err("failed to reset target\n"); } -static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif) +void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile, + bool get_dbglogs) +{ + struct ath6kl *ar = ath6kl_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, &ar->flag) || + test_bit(CONNECT_PEND, &ar->flag)); + ath6kl_disconnect(ar); + if (!keep_profile) + ath6kl_init_profile_info(ar); + + del_timer(&ar->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(ar, DISCONNECT_CMD, + (ar->nw_type & AP_NETWORK) ? + bcast_mac : ar->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 *ar) { u8 index; u8 keyusage; for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) { - if (vif->wep_key_list[index].key_len) { + if (ar->wep_key_list[index].key_len) { keyusage = GROUP_USAGE; - if (index == vif->def_txkey_index) + if (index == ar->def_txkey_index) keyusage |= TX_USAGE; - ath6kl_wmi_addkey_cmd(vif->ar->wmi, vif->fw_vif_idx, + ath6kl_wmi_addkey_cmd(ar->wmi, index, WEP_CRYPT, keyusage, - vif->wep_key_list[index].key_len, - NULL, 0, - vif->wep_key_list[index].key, + ar->wep_key_list[index].key_len, + NULL, + ar->wep_key_list[index].key, KEY_OP_INIT_VAL, NULL, NO_SYNC_WMIFLAG); } } } -void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) +void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel) { - struct ath6kl *ar = vif->ar; struct ath6kl_req_key *ik; int res; u8 key_rsc[ATH6KL_KEY_SEQ_LEN]; @@ -461,10 +529,10 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "AP mode started on %u MHz\n", channel); - switch (vif->auth_mode) { + switch (ar->auth_mode) { case NONE_AUTH: - if (vif->prwise_crypto == WEP_CRYPT) - ath6kl_install_static_wep_keys(vif); + if (ar->prwise_crypto == WEP_CRYPT) + ath6kl_install_static_wep_keys(ar); break; case WPA_PSK_AUTH: case WPA2_PSK_AUTH: @@ -476,9 +544,8 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) "the initial group key for AP mode\n"); memset(key_rsc, 0, sizeof(key_rsc)); res = ath6kl_wmi_addkey_cmd( - ar->wmi, vif->fw_vif_idx, ik->key_index, ik->key_type, - GROUP_USAGE, ik->key_len, key_rsc, ATH6KL_KEY_SEQ_LEN, - ik->key, + ar->wmi, 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) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed " @@ -487,16 +554,15 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) break; } - ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0); - set_bit(CONNECTED, &vif->flags); - netif_carrier_on(vif->ndev); + ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0); + set_bit(CONNECTED, &ar->flag); + netif_carrier_on(ar->net_dev); } -void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, +void ath6kl_connect_ap_mode_sta(struct ath6kl *ar, 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; @@ -551,32 +617,348 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, sinfo.assoc_req_ies_len = ies_len; sinfo.filled |= STATION_INFO_ASSOC_REQ_IES; - cfg80211_new_sta(vif->ndev, mac_addr, &sinfo, GFP_KERNEL); + cfg80211_new_sta(ar->net_dev, mac_addr, &sinfo, GFP_KERNEL); - netif_wake_queue(vif->ndev); + netif_wake_queue(ar->net_dev); +} + +/* Functions for Tx credit handling */ +void ath6k_credit_init(struct htc_credit_state_info *cred_info, + struct list_head *ep_list, + int tot_credits) +{ + struct htc_endpoint_credit_dist *cur_ep_dist; + int count; + + cred_info->cur_free_credits = tot_credits; + cred_info->total_avail_credits = tot_credits; + + list_for_each_entry(cur_ep_dist, ep_list, list) { + if (cur_ep_dist->endpoint == ENDPOINT_0) + continue; + + cur_ep_dist->cred_min = cur_ep_dist->cred_per_msg; + + if (tot_credits > 4) + if ((cur_ep_dist->svc_id == WMI_DATA_BK_SVC) || + (cur_ep_dist->svc_id == WMI_DATA_BE_SVC)) { + ath6kl_deposit_credit_to_ep(cred_info, + cur_ep_dist, + cur_ep_dist->cred_min); + cur_ep_dist->dist_flags |= HTC_EP_ACTIVE; + } + + if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) { + ath6kl_deposit_credit_to_ep(cred_info, cur_ep_dist, + cur_ep_dist->cred_min); + /* + * Control service is always marked active, it + * never goes inactive EVER. + */ + cur_ep_dist->dist_flags |= HTC_EP_ACTIVE; + } else if (cur_ep_dist->svc_id == WMI_DATA_BK_SVC) + /* this is the lowest priority data endpoint */ + cred_info->lowestpri_ep_dist = cur_ep_dist->list; + + /* + * Streams have to be created (explicit | implicit) for all + * kinds of traffic. BE endpoints are also inactive in the + * beginning. When BE traffic starts it creates implicit + * streams that redistributes credits. + * + * Note: all other endpoints have minimums set but are + * initially given NO credits. credits will be distributed + * as traffic activity demands + */ + } + + WARN_ON(cred_info->cur_free_credits <= 0); + + list_for_each_entry(cur_ep_dist, ep_list, list) { + if (cur_ep_dist->endpoint == ENDPOINT_0) + continue; + + if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) + cur_ep_dist->cred_norm = cur_ep_dist->cred_per_msg; + else { + /* + * For the remaining data endpoints, we assume that + * each cred_per_msg are the same. We use a simple + * calculation here, we take the remaining credits + * and determine how many max messages this can + * cover and then set each endpoint's normal value + * equal to 3/4 this amount. + */ + count = (cred_info->cur_free_credits / + cur_ep_dist->cred_per_msg) + * cur_ep_dist->cred_per_msg; + count = (count * 3) >> 2; + count = max(count, cur_ep_dist->cred_per_msg); + cur_ep_dist->cred_norm = count; + + } + } +} + +/* initialize and setup credit distribution */ +int ath6k_setup_credit_dist(void *htc_handle, + struct htc_credit_state_info *cred_info) +{ + u16 servicepriority[5]; + + memset(cred_info, 0, sizeof(struct htc_credit_state_info)); + + servicepriority[0] = WMI_CONTROL_SVC; /* highest */ + servicepriority[1] = WMI_DATA_VO_SVC; + servicepriority[2] = WMI_DATA_VI_SVC; + servicepriority[3] = WMI_DATA_BE_SVC; + servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */ + + /* set priority list */ + ath6kl_htc_set_credit_dist(htc_handle, cred_info, servicepriority, 5); + + return 0; +} + +/* reduce an ep's credits back to a set limit */ +static void ath6k_reduce_credits(struct htc_credit_state_info *cred_info, + struct htc_endpoint_credit_dist *ep_dist, + int limit) +{ + int credits; + + ep_dist->cred_assngd = limit; + + if (ep_dist->credits <= limit) + return; + + credits = ep_dist->credits - limit; + ep_dist->credits -= credits; + cred_info->cur_free_credits += credits; +} + +static void ath6k_credit_update(struct htc_credit_state_info *cred_info, + struct list_head *epdist_list) +{ + struct htc_endpoint_credit_dist *cur_dist_list; + + list_for_each_entry(cur_dist_list, epdist_list, list) { + if (cur_dist_list->endpoint == ENDPOINT_0) + continue; + + if (cur_dist_list->cred_to_dist > 0) { + cur_dist_list->credits += + cur_dist_list->cred_to_dist; + cur_dist_list->cred_to_dist = 0; + if (cur_dist_list->credits > + cur_dist_list->cred_assngd) + ath6k_reduce_credits(cred_info, + cur_dist_list, + cur_dist_list->cred_assngd); + + if (cur_dist_list->credits > + cur_dist_list->cred_norm) + ath6k_reduce_credits(cred_info, cur_dist_list, + cur_dist_list->cred_norm); + + if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) { + if (cur_dist_list->txq_depth == 0) + ath6k_reduce_credits(cred_info, + cur_dist_list, 0); + } + } + } +} + +/* + * HTC has an endpoint that needs credits, ep_dist is the endpoint in + * question. + */ +void ath6k_seek_credits(struct htc_credit_state_info *cred_info, + struct htc_endpoint_credit_dist *ep_dist) +{ + struct htc_endpoint_credit_dist *curdist_list; + int credits = 0; + int need; + + if (ep_dist->svc_id == WMI_CONTROL_SVC) + goto out; + + if ((ep_dist->svc_id == WMI_DATA_VI_SVC) || + (ep_dist->svc_id == WMI_DATA_VO_SVC)) + if ((ep_dist->cred_assngd >= ep_dist->cred_norm)) + goto out; + + /* + * For all other services, we follow a simple algorithm of: + * + * 1. checking the free pool for credits + * 2. checking lower priority endpoints for credits to take + */ + + credits = min(cred_info->cur_free_credits, ep_dist->seek_cred); + + if (credits >= ep_dist->seek_cred) + goto out; + + /* + * We don't have enough in the free pool, try taking away from + * lower priority services The rule for taking away credits: + * + * 1. Only take from lower priority endpoints + * 2. Only take what is allocated above the minimum (never + * starve an endpoint completely) + * 3. Only take what you need. + */ + + list_for_each_entry_reverse(curdist_list, + &cred_info->lowestpri_ep_dist, + list) { + if (curdist_list == ep_dist) + break; + + need = ep_dist->seek_cred - cred_info->cur_free_credits; + + if ((curdist_list->cred_assngd - need) >= + curdist_list->cred_min) { + /* + * The current one has been allocated more than + * it's minimum and it has enough credits assigned + * above it's minimum to fulfill our need try to + * take away just enough to fulfill our need. + */ + ath6k_reduce_credits(cred_info, curdist_list, + curdist_list->cred_assngd - need); + + if (cred_info->cur_free_credits >= + ep_dist->seek_cred) + break; + } + + if (curdist_list->endpoint == ENDPOINT_0) + break; + } + + credits = min(cred_info->cur_free_credits, ep_dist->seek_cred); + +out: + /* did we find some credits? */ + if (credits) + ath6kl_deposit_credit_to_ep(cred_info, ep_dist, credits); + + ep_dist->seek_cred = 0; +} + +/* redistribute credits based on activity change */ +static void ath6k_redistribute_credits(struct htc_credit_state_info *info, + struct list_head *ep_dist_list) +{ + struct htc_endpoint_credit_dist *curdist_list; + + list_for_each_entry(curdist_list, ep_dist_list, list) { + if (curdist_list->endpoint == ENDPOINT_0) + continue; + + if ((curdist_list->svc_id == WMI_DATA_BK_SVC) || + (curdist_list->svc_id == WMI_DATA_BE_SVC)) + curdist_list->dist_flags |= HTC_EP_ACTIVE; + + if ((curdist_list->svc_id != WMI_CONTROL_SVC) && + !(curdist_list->dist_flags & HTC_EP_ACTIVE)) { + if (curdist_list->txq_depth == 0) + ath6k_reduce_credits(info, + curdist_list, 0); + else + ath6k_reduce_credits(info, + curdist_list, + curdist_list->cred_min); + } + } +} + +/* + * + * This function is invoked whenever endpoints require credit + * distributions. A lock is held while this function is invoked, this + * function shall NOT block. The ep_dist_list is a list of distribution + * structures in prioritized order as defined by the call to the + * htc_set_credit_dist() api. + */ +void ath6k_credit_distribute(struct htc_credit_state_info *cred_info, + struct list_head *ep_dist_list, + enum htc_credit_dist_reason reason) +{ + switch (reason) { + case HTC_CREDIT_DIST_SEND_COMPLETE: + ath6k_credit_update(cred_info, ep_dist_list); + break; + case HTC_CREDIT_DIST_ACTIVITY_CHANGE: + ath6k_redistribute_credits(cred_info, ep_dist_list); + break; + default: + break; + } + + WARN_ON(cred_info->cur_free_credits > cred_info->total_avail_credits); + WARN_ON(cred_info->cur_free_credits < 0); } void disconnect_timer_handler(unsigned long ptr) { struct net_device *dev = (struct net_device *)ptr; - struct ath6kl_vif *vif = netdev_priv(dev); + struct ath6kl *ar = ath6kl_priv(dev); - ath6kl_init_profile_info(vif); - ath6kl_disconnect(vif); + ath6kl_init_profile_info(ar); + ath6kl_disconnect(ar); } -void ath6kl_disconnect(struct ath6kl_vif *vif) +void ath6kl_disconnect(struct ath6kl *ar) { - if (test_bit(CONNECTED, &vif->flags) || - test_bit(CONNECT_PEND, &vif->flags)) { - ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx); + if (test_bit(CONNECTED, &ar->flag) || + test_bit(CONNECT_PEND, &ar->flag)) { + 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, &vif->flags); + clear_bit(CONNECT_PEND, &ar->flag); + } +} + +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, + NULL, 0, + WLAN_STATUS_UNSPECIFIED_FAILURE, + GFP_KERNEL); + break; + case SME_CONNECTED: + default: + /* + * FIXME: oddly enough smeState is in DISCONNECTED during + * suspend, why? Need to send disconnected event in that + * state. + */ + cfg80211_disconnected(ar->net_dev, 0, NULL, 0, GFP_KERNEL); + break; } + + if (test_bit(CONNECTED, &ar->flag) || + test_bit(CONNECT_PEND, &ar->flag)) + ath6kl_wmi_disconnect_cmd(ar->wmi); + + ar->sme_state = SME_DISCONNECTED; + + /* disable scanning */ + if (ath6kl_wmi_scanparams_cmd(ar->wmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, + 0, 0) != 0) + printk(KERN_WARNING "ath6kl: failed to disable scan " + "during suspend\n"); + + ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED); } /* WMI Event handlers */ @@ -598,16 +980,17 @@ 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; - memcpy(ar->mac_addr, datap, ETH_ALEN); + memcpy(dev->dev_addr, datap, ETH_ALEN); ath6kl_dbg(ATH6KL_DBG_TRC, "%s: mac addr = %pM\n", - __func__, ar->mac_addr); + __func__, dev->dev_addr); ar->version.wlan_ver = sw_ver; ar->version.abi_ver = abi_ver; - snprintf(ar->wiphy->fw_version, - sizeof(ar->wiphy->fw_version), + snprintf(ar->wdev->wiphy->fw_version, + sizeof(ar->wdev->wiphy->fw_version), "%u.%u.%u.%u", (ar->version.wlan_ver & 0xf0000000) >> 28, (ar->version.wlan_ver & 0x0f000000) >> 24, @@ -618,91 +1001,78 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver) set_bit(WMI_READY, &ar->flag); wake_up(&ar->event_wq); - if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) { - ath6kl_info("hw %s fw %s%s\n", - get_hw_id_string(ar->wiphy->hw_version), - ar->wiphy->fw_version, - test_bit(TESTMODE, &ar->flag) ? " testmode" : ""); - } + ath6kl_info("hw %s fw %s%s\n", + get_hw_id_string(ar->wdev->wiphy->hw_version), + ar->wdev->wiphy->fw_version, + test_bit(TESTMODE, &ar->flag) ? " testmode" : ""); } -void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status) +void ath6kl_scan_complete_evt(struct ath6kl *ar, int status) { - struct ath6kl *ar = vif->ar; - bool aborted = false; - - if (status != WMI_SCAN_STATUS_SUCCESS) - aborted = true; - - ath6kl_cfg80211_scan_complete_event(vif, aborted); + ath6kl_cfg80211_scan_complete_event(ar, status); if (!ar->usr_bss_filter) { - clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); - ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, - NONE_BSS_FILTER, 0); + clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag); + ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0); } - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "scan complete: %d\n", status); + ath6kl_dbg(ATH6KL_DBG_WLAN_SCAN, "scan complete: %d\n", status); } -void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, +void ath6kl_connect_event(struct ath6kl *ar, 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) { - struct ath6kl *ar = vif->ar; + unsigned long flags; - ath6kl_cfg80211_connect_event(vif, channel, bssid, + ath6kl_cfg80211_connect_event(ar, channel, bssid, listen_int, beacon_int, net_type, beacon_ie_len, assoc_req_len, assoc_resp_len, assoc_info); - memcpy(vif->bssid, bssid, sizeof(vif->bssid)); - vif->bss_ch = channel; + memcpy(ar->bssid, bssid, sizeof(ar->bssid)); + ar->bss_ch = channel; - if ((vif->nw_type == INFRA_NETWORK)) - ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, - ar->listen_intvl_t, + if ((ar->nw_type == INFRA_NETWORK)) + ath6kl_wmi_listeninterval_cmd(ar->wmi, ar->listen_intvl_t, ar->listen_intvl_b); - netif_wake_queue(vif->ndev); + netif_wake_queue(ar->net_dev); /* Update connect & link status atomically */ - 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(&vif->if_lock); + spin_lock_irqsave(&ar->lock, flags); + set_bit(CONNECTED, &ar->flag); + clear_bit(CONNECT_PEND, &ar->flag); + netif_carrier_on(ar->net_dev); + spin_unlock_irqrestore(&ar->lock, flags); - aggr_reset_state(vif->aggr_cntxt); - vif->reconnect_flag = 0; + aggr_reset_state(ar->aggr_cntxt); + ar->reconnect_flag = 0; - if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) { + if ((ar->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; } if (!ar->usr_bss_filter) { - set_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); - ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, - CURRENT_BSS_FILTER, 0); + set_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag); + ath6kl_wmi_bssfilter_cmd(ar->wmi, CURRENT_BSS_FILTER, 0); } } -void ath6kl_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid, bool ismcast) +void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast) { struct ath6kl_sta *sta; - 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. */ - if (vif->nw_type == AP_NETWORK) { + if (ar->nw_type == AP_NETWORK) { sta = ath6kl_find_sta_by_aid(ar, (keyid >> 2)); if (!sta) return; @@ -711,20 +1081,19 @@ void ath6kl_tkip_micerr_event(struct ath6kl_vif *vif, 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(vif->ndev, sta->mac, + cfg80211_michael_mic_failure(ar->net_dev, sta->mac, NL80211_KEYTYPE_PAIRWISE, keyid, tsc, GFP_KERNEL); } else - ath6kl_cfg80211_tkip_micerr_event(vif, keyid, ismcast); + ath6kl_cfg80211_tkip_micerr_event(ar, keyid, ismcast); } -static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len) +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 ath6kl *ar = vif->ar; - struct target_stats *stats = &vif->target_stats; + struct target_stats *stats = &ar->target_stats; struct tkip_ccmp_stats *ccmp_stats; u8 ac; @@ -820,8 +1189,8 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len) stats->wow_evt_discarded += le16_to_cpu(tgt_stats->wow_stats.wow_evt_discarded); - if (test_bit(STATS_UPDATE_PEND, &vif->flags)) { - clear_bit(STATS_UPDATE_PEND, &vif->flags); + if (test_bit(STATS_UPDATE_PEND, &ar->flag)) { + clear_bit(STATS_UPDATE_PEND, &ar->flag); wake_up(&ar->event_wq); } } @@ -831,15 +1200,14 @@ 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_vif *vif, u8 *ptr, u32 len) +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 ath6kl *ar = vif->ar; struct wmi_ap_mode_stat *ap = &ar->ap_stats; struct wmi_per_sta_stat *st_ap, *st_p; u8 ac; - if (vif->nw_type == AP_NETWORK) { + if (ar->nw_type == AP_NETWORK) { if (len < sizeof(*p)) return; @@ -858,7 +1226,7 @@ void ath6kl_tgt_stats_event(struct ath6kl_vif *vif, u8 *ptr, u32 len) } } else { - ath6kl_update_target_stats(vif, ptr, len); + ath6kl_update_target_stats(ar, ptr, len); } } @@ -877,12 +1245,11 @@ void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr) wake_up(&ar->event_wq); } -void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid) +void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid) { struct ath6kl_sta *conn; struct sk_buff *skb; bool psq_empty = false; - struct ath6kl *ar = vif->ar; conn = ath6kl_find_sta_by_aid(ar, aid); @@ -905,7 +1272,7 @@ void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid) spin_unlock_bh(&conn->psq_lock); conn->sta_flags |= STA_PS_POLLED; - ath6kl_data_tx(skb, vif->ndev); + ath6kl_data_tx(skb, ar->net_dev); conn->sta_flags &= ~STA_PS_POLLED; spin_lock_bh(&conn->psq_lock); @@ -913,14 +1280,13 @@ void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid) spin_unlock_bh(&conn->psq_lock); if (psq_empty) - ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, conn->aid, 0); + ath6kl_wmi_set_pvb_cmd(ar->wmi, conn->aid, 0); } -void ath6kl_dtimexpiry_event(struct ath6kl_vif *vif) +void ath6kl_dtimexpiry_event(struct ath6kl *ar) { bool mcastq_empty = false; struct sk_buff *skb; - struct ath6kl *ar = vif->ar; /* * If there are no associated STAs, ignore the DTIM expiry event. @@ -942,31 +1308,31 @@ void ath6kl_dtimexpiry_event(struct ath6kl_vif *vif) return; /* set the STA flag to dtim_expired for the frame to go out */ - set_bit(DTIM_EXPIRED, &vif->flags); + set_bit(DTIM_EXPIRED, &ar->flag); spin_lock_bh(&ar->mcastpsq_lock); while ((skb = skb_dequeue(&ar->mcastpsq)) != NULL) { spin_unlock_bh(&ar->mcastpsq_lock); - ath6kl_data_tx(skb, vif->ndev); + ath6kl_data_tx(skb, ar->net_dev); spin_lock_bh(&ar->mcastpsq_lock); } spin_unlock_bh(&ar->mcastpsq_lock); - clear_bit(DTIM_EXPIRED, &vif->flags); + clear_bit(DTIM_EXPIRED, &ar->flag); /* clear the LSB of the BitMapCtl field of the TIM IE */ - ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, MCAST_AID, 0); + ath6kl_wmi_set_pvb_cmd(ar->wmi, MCAST_AID, 0); } -void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, +void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid, u8 assoc_resp_len, u8 *assoc_info, u16 prot_reason_status) { - struct ath6kl *ar = vif->ar; + unsigned long flags; - if (vif->nw_type == AP_NETWORK) { + if (ar->nw_type == AP_NETWORK) { if (!ath6kl_remove_sta(ar, bssid, prot_reason_status)) return; @@ -978,31 +1344,31 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, 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, vif->fw_vif_idx, - MCAST_AID, 0); + ath6kl_wmi_set_pvb_cmd(ar->wmi, MCAST_AID, 0); } if (!is_broadcast_ether_addr(bssid)) { /* send event to application */ - cfg80211_del_sta(vif->ndev, bssid, GFP_KERNEL); + cfg80211_del_sta(ar->net_dev, bssid, GFP_KERNEL); } - 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); + 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); } return; } - ath6kl_cfg80211_disconnect_event(vif, reason, bssid, + ath6kl_cfg80211_disconnect_event(ar, reason, bssid, assoc_resp_len, assoc_info, prot_reason_status); - aggr_reset_state(vif->aggr_cntxt); + aggr_reset_state(ar->aggr_cntxt); - del_timer(&vif->disconnect_timer); + del_timer(&ar->disconnect_timer); - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "disconnect reason is %d\n", reason); + ath6kl_dbg(ATH6KL_DBG_WLAN_CONNECT, + "disconnect reason is %d\n", reason); /* * If the event is due to disconnect cmd from the host, only they @@ -1011,98 +1377,83 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, 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, vif->fw_vif_idx, - NONE_BSS_FILTER, 0); + ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0); } else { - set_bit(CONNECT_PEND, &vif->flags); + set_bit(CONNECT_PEND, &ar->flag); if (((reason == ASSOC_FAILED) && (prot_reason_status == 0x11)) || ((reason == ASSOC_FAILED) && (prot_reason_status == 0x0) - && (vif->reconnect_flag == 1))) { - set_bit(CONNECTED, &vif->flags); + && (ar->reconnect_flag == 1))) { + set_bit(CONNECTED, &ar->flag); return; } } /* update connect & link status atomically */ - spin_lock_bh(&vif->if_lock); - clear_bit(CONNECTED, &vif->flags); - netif_carrier_off(vif->ndev); - spin_unlock_bh(&vif->if_lock); + spin_lock_irqsave(&ar->lock, flags); + clear_bit(CONNECTED, &ar->flag); + netif_carrier_off(ar->net_dev); + spin_unlock_irqrestore(&ar->lock, flags); - if ((reason != CSERV_DISCONNECT) || (vif->reconnect_flag != 1)) - vif->reconnect_flag = 0; + if ((reason != CSERV_DISCONNECT) || (ar->reconnect_flag != 1)) + ar->reconnect_flag = 0; if (reason != CSERV_DISCONNECT) ar->user_key_ctrl = 0; - netif_stop_queue(vif->ndev); - memset(vif->bssid, 0, sizeof(vif->bssid)); - vif->bss_ch = 0; + netif_stop_queue(ar->net_dev); + memset(ar->bssid, 0, sizeof(ar->bssid)); + ar->bss_ch = 0; ath6kl_tx_data_cleanup(ar); } -struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar) -{ - struct ath6kl_vif *vif; - - spin_lock_bh(&ar->list_lock); - if (list_empty(&ar->vif_list)) { - spin_unlock_bh(&ar->list_lock); - return NULL; - } - - vif = list_first_entry(&ar->vif_list, struct ath6kl_vif, list); - - spin_unlock_bh(&ar->list_lock); - - return vif; -} - static int ath6kl_open(struct net_device *dev) { - struct ath6kl_vif *vif = netdev_priv(dev); + struct ath6kl *ar = ath6kl_priv(dev); + unsigned long flags; - set_bit(WLAN_ENABLED, &vif->flags); + spin_lock_irqsave(&ar->lock, flags); - if (test_bit(CONNECTED, &vif->flags)) { + set_bit(WLAN_ENABLED, &ar->flag); + + if (test_bit(CONNECTED, &ar->flag)) { netif_carrier_on(dev); netif_wake_queue(dev); } else netif_carrier_off(dev); + spin_unlock_irqrestore(&ar->lock, flags); + return 0; } 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); - ath6kl_disconnect(vif); + ath6kl_disconnect(ar); if (test_bit(WMI_READY, &ar->flag)) { - if (ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0xFFFF, - 0, 0, 0, 0, 0, 0, 0, 0, 0)) + if (ath6kl_wmi_scanparams_cmd(ar->wmi, 0xFFFF, 0, 0, 0, 0, 0, 0, + 0, 0, 0)) return -EIO; + clear_bit(WLAN_ENABLED, &ar->flag); } - ath6kl_cfg80211_scan_complete_event(vif, true); - - clear_bit(WLAN_ENABLED, &vif->flags); + ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED); return 0; } static struct net_device_stats *ath6kl_get_stats(struct net_device *dev) { - struct ath6kl_vif *vif = netdev_priv(dev); + struct ath6kl *ar = ath6kl_priv(dev); - return &vif->net_stats; + return &ar->net_stats; } static struct net_device_ops ath6kl_netdev_ops = { @@ -1115,7 +1466,6 @@ 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; diff --git a/trunk/drivers/net/wireless/ath/ath6kl/sdio.c b/trunk/drivers/net/wireless/ath/ath6kl/sdio.c index beb5f9bf26af..f1dc311ee0c7 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/sdio.c @@ -21,7 +21,7 @@ #include #include #include -#include "hif.h" +#include "htc_hif.h" #include "hif-ops.h" #include "target.h" #include "debug.h" @@ -45,8 +45,6 @@ struct ath6kl_sdio { struct list_head scat_req; spinlock_t scat_lock; - bool scatter_enabled; - bool is_disabled; atomic_t irq_handling; const struct sdio_device_id *id; @@ -136,8 +134,6 @@ static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr, { int ret = 0; - sdio_claim_host(func); - if (request & HIF_WRITE) { /* FIXME: looks like ugly workaround for something */ if (addr >= HIF_MBOX_BASE_ADDR && @@ -159,8 +155,6 @@ static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr, ret = sdio_memcpy_fromio(func, buf, addr, len); } - sdio_release_host(func); - ath6kl_dbg(ATH6KL_DBG_SDIO, "%s addr 0x%x%s buf 0x%p len %d\n", request & HIF_WRITE ? "wr" : "rd", addr, request & HIF_FIXED_ADDRESS ? " (fixed)" : "", buf, len); @@ -172,11 +166,12 @@ static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr, static struct bus_request *ath6kl_sdio_alloc_busreq(struct ath6kl_sdio *ar_sdio) { struct bus_request *bus_req; + unsigned long flag; - spin_lock_bh(&ar_sdio->lock); + spin_lock_irqsave(&ar_sdio->lock, flag); if (list_empty(&ar_sdio->bus_req_freeq)) { - spin_unlock_bh(&ar_sdio->lock); + spin_unlock_irqrestore(&ar_sdio->lock, flag); return NULL; } @@ -184,7 +179,7 @@ static struct bus_request *ath6kl_sdio_alloc_busreq(struct ath6kl_sdio *ar_sdio) struct bus_request, list); list_del(&bus_req->list); - spin_unlock_bh(&ar_sdio->lock); + spin_unlock_irqrestore(&ar_sdio->lock, flag); ath6kl_dbg(ATH6KL_DBG_SCATTER, "%s: bus request 0x%p\n", __func__, bus_req); @@ -194,12 +189,14 @@ static struct bus_request *ath6kl_sdio_alloc_busreq(struct ath6kl_sdio *ar_sdio) static void ath6kl_sdio_free_bus_req(struct ath6kl_sdio *ar_sdio, struct bus_request *bus_req) { + unsigned long flag; + ath6kl_dbg(ATH6KL_DBG_SCATTER, "%s: bus request 0x%p\n", __func__, bus_req); - spin_lock_bh(&ar_sdio->lock); + spin_lock_irqsave(&ar_sdio->lock, flag); list_add_tail(&bus_req->list, &ar_sdio->bus_req_freeq); - spin_unlock_bh(&ar_sdio->lock); + spin_unlock_irqrestore(&ar_sdio->lock, flag); } static void ath6kl_sdio_setup_scat_data(struct hif_scatter_req *scat_req, @@ -293,14 +290,10 @@ static int ath6kl_sdio_scat_rw(struct ath6kl_sdio *ar_sdio, mmc_req.cmd = &cmd; mmc_req.data = &data; - sdio_claim_host(ar_sdio->func); - mmc_set_data_timeout(&data, ar_sdio->func->card); /* synchronous call to process request */ mmc_wait_for_req(ar_sdio->func->card->host, &mmc_req); - sdio_release_host(ar_sdio->func); - status = cmd.error ? cmd.error : data.error; scat_complete: @@ -401,9 +394,11 @@ static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf, } else tbuf = buf; + sdio_claim_host(ar_sdio->func); ret = ath6kl_sdio_io(ar_sdio->func, request, addr, tbuf, len); if ((request & HIF_READ) && bounced) memcpy(buf, tbuf, len); + sdio_release_host(ar_sdio->func); return ret; } @@ -422,25 +417,29 @@ static void __ath6kl_sdio_write_async(struct ath6kl_sdio *ar_sdio, req->request); context = req->packet; ath6kl_sdio_free_bus_req(ar_sdio, req); - ath6kl_hif_rw_comp_handler(context, status); + ath6kldev_rw_comp_handler(context, status); } } static void ath6kl_sdio_write_async_work(struct work_struct *work) { struct ath6kl_sdio *ar_sdio; + unsigned long flags; struct bus_request *req, *tmp_req; ar_sdio = container_of(work, struct ath6kl_sdio, wr_async_work); + sdio_claim_host(ar_sdio->func); - spin_lock_bh(&ar_sdio->wr_async_lock); + spin_lock_irqsave(&ar_sdio->wr_async_lock, flags); list_for_each_entry_safe(req, tmp_req, &ar_sdio->wr_asyncq, list) { list_del(&req->list); - spin_unlock_bh(&ar_sdio->wr_async_lock); + spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags); __ath6kl_sdio_write_async(ar_sdio, req); - spin_lock_bh(&ar_sdio->wr_async_lock); + spin_lock_irqsave(&ar_sdio->wr_async_lock, flags); } - spin_unlock_bh(&ar_sdio->wr_async_lock); + spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags); + + sdio_release_host(ar_sdio->func); } static void ath6kl_sdio_irq_handler(struct sdio_func *func) @@ -459,23 +458,20 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func) */ sdio_release_host(ar_sdio->func); - status = ath6kl_hif_intr_bh_handler(ar_sdio->ar); + status = ath6kldev_intr_bh_handler(ar_sdio->ar); sdio_claim_host(ar_sdio->func); atomic_set(&ar_sdio->irq_handling, 0); WARN_ON(status && status != -ECANCELED); } -static int ath6kl_sdio_power_on(struct ath6kl *ar) +static int ath6kl_sdio_power_on(struct ath6kl_sdio *ar_sdio) { - struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); struct sdio_func *func = ar_sdio->func; int ret = 0; if (!ar_sdio->is_disabled) return 0; - ath6kl_dbg(ATH6KL_DBG_BOOT, "sdio power on\n"); - sdio_claim_host(func); ret = sdio_enable_func(func); @@ -498,16 +494,13 @@ static int ath6kl_sdio_power_on(struct ath6kl *ar) return ret; } -static int ath6kl_sdio_power_off(struct ath6kl *ar) +static int ath6kl_sdio_power_off(struct ath6kl_sdio *ar_sdio) { - struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); int ret; if (ar_sdio->is_disabled) return 0; - ath6kl_dbg(ATH6KL_DBG_BOOT, "sdio power off\n"); - /* Disable the card */ sdio_claim_host(ar_sdio->func); ret = sdio_disable_func(ar_sdio->func); @@ -527,6 +520,7 @@ static int ath6kl_sdio_write_async(struct ath6kl *ar, u32 address, u8 *buffer, { struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); struct bus_request *bus_req; + unsigned long flags; bus_req = ath6kl_sdio_alloc_busreq(ar_sdio); @@ -539,9 +533,9 @@ static int ath6kl_sdio_write_async(struct ath6kl *ar, u32 address, u8 *buffer, bus_req->request = request; bus_req->packet = packet; - spin_lock_bh(&ar_sdio->wr_async_lock); + spin_lock_irqsave(&ar_sdio->wr_async_lock, flags); list_add_tail(&bus_req->list, &ar_sdio->wr_asyncq); - spin_unlock_bh(&ar_sdio->wr_async_lock); + spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags); queue_work(ar->ath6kl_wq, &ar_sdio->wr_async_work); return 0; @@ -587,8 +581,9 @@ static struct hif_scatter_req *ath6kl_sdio_scatter_req_get(struct ath6kl *ar) { struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); struct hif_scatter_req *node = NULL; + unsigned long flag; - spin_lock_bh(&ar_sdio->scat_lock); + spin_lock_irqsave(&ar_sdio->scat_lock, flag); if (!list_empty(&ar_sdio->scat_req)) { node = list_first_entry(&ar_sdio->scat_req, @@ -596,7 +591,7 @@ static struct hif_scatter_req *ath6kl_sdio_scatter_req_get(struct ath6kl *ar) list_del(&node->list); } - spin_unlock_bh(&ar_sdio->scat_lock); + spin_unlock_irqrestore(&ar_sdio->scat_lock, flag); return node; } @@ -605,12 +600,13 @@ static void ath6kl_sdio_scatter_req_add(struct ath6kl *ar, struct hif_scatter_req *s_req) { struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); + unsigned long flag; - spin_lock_bh(&ar_sdio->scat_lock); + spin_lock_irqsave(&ar_sdio->scat_lock, flag); list_add_tail(&s_req->list, &ar_sdio->scat_req); - spin_unlock_bh(&ar_sdio->scat_lock); + spin_unlock_irqrestore(&ar_sdio->scat_lock, flag); } @@ -621,6 +617,7 @@ static int ath6kl_sdio_async_rw_scatter(struct ath6kl *ar, struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); u32 request = scat_req->req; int status = 0; + unsigned long flags; if (!scat_req->len) return -EINVAL; @@ -629,12 +626,14 @@ static int ath6kl_sdio_async_rw_scatter(struct ath6kl *ar, "hif-scatter: total len: %d scatter entries: %d\n", scat_req->len, scat_req->scat_entries); - if (request & HIF_SYNCHRONOUS) + if (request & HIF_SYNCHRONOUS) { + sdio_claim_host(ar_sdio->func); status = ath6kl_sdio_scat_rw(ar_sdio, scat_req->busrequest); - else { - spin_lock_bh(&ar_sdio->wr_async_lock); + sdio_release_host(ar_sdio->func); + } else { + spin_lock_irqsave(&ar_sdio->wr_async_lock, flags); list_add_tail(&scat_req->busrequest->list, &ar_sdio->wr_asyncq); - spin_unlock_bh(&ar_sdio->wr_async_lock); + spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags); queue_work(ar->ath6kl_wq, &ar_sdio->wr_async_work); } @@ -646,27 +645,23 @@ static void ath6kl_sdio_cleanup_scatter(struct ath6kl *ar) { struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); struct hif_scatter_req *s_req, *tmp_req; + unsigned long flag; /* empty the free list */ - spin_lock_bh(&ar_sdio->scat_lock); + spin_lock_irqsave(&ar_sdio->scat_lock, flag); list_for_each_entry_safe(s_req, tmp_req, &ar_sdio->scat_req, list) { list_del(&s_req->list); - spin_unlock_bh(&ar_sdio->scat_lock); + spin_unlock_irqrestore(&ar_sdio->scat_lock, flag); - /* - * FIXME: should we also call completion handler with - * ath6kl_hif_rw_comp_handler() with status -ECANCELED so - * that the packet is properly freed? - */ if (s_req->busrequest) ath6kl_sdio_free_bus_req(ar_sdio, s_req->busrequest); kfree(s_req->virt_dma_buf); kfree(s_req->sgentries); kfree(s_req); - spin_lock_bh(&ar_sdio->scat_lock); + spin_lock_irqsave(&ar_sdio->scat_lock, flag); } - spin_unlock_bh(&ar_sdio->scat_lock); + spin_unlock_irqrestore(&ar_sdio->scat_lock, flag); } /* setup of HIF scatter resources */ @@ -677,11 +672,6 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar) int ret; bool virt_scat = false; - if (ar_sdio->scatter_enabled) - return 0; - - ar_sdio->scatter_enabled = true; - /* check if host supports scatter and it meets our requirements */ if (ar_sdio->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) { ath6kl_err("host only supports scatter of :%d entries, need: %d\n", @@ -696,8 +686,8 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar) MAX_SCATTER_REQUESTS, virt_scat); if (!ret) { - ath6kl_dbg(ATH6KL_DBG_BOOT, - "hif-scatter enabled requests %d entries %d\n", + ath6kl_dbg(ATH6KL_DBG_SCATTER, + "hif-scatter enabled: max scatter req : %d entries: %d\n", MAX_SCATTER_REQUESTS, MAX_SCATTER_ENTRIES_PER_REQ); @@ -721,8 +711,8 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar) return ret; } - ath6kl_dbg(ATH6KL_DBG_BOOT, - "virtual scatter enabled requests %d entries %d\n", + ath6kl_dbg(ATH6KL_DBG_SCATTER, + "Vitual scatter enabled, max_scat_req:%d, entries:%d\n", ATH6KL_SCATTER_REQS, ATH6KL_SCATTER_ENTRIES_PER_REQ); target->max_scat_entries = ATH6KL_SCATTER_ENTRIES_PER_REQ; @@ -733,47 +723,7 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar) return 0; } -static int ath6kl_sdio_config(struct ath6kl *ar) -{ - struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); - struct sdio_func *func = ar_sdio->func; - int ret; - - sdio_claim_host(func); - - if ((ar_sdio->id->device & MANUFACTURER_ID_ATH6KL_BASE_MASK) >= - MANUFACTURER_ID_AR6003_BASE) { - /* enable 4-bit ASYNC interrupt on AR6003 or later */ - ret = ath6kl_sdio_func0_cmd52_wr_byte(func->card, - CCCR_SDIO_IRQ_MODE_REG, - SDIO_IRQ_MODE_ASYNC_4BIT_IRQ); - if (ret) { - ath6kl_err("Failed to enable 4-bit async irq mode %d\n", - ret); - goto out; - } - - ath6kl_dbg(ATH6KL_DBG_BOOT, "4-bit async irq mode enabled\n"); - } - - /* give us some time to enable, in ms */ - func->enable_timeout = 100; - - ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); - if (ret) { - ath6kl_err("Set sdio block size %d failed: %d)\n", - HIF_MBOX_BLOCK_SIZE, ret); - sdio_release_host(func); - goto out; - } - -out: - sdio_release_host(func); - - return ret; -} - -static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) +static int ath6kl_sdio_suspend(struct ath6kl *ar) { struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); struct sdio_func *func = ar_sdio->func; @@ -782,14 +732,12 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) flags = sdio_get_host_pm_caps(func); - ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio suspend pm_caps 0x%x\n", flags); - - if (!(flags & MMC_PM_KEEP_POWER) || - (ar->conf_flags & ATH6KL_CONF_SUSPEND_CUTPOWER)) { - /* as host doesn't support keep power we need to cut power */ - return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, - NULL); - } + if (!(flags & MMC_PM_KEEP_POWER)) + /* as host doesn't support keep power we need to bail out */ + ath6kl_dbg(ATH6KL_DBG_SDIO, + "func %d doesn't support MMC_PM_KEEP_POWER\n", + func->num); + return -EINVAL; ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); if (ret) { @@ -798,85 +746,11 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) return ret; } - if ((flags & MMC_PM_WAKE_SDIO_IRQ) && wow) { - /* - * The host sdio controller is capable of keep power and - * sdio irq wake up at this point. It's fine to continue - * wow suspend operation. - */ - ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow); - if (ret) - return ret; - - ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); - if (ret) - ath6kl_err("set sdio wake irq flag failed: %d\n", ret); - - return ret; - } - - return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, NULL); -} - -static int ath6kl_sdio_resume(struct ath6kl *ar) -{ - switch (ar->state) { - case ATH6KL_STATE_OFF: - case ATH6KL_STATE_CUTPOWER: - ath6kl_dbg(ATH6KL_DBG_SUSPEND, - "sdio resume configuring sdio\n"); - - /* need to set sdio settings after power is cut from sdio */ - ath6kl_sdio_config(ar); - break; - - case ATH6KL_STATE_ON: - break; - - case ATH6KL_STATE_DEEPSLEEP: - break; - - case ATH6KL_STATE_WOW: - break; - } - - ath6kl_cfg80211_resume(ar); + ath6kl_deep_sleep_enable(ar); return 0; } -static void ath6kl_sdio_stop(struct ath6kl *ar) -{ - struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); - struct bus_request *req, *tmp_req; - void *context; - - /* FIXME: make sure that wq is not queued again */ - - cancel_work_sync(&ar_sdio->wr_async_work); - - spin_lock_bh(&ar_sdio->wr_async_lock); - - list_for_each_entry_safe(req, tmp_req, &ar_sdio->wr_asyncq, list) { - list_del(&req->list); - - if (req->scat_req) { - /* this is a scatter gather request */ - req->scat_req->status = -ECANCELED; - req->scat_req->complete(ar_sdio->ar->htc_target, - req->scat_req); - } else { - context = req->packet; - ath6kl_sdio_free_bus_req(ar_sdio, req); - ath6kl_hif_rw_comp_handler(context, -ECANCELED); - } - } - - spin_unlock_bh(&ar_sdio->wr_async_lock); - - WARN_ON(get_queue_depth(&ar_sdio->scat_req) != 4); -} - static const struct ath6kl_hif_ops ath6kl_sdio_ops = { .read_write_sync = ath6kl_sdio_read_write_sync, .write_async = ath6kl_sdio_write_async, @@ -888,43 +762,8 @@ static const struct ath6kl_hif_ops ath6kl_sdio_ops = { .scat_req_rw = ath6kl_sdio_async_rw_scatter, .cleanup_scatter = ath6kl_sdio_cleanup_scatter, .suspend = ath6kl_sdio_suspend, - .resume = ath6kl_sdio_resume, - .power_on = ath6kl_sdio_power_on, - .power_off = ath6kl_sdio_power_off, - .stop = ath6kl_sdio_stop, }; -#ifdef CONFIG_PM_SLEEP - -/* - * Empty handlers so that mmc subsystem doesn't remove us entirely during - * suspend. We instead follow cfg80211 suspend/resume handlers. - */ -static int ath6kl_sdio_pm_suspend(struct device *device) -{ - ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio pm suspend\n"); - - return 0; -} - -static int ath6kl_sdio_pm_resume(struct device *device) -{ - ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio pm resume\n"); - - return 0; -} - -static SIMPLE_DEV_PM_OPS(ath6kl_sdio_pm_ops, ath6kl_sdio_pm_suspend, - ath6kl_sdio_pm_resume); - -#define ATH6KL_SDIO_PM_OPS (&ath6kl_sdio_pm_ops) - -#else - -#define ATH6KL_SDIO_PM_OPS NULL - -#endif /* CONFIG_PM_SLEEP */ - static int ath6kl_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { @@ -933,8 +772,8 @@ static int ath6kl_sdio_probe(struct sdio_func *func, struct ath6kl *ar; int count; - ath6kl_dbg(ATH6KL_DBG_BOOT, - "sdio new func %d vendor 0x%x device 0x%x block 0x%x/0x%x\n", + ath6kl_dbg(ATH6KL_DBG_SDIO, + "new func %d vendor 0x%x device 0x%x block 0x%x/0x%x\n", func->num, func->vendor, func->device, func->max_blksize, func->cur_blksize); @@ -980,22 +819,57 @@ static int ath6kl_sdio_probe(struct sdio_func *func, ath6kl_sdio_set_mbox_info(ar); - ret = ath6kl_sdio_config(ar); + sdio_claim_host(func); + + if ((ar_sdio->id->device & MANUFACTURER_ID_ATH6KL_BASE_MASK) >= + MANUFACTURER_ID_AR6003_BASE) { + /* enable 4-bit ASYNC interrupt on AR6003 or later */ + ret = ath6kl_sdio_func0_cmd52_wr_byte(func->card, + CCCR_SDIO_IRQ_MODE_REG, + SDIO_IRQ_MODE_ASYNC_4BIT_IRQ); + if (ret) { + ath6kl_err("Failed to enable 4-bit async irq mode %d\n", + ret); + sdio_release_host(func); + goto err_cfg80211; + } + + ath6kl_dbg(ATH6KL_DBG_SDIO, "4-bit async irq mode enabled\n"); + } + + /* give us some time to enable, in ms */ + func->enable_timeout = 100; + + sdio_release_host(func); + + ret = ath6kl_sdio_power_on(ar_sdio); + if (ret) + goto err_cfg80211; + + sdio_claim_host(func); + + ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); if (ret) { - ath6kl_err("Failed to config sdio: %d\n", ret); - goto err_core_alloc; + ath6kl_err("Set sdio block size %d failed: %d)\n", + HIF_MBOX_BLOCK_SIZE, ret); + sdio_release_host(func); + goto err_off; } + sdio_release_host(func); + ret = ath6kl_core_init(ar); if (ret) { ath6kl_err("Failed to init ath6kl core\n"); - goto err_core_alloc; + goto err_off; } return ret; -err_core_alloc: - ath6kl_core_free(ar_sdio->ar); +err_off: + ath6kl_sdio_power_off(ar_sdio); +err_cfg80211: + ath6kl_cfg80211_deinit(ar_sdio->ar); err_dma: kfree(ar_sdio->dma_buffer); err_hif: @@ -1008,8 +882,8 @@ static void ath6kl_sdio_remove(struct sdio_func *func) { struct ath6kl_sdio *ar_sdio; - ath6kl_dbg(ATH6KL_DBG_BOOT, - "sdio removed func %d vendor 0x%x device 0x%x\n", + ath6kl_dbg(ATH6KL_DBG_SDIO, + "removed func %d vendor 0x%x device 0x%x\n", func->num, func->vendor, func->device); ar_sdio = sdio_get_drvdata(func); @@ -1017,7 +891,9 @@ static void ath6kl_sdio_remove(struct sdio_func *func) ath6kl_stop_txrx(ar_sdio->ar); cancel_work_sync(&ar_sdio->wr_async_work); - ath6kl_core_cleanup(ar_sdio->ar); + ath6kl_unavail_ev(ar_sdio->ar); + + ath6kl_sdio_power_off(ar_sdio); kfree(ar_sdio->dma_buffer); kfree(ar_sdio); @@ -1032,11 +908,10 @@ static const struct sdio_device_id ath6kl_sdio_devices[] = { MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices); static struct sdio_driver ath6kl_sdio_driver = { - .name = "ath6kl", + .name = "ath6kl_sdio", .id_table = ath6kl_sdio_devices, .probe = ath6kl_sdio_probe, .remove = ath6kl_sdio_remove, - .drv.pm = ATH6KL_SDIO_PM_OPS, }; static int __init ath6kl_sdio_init(void) diff --git a/trunk/drivers/net/wireless/ath/ath6kl/target.h b/trunk/drivers/net/wireless/ath/ath6kl/target.h index 687e2b350e8f..c9a76051f042 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/target.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/target.h @@ -320,10 +320,7 @@ 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 */ diff --git a/trunk/drivers/net/wireless/ath/ath6kl/txrx.c b/trunk/drivers/net/wireless/ath/ath6kl/txrx.c index d9cff2b950b1..a7117074f81c 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/txrx.c @@ -77,13 +77,12 @@ 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_vif *vif, struct sk_buff *skb, +static bool ath6kl_powersave_ap(struct ath6kl *ar, 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; - struct ath6kl *ar = vif->ar; if (is_multicast_ether_addr(datap->h_dest)) { u8 ctr = 0; @@ -101,7 +100,7 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb, * If this transmit is not because of a Dtim Expiry * q it. */ - if (!test_bit(DTIM_EXPIRED, &vif->flags)) { + if (!test_bit(DTIM_EXPIRED, &ar->flag)) { bool is_mcastq_empty = false; spin_lock_bh(&ar->mcastpsq_lock); @@ -117,7 +116,6 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, 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; @@ -133,7 +131,7 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb, } } } else { - conn = ath6kl_find_sta(vif, datap->h_dest); + conn = ath6kl_find_sta(ar, datap->h_dest); if (!conn) { dev_kfree_skb(skb); @@ -156,7 +154,6 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, 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; @@ -238,7 +235,6 @@ 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 */ @@ -250,7 +246,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, &vif->flags)) { + if (!test_bit(CONNECTED, &ar->flag)) { dev_kfree_skb(skb); return 0; } @@ -259,21 +255,15 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) goto fail_tx; /* AP mode Power saving processing */ - if (vif->nw_type == AP_NETWORK) { - if (ath6kl_powersave_ap(vif, skb, &more_data)) + if (ar->nw_type == AP_NETWORK) { + if (ath6kl_powersave_ap(ar, skb, &more_data)) return 0; } if (test_bit(WMI_ENABLED, &ar->flag)) { if (skb_headroom(skb) < dev->needed_headroom) { - struct sk_buff *tmp_skb = skb; - - skb = skb_realloc_headroom(skb, dev->needed_headroom); - kfree_skb(tmp_skb); - if (skb == NULL) { - vif->net_stats.tx_dropped++; - return 0; - } + WARN_ON(1); + goto fail_tx; } if (ath6kl_wmi_dix_2_dot3(ar->wmi, skb)) { @@ -282,20 +272,18 @@ 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, - vif->fw_vif_idx)) { + more_data, 0, 0, NULL)) { ath6kl_err("wmi_data_hdr_add failed\n"); goto fail_tx; } - if ((vif->nw_type == ADHOC_NETWORK) && - ar->ibss_ps_enable && test_bit(CONNECTED, &vif->flags)) + if ((ar->nw_type == ADHOC_NETWORK) && + ar->ibss_ps_enable && test_bit(CONNECTED, &ar->flag)) chk_adhoc_ps_mapping = true; else { /* get the stream mapping */ - ret = ath6kl_wmi_implicit_create_pstream(ar->wmi, - vif->fw_vif_idx, skb, - 0, test_bit(WMM_ENABLED, &vif->flags), &ac); + ret = ath6kl_wmi_implicit_create_pstream(ar->wmi, skb, + 0, test_bit(WMM_ENABLED, &ar->flag), &ac); if (ret) goto fail_tx; } @@ -366,8 +354,8 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) fail_tx: dev_kfree_skb(skb); - vif->net_stats.tx_dropped++; - vif->net_stats.tx_aborted_errors++; + ar->net_stats.tx_dropped++; + ar->net_stats.tx_aborted_errors++; return 0; } @@ -438,9 +426,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, struct htc_packet *packet) { struct ath6kl *ar = target->dev->ar; - 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) { /* @@ -453,11 +439,19 @@ 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"); - goto stop_adhoc_netq; + return HTC_SEND_FULL_KEEP; } if (packet->info.tx.tag == ATH6KL_CONTROL_PKT_TAG) - goto stop_adhoc_netq; + return HTC_SEND_FULL_KEEP; + + if (ar->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; /* * The last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for @@ -465,43 +459,29 @@ 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. */ - action = HTC_SEND_FULL_DROP; - goto stop_adhoc_netq; - } - -stop_adhoc_netq: - /* FIXME: Locking */ - spin_lock_bh(&ar->list_lock); - list_for_each_entry(vif, &ar->vif_list, list) { - if (vif->nw_type == ADHOC_NETWORK) { - spin_unlock_bh(&ar->list_lock); - - spin_lock_bh(&vif->if_lock); - set_bit(NETQ_STOPPED, &vif->flags); - spin_unlock_bh(&vif->if_lock); - netif_stop_queue(vif->ndev); + return HTC_SEND_FULL_DROP; - return action; - } - } - spin_unlock_bh(&ar->list_lock); +stop_net_queues: + spin_lock_bh(&ar->lock); + set_bit(NETQ_STOPPED, &ar->flag); + spin_unlock_bh(&ar->lock); + netif_stop_queue(ar->net_dev); - return action; + return HTC_SEND_FULL_KEEP; } /* TODO this needs to be looked at */ -static void ath6kl_tx_clear_node_map(struct ath6kl_vif *vif, +static void ath6kl_tx_clear_node_map(struct ath6kl *ar, enum htc_endpoint_id eid, u32 map_no) { - struct ath6kl *ar = vif->ar; u32 i; - if (vif->nw_type != ADHOC_NETWORK) + if (ar->nw_type != ADHOC_NETWORK) return; if (!ar->ibss_ps_enable) @@ -543,9 +523,7 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue) int status; enum htc_endpoint_id eid; bool wake_event = false; - bool flushing[MAX_NUM_VIF] = {false}; - u8 if_idx; - struct ath6kl_vif *vif; + bool flushing = false; skb_queue_head_init(&skb_queue); @@ -591,30 +569,15 @@ 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 */ - flushing[if_idx] = true; - - vif->net_stats.tx_errors++; + flushing = true; - if (status != -ENOSPC && status != -ECANCELED) - ath6kl_warn("tx complete error: %d\n", status); + ar->net_stats.tx_errors++; + if (status != -ENOSPC) + ath6kl_err("tx error, status: 0x%x\n", status); ath6kl_dbg(ATH6KL_DBG_WLAN_TX, "%s: skb=0x%p data=0x%p len=0x%x eid=%d %s\n", __func__, skb, packet->buf, packet->act_len, @@ -625,34 +588,27 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue) __func__, skb, packet->buf, packet->act_len, eid, "OK"); - flushing[if_idx] = false; - vif->net_stats.tx_packets++; - vif->net_stats.tx_bytes += skb->len; + flushing = false; + ar->net_stats.tx_packets++; + ar->net_stats.tx_bytes += skb->len; } - ath6kl_tx_clear_node_map(vif, eid, map_no); + ath6kl_tx_clear_node_map(ar, eid, map_no); ath6kl_free_cookie(ar, ath6kl_cookie); - if (test_bit(NETQ_STOPPED, &vif->flags)) - clear_bit(NETQ_STOPPED, &vif->flags); + if (test_bit(NETQ_STOPPED, &ar->flag)) + clear_bit(NETQ_STOPPED, &ar->flag); } spin_unlock_bh(&ar->lock); __skb_queue_purge(&skb_queue); - /* FIXME: Locking */ - spin_lock_bh(&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_bh(&ar->list_lock); - netif_wake_queue(vif->ndev); - spin_lock_bh(&ar->list_lock); - } + if (test_bit(CONNECTED, &ar->flag)) { + if (!flushing) + netif_wake_queue(ar->net_dev); } - spin_unlock_bh(&ar->list_lock); if (wake_event) wake_up(&ar->event_wq); @@ -1085,9 +1041,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; - struct ath6kl_vif *vif; u16 seq_no, offset; - u8 tid, if_idx; + u8 tid; ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: ar=0x%p eid=%d, skb=0x%p, data=0x%p, len=0x%x status:%d", @@ -1095,23 +1050,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) packet->act_len, status); if (status || !(skb->data + HTC_HDR_LENGTH)) { - 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) { + ar->net_stats.rx_errors++; dev_kfree_skb(skb); return; } @@ -1120,28 +1059,28 @@ 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(&vif->if_lock); + spin_lock_bh(&ar->lock); - vif->net_stats.rx_packets++; - vif->net_stats.rx_bytes += packet->act_len; + ar->net_stats.rx_packets++; + ar->net_stats.rx_bytes += packet->act_len; - spin_unlock_bh(&vif->if_lock); + 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); - skb->dev = vif->ndev; + skb->dev = ar->net_dev; if (!test_bit(WMI_ENABLED, &ar->flag)) { if (EPPING_ALIGNMENT_PAD > 0) skb_pull(skb, EPPING_ALIGNMENT_PAD); - ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb); + ath6kl_deliver_frames_to_nw_stack(ar->net_dev, skb); return; } - ath6kl_check_wow_status(ar); - if (ept == ar->ctrl_ep) { ath6kl_wmi_control_rx(ar->wmi, skb); return; @@ -1157,18 +1096,18 @@ 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 (vif->nw_type != AP_NETWORK && + if (ar->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"); - vif->net_stats.rx_errors++; - vif->net_stats.rx_length_errors++; + ar->net_stats.rx_errors++; + ar->net_stats.rx_length_errors++; dev_kfree_skb(skb); return; } /* Get the Power save state of the STA */ - if (vif->nw_type == AP_NETWORK) { + if (ar->nw_type == AP_NETWORK) { meta_type = wmi_data_hdr_get_meta(dhdr); ps_state = !!((dhdr->info >> WMI_DATA_HDR_PS_SHIFT) & @@ -1190,7 +1129,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) } datap = (struct ethhdr *) (skb->data + offset); - conn = ath6kl_find_sta(vif, datap->h_source); + conn = ath6kl_find_sta(ar, datap->h_source); if (!conn) { dev_kfree_skb(skb); @@ -1221,13 +1160,12 @@ 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, vif->ndev); + ath6kl_data_tx(skbuff, ar->net_dev); spin_lock_bh(&conn->psq_lock); } spin_unlock_bh(&conn->psq_lock); /* Clear the PVB for this STA */ - ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, - conn->aid, 0); + ath6kl_wmi_set_pvb_cmd(ar->wmi, conn->aid, 0); } } @@ -1277,12 +1215,12 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) return; } - if (!(vif->ndev->flags & IFF_UP)) { + if (!(ar->net_dev->flags & IFF_UP)) { dev_kfree_skb(skb); return; } - if (vif->nw_type == AP_NETWORK) { + if (ar->nw_type == AP_NETWORK) { datap = (struct ethhdr *) skb->data; if (is_multicast_ether_addr(datap->h_dest)) /* @@ -1297,7 +1235,8 @@ 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(vif, datap->h_dest); + struct ath6kl_sta *conn = NULL; + conn = ath6kl_find_sta(ar, datap->h_dest); if (conn && ar->intra_bss) { skb1 = skb; @@ -1308,23 +1247,18 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) } } if (skb1) - ath6kl_data_tx(skb1, vif->ndev); - - if (skb == NULL) { - /* nothing to deliver up the stack */ - return; - } + ath6kl_data_tx(skb1, ar->net_dev); } datap = (struct ethhdr *) skb->data; if (is_unicast_ether_addr(datap->h_dest) && - aggr_process_recv_frm(vif->aggr_cntxt, tid, seq_no, + aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no, is_amsdu, skb)) /* aggregation code will handle the skb */ return; - ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb); + ath6kl_deliver_frames_to_nw_stack(ar->net_dev, skb); } static void aggr_timeout(unsigned long arg) @@ -1402,10 +1336,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_vif *vif, u8 tid, u16 seq_no, - u8 win_sz) +void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no, u8 win_sz) { - struct aggr_info *p_aggr = vif->aggr_cntxt; + struct aggr_info *p_aggr = ar->aggr_cntxt; struct rxtid *rxtid; struct rxtid_stats *stats; u16 hold_q_size; @@ -1472,9 +1405,9 @@ struct aggr_info *aggr_init(struct net_device *dev) return p_aggr; } -void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid) +void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid) { - struct aggr_info *p_aggr = vif->aggr_cntxt; + struct aggr_info *p_aggr = ar->aggr_cntxt; struct rxtid *rxtid; if (!p_aggr) diff --git a/trunk/drivers/net/wireless/ath/ath6kl/wmi.c b/trunk/drivers/net/wireless/ath/ath6kl/wmi.c index 922344d3b262..a7de23cbd2c7 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/trunk/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, u8 if_idx); +static int ath6kl_wmi_sync_point(struct wmi *wmi); static const s32 wmi_rate_tbl[][2] = { /* {W/O SGI, with SGI} */ @@ -81,26 +81,6 @@ enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi) return wmi->ep_id; } -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; - - /* FIXME: Locking */ - spin_lock_bh(&ar->list_lock); - list_for_each_entry(vif, &ar->vif_list, list) { - if (vif->fw_vif_idx == if_idx) { - found = vif; - break; - } - } - spin_unlock_bh(&ar->list_lock); - - return found; -} - /* 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. @@ -182,12 +162,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 if_idx) + u8 meta_ver, void *tx_meta_info) { struct wmi_data_hdr *data_hdr; int ret; - if (WARN_ON(skb == NULL || (if_idx > MAX_NUM_VIF - 1))) + if (WARN_ON(skb == NULL)) return -EINVAL; if (tx_meta_info) { @@ -209,7 +189,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 = cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK); + data_hdr->info3 = 0; return 0; } @@ -236,8 +216,7 @@ static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri) return ip_pri; } -int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx, - 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) { @@ -283,12 +262,7 @@ int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx, usr_pri = layer2_priority & 0x7; } - /* - * workaround for WMM S5 - * - * FIXME: wmi->traffic_class is always 100 so this test doesn't - * make sense - */ + /* workaround for WMM S5 */ if ((wmi->traffic_class == WMM_AC_VI) && ((usr_pri == 5) || (usr_pri == 4))) usr_pri = 1; @@ -310,7 +284,7 @@ int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx, 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, if_idx, &cmd); + ath6kl_wmi_create_pstream_cmd(wmi, &cmd); } *ac = traffic_class; @@ -436,14 +410,13 @@ 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, struct ath6kl_vif *vif) + int len) { struct wmi_remain_on_chnl_event *ev; u32 freq; u32 dur; struct ieee80211_channel *chan; struct ath6kl *ar = wmi->parent_dev; - u32 id; if (len < sizeof(*ev)) return -EINVAL; @@ -453,29 +426,26 @@ 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->wiphy, freq); + chan = ieee80211_get_channel(ar->wdev->wiphy, freq); if (!chan) { ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl: Unknown channel " "(freq=%u)\n", freq); return -EINVAL; } - id = vif->last_roc_id; - cfg80211_ready_on_channel(vif->ndev, id, chan, NL80211_CHAN_NO_HT, + cfg80211_ready_on_channel(ar->net_dev, 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, - struct ath6kl_vif *vif) + u8 *datap, int len) { struct wmi_cancel_remain_on_chnl_event *ev; u32 freq; u32 dur; struct ieee80211_channel *chan; struct ath6kl *ar = wmi->parent_dev; - u32 id; if (len < sizeof(*ev)) return -EINVAL; @@ -485,29 +455,23 @@ 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->wiphy, freq); + chan = ieee80211_get_channel(ar->wdev->wiphy, freq); if (!chan) { ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: Unknown " "channel (freq=%u)\n", freq); return -EINVAL; } - if (vif->last_cancel_roc_id && - vif->last_cancel_roc_id + 1 == vif->last_roc_id) - id = vif->last_cancel_roc_id; /* event for cancel command */ - else - id = vif->last_roc_id; /* timeout on uncanceled r-o-c */ - vif->last_cancel_roc_id = 0; - cfg80211_remain_on_channel_expired(vif->ndev, id, chan, + cfg80211_remain_on_channel_expired(ar->net_dev, 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, - struct ath6kl_vif *vif) +static int ath6kl_wmi_tx_status_event_rx(struct wmi *wmi, u8 *datap, int len) { struct wmi_tx_status_event *ev; u32 id; + struct ath6kl *ar = wmi->parent_dev; if (len < sizeof(*ev)) return -EINVAL; @@ -517,7 +481,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(vif->ndev, id, + cfg80211_mgmt_tx_status(ar->net_dev, id, wmi->last_mgmt_tx_frame, wmi->last_mgmt_tx_frame_len, !!ev->ack_status, GFP_ATOMIC); @@ -529,12 +493,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, - struct ath6kl_vif *vif) +static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len) { struct wmi_p2p_rx_probe_req_event *ev; u32 freq; u16 dlen; + struct ath6kl *ar = wmi->parent_dev; if (len < sizeof(*ev)) return -EINVAL; @@ -549,10 +513,10 @@ 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, vif->probe_req_report); + dlen, freq, ar->probe_req_report); - if (vif->probe_req_report || vif->nw_type == AP_NETWORK) - cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC); + if (ar->probe_req_report || ar->nw_type == AP_NETWORK) + cfg80211_rx_mgmt(ar->net_dev, freq, ev->data, dlen, GFP_ATOMIC); return 0; } @@ -572,12 +536,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, - struct ath6kl_vif *vif) +static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len) { struct wmi_rx_action_event *ev; u32 freq; u16 dlen; + struct ath6kl *ar = wmi->parent_dev; if (len < sizeof(*ev)) return -EINVAL; @@ -591,7 +555,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(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC); + cfg80211_rx_mgmt(ar->net_dev, freq, ev->data, dlen, GFP_ATOMIC); return 0; } @@ -656,8 +620,7 @@ 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, u8 if_idx, - enum wmi_cmd_id cmd_id) +static int ath6kl_wmi_simple_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id) { struct sk_buff *skb; int ret; @@ -666,7 +629,7 @@ static int ath6kl_wmi_simple_cmd(struct wmi *wmi, u8 if_idx, if (!skb) return -ENOMEM; - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, cmd_id, NO_SYNC_WMIFLAG); + ret = ath6kl_wmi_cmd_send(wmi, skb, cmd_id, NO_SYNC_WMIFLAG); return ret; } @@ -678,6 +641,7 @@ static int ath6kl_wmi_ready_event_rx(struct wmi *wmi, u8 *datap, int len) if (len < sizeof(struct wmi_ready_event_2)) return -EINVAL; + wmi->ready = true; ath6kl_ready_event(wmi->parent_dev, ev->mac_addr, le32_to_cpu(ev->sw_version), le32_to_cpu(ev->abi_version)); @@ -709,73 +673,32 @@ 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, 0, skb, WMI_SET_ROAM_CTRL_CMDID, - NO_SYNC_WMIFLAG); + ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_ROAM_CTRL_CMDID, NO_SYNC_WMIFLAG); return 0; } -int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid) -{ - struct sk_buff *skb; - struct roam_ctrl_cmd *cmd; - - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - cmd = (struct roam_ctrl_cmd *) skb->data; - memset(cmd, 0, sizeof(*cmd)); - - memcpy(cmd->info.bssid, bssid, ETH_ALEN); - cmd->roam_ctrl = WMI_FORCE_ROAM; - - ath6kl_dbg(ATH6KL_DBG_WMI, "force roam to %pM\n", bssid); - return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID, - NO_SYNC_WMIFLAG); -} - -int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode) -{ - struct sk_buff *skb; - struct roam_ctrl_cmd *cmd; - - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - cmd = (struct roam_ctrl_cmd *) skb->data; - memset(cmd, 0, sizeof(*cmd)); - - cmd->info.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, 0, skb, WMI_SET_ROAM_CTRL_CMDID, - NO_SYNC_WMIFLAG); -} - -static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len, - struct ath6kl_vif *vif) +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; if (len < sizeof(struct wmi_connect_event)) return -EINVAL; ev = (struct wmi_connect_event *) datap; - if (vif->nw_type == AP_NETWORK) { + if (ar->nw_type == AP_NETWORK) { /* AP mode start/STA connected event */ - struct net_device *dev = vif->ndev; + struct net_device *dev = ar->net_dev; 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( - vif, le16_to_cpu(ev->u.ap_bss.ch)); + ar, 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 " @@ -787,7 +710,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( - vif, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr, + ar, 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, @@ -832,7 +755,7 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len, pie += pie[1] + 2; } - ath6kl_connect_event(vif, le16_to_cpu(ev->u.sta.ch), + ath6kl_connect_event(wmi->parent_dev, 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), @@ -911,15 +834,14 @@ 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->wiphy, alpha2); + regulatory_hint(wmi->parent_dev->wdev->wiphy, alpha2); ath6kl_dbg(ATH6KL_DBG_WMI, "Country alpha2 being used: %c%c\n", alpha2[0], alpha2[1]); } } -static int ath6kl_wmi_disconnect_event_rx(struct wmi *wmi, u8 *datap, int len, - struct ath6kl_vif *vif) +static int ath6kl_wmi_disconnect_event_rx(struct wmi *wmi, u8 *datap, int len) { struct wmi_disconnect_event *ev; wmi->traffic_class = 100; @@ -935,8 +857,10 @@ static int ath6kl_wmi_disconnect_event_rx(struct wmi *wmi, u8 *datap, int len, ev->disconn_reason, ev->assoc_resp_len); wmi->is_wmm_enabled = false; + wmi->pair_crypto_type = NONE_CRYPT; + wmi->grp_crypto_type = NONE_CRYPT; - ath6kl_disconnect_event(vif, ev->disconn_reason, + ath6kl_disconnect_event(wmi->parent_dev, ev->disconn_reason, ev->bssid, ev->assoc_resp_len, ev->assoc_info, le16_to_cpu(ev->proto_reason_status)); @@ -962,8 +886,7 @@ 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, - struct ath6kl_vif *vif) +static int ath6kl_wmi_tkip_micerr_event_rx(struct wmi *wmi, u8 *datap, int len) { struct wmi_tkip_micerr_event *ev; @@ -972,13 +895,12 @@ 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(vif, ev->key_id, ev->is_mcast); + ath6kl_tkip_micerr_event(wmi->parent_dev, ev->key_id, ev->is_mcast); return 0; } -static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len, - struct ath6kl_vif *vif) +static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len) { struct wmi_bss_info_hdr2 *bih; u8 *buf; @@ -1005,27 +927,26 @@ 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, &vif->flags)) { - clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); - ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, - NONE_BSS_FILTER, 0); + test_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag)) { + clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag); + ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0); } - channel = ieee80211_get_channel(ar->wiphy, le16_to_cpu(bih->ch)); + channel = ieee80211_get_channel(ar->wdev->wiphy, le16_to_cpu(bih->ch)); if (channel == NULL) return -EINVAL; if (len < 8 + 2 + 2) return -EINVAL; - if (bih->frame_type == BEACON_FTYPE && test_bit(CONNECTED, &vif->flags) - && memcmp(bih->bssid, vif->bssid, ETH_ALEN) == 0) { + if (bih->frame_type == BEACON_FTYPE && test_bit(CONNECTED, &ar->flag) && + 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) { - vif->assoc_bss_dtim_period = tim[3]; - set_bit(DTIM_PERIOD_AVAIL, &vif->flags); + ar->assoc_bss_dtim_period = tim[3]; + set_bit(DTIM_PERIOD_AVAIL, &ar->flag); } } @@ -1045,7 +966,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 = vif->ndev; + struct net_device *dev = ar->net_dev; mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); @@ -1058,7 +979,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->wiphy, channel, mgmt, + bss = cfg80211_inform_bss_frame(ar->wdev->wiphy, channel, mgmt, 24 + len, (bih->snr - 95) * 100, GFP_ATOMIC); kfree(mgmt); @@ -1173,21 +1094,20 @@ 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, - struct ath6kl_vif *vif) +static int ath6kl_wmi_scan_complete_rx(struct wmi *wmi, u8 *datap, int len) { struct wmi_scan_complete_event *ev; ev = (struct wmi_scan_complete_event *) datap; - ath6kl_scan_complete_evt(vif, a_sle32_to_cpu(ev->status)); + ath6kl_scan_complete_evt(wmi->parent_dev, 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, struct ath6kl_vif *vif) + int len) { struct wmi_neighbor_report_event *ev; u8 i; @@ -1205,7 +1125,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(vif->ndev, i, + cfg80211_pmksa_candidate_notify(wmi->parent_dev->net_dev, i, ev->neighbor[i].bssid, !!(ev->neighbor[i].bss_flags & WMI_PREAUTH_CAPABLE_BSS), @@ -1246,10 +1166,9 @@ 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, - struct ath6kl_vif *vif) +static int ath6kl_wmi_stats_event_rx(struct wmi *wmi, u8 *datap, int len) { - ath6kl_tgt_stats_event(vif, datap, len); + ath6kl_tgt_stats_event(wmi->parent_dev, datap, len); return 0; } @@ -1303,7 +1222,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, 0, skb, WMI_RSSI_THRESHOLD_PARAMS_CMDID, + return ath6kl_wmi_cmd_send(wmi, skb, WMI_RSSI_THRESHOLD_PARAMS_CMDID, NO_SYNC_WMIFLAG); } @@ -1403,8 +1322,7 @@ 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, - struct ath6kl_vif *vif) +static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len) { struct wmi_cac_event *reply; struct ieee80211_tspec_ie *ts; @@ -1425,8 +1343,7 @@ 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, vif->fw_vif_idx, - reply->ac, tsid); + ath6kl_wmi_delete_pstream_cmd(wmi, reply->ac, tsid); } else if (reply->cac_indication == CAC_INDICATION_NO_RESP) { /* * Following assumes that there is only one outstanding @@ -1441,8 +1358,7 @@ 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, vif->fw_vif_idx, - reply->ac, index); + ath6kl_wmi_delete_pstream_cmd(wmi, reply->ac, index); } /* @@ -1487,7 +1403,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, 0, skb, WMI_SNR_THRESHOLD_PARAMS_CMDID, + return ath6kl_wmi_cmd_send(wmi, skb, WMI_SNR_THRESHOLD_PARAMS_CMDID, NO_SYNC_WMIFLAG); } @@ -1612,15 +1528,14 @@ static int ath6kl_wmi_aplist_event_rx(struct wmi *wmi, u8 *datap, int len) return 0; } -int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb, +int ath6kl_wmi_cmd_send(struct wmi *wmi, 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_idx > (MAX_NUM_VIF - 1)))) + if (WARN_ON(skb == NULL)) return -EINVAL; ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n", @@ -1639,20 +1554,19 @@ 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, if_idx); + ath6kl_wmi_sync_point(wmi); } skb_push(skb, sizeof(struct wmi_cmd_hdr)); cmd_hdr = (struct wmi_cmd_hdr *) skb->data; cmd_hdr->cmd_id = cpu_to_le16(cmd_id); - info1 = if_idx & WMI_CMD_HDR_IF_ID_MASK; - cmd_hdr->info1 = cpu_to_le16(info1); + cmd_hdr->info1 = 0; /* added for virtual interface */ /* 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, if_idx); + false, false, 0, NULL); if (ret) { dev_kfree_skb(skb); return ret; @@ -1668,14 +1582,13 @@ 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, if_idx); + ath6kl_wmi_sync_point(wmi); } return 0; } -int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx, - enum network_type nw_type, +int ath6kl_wmi_connect_cmd(struct wmi *wmi, enum network_type nw_type, enum dot11_auth_mode dot11_auth_mode, enum auth_mode auth_mode, enum crypto_type pairwise_crypto, @@ -1726,14 +1639,15 @@ int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx, if (bssid != NULL) memcpy(cc->bssid, bssid, ETH_ALEN); - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_CONNECT_CMDID, - NO_SYNC_WMIFLAG); + wmi->pair_crypto_type = pairwise_crypto; + wmi->grp_crypto_type = group_crypto; + + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid, - u16 channel) +int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 *bssid, u16 channel) { struct sk_buff *skb; struct wmi_reconnect_cmd *cc; @@ -1754,13 +1668,13 @@ int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid, if (bssid != NULL) memcpy(cc->bssid, bssid, ETH_ALEN); - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_RECONNECT_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx) +int ath6kl_wmi_disconnect_cmd(struct wmi *wmi) { int ret; @@ -1769,13 +1683,12 @@ int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx) wmi->traffic_class = 100; /* Disconnect command does not need to do a SYNC before. */ - ret = ath6kl_wmi_simple_cmd(wmi, if_idx, WMI_DISCONNECT_CMDID); + ret = ath6kl_wmi_simple_cmd(wmi, WMI_DISCONNECT_CMDID); return ret; } -int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, - enum wmi_scan_type scan_type, +int ath6kl_wmi_startscan_cmd(struct wmi *wmi, 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) @@ -1811,14 +1724,13 @@ int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, for (i = 0; i < num_chan; i++) sc->ch_list[i] = cpu_to_le16(ch_list[i]); - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_START_SCAN_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx, - u16 fg_start_sec, +int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, 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, @@ -1845,12 +1757,12 @@ int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx, 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, if_idx, skb, WMI_SET_SCAN_PARAMS_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_SCAN_PARAMS_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 if_idx, u8 filter, u32 ie_mask) +int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 filter, u32 ie_mask) { struct sk_buff *skb; struct wmi_bss_filter_cmd *cmd; @@ -1867,12 +1779,12 @@ int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 if_idx, u8 filter, u32 ie_mask) cmd->bss_filter = filter; cmd->ie_mask = cpu_to_le32(ie_mask); - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_BSS_FILTER_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_BSS_FILTER_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag, +int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 index, u8 flag, u8 ssid_len, u8 *ssid) { struct sk_buff *skb; @@ -1904,13 +1816,12 @@ int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag, cmd->ssid_len = ssid_len; memcpy(cmd->ssid, ssid, ssid_len); - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_PROBED_SSID_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_PROBED_SSID_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx, - u16 listen_interval, +int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u16 listen_interval, u16 listen_beacons) { struct sk_buff *skb; @@ -1925,12 +1836,12 @@ int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx, cmd->listen_intvl = cpu_to_le16(listen_interval); cmd->num_beacons = cpu_to_le16(listen_beacons); - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_LISTEN_INT_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_LISTEN_INT_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode) +int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 pwr_mode) { struct sk_buff *skb; struct wmi_power_mode_cmd *cmd; @@ -1944,12 +1855,12 @@ int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode) cmd->pwr_mode = pwr_mode; wmi->pwr_mode = pwr_mode; - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_POWER_MODE_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_POWER_MODE_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u8 if_idx, u16 idle_period, +int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u16 idle_period, u16 ps_poll_num, u16 dtim_policy, u16 tx_wakeup_policy, u16 num_tx_to_wakeup, u16 ps_fail_event_policy) @@ -1970,12 +1881,12 @@ int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u8 if_idx, 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, if_idx, skb, WMI_SET_POWER_PARAMS_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_POWER_PARAMS_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 if_idx, u8 timeout) +int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 timeout) { struct sk_buff *skb; struct wmi_disc_timeout_cmd *cmd; @@ -1988,20 +1899,15 @@ int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 if_idx, u8 timeout) cmd = (struct wmi_disc_timeout_cmd *) skb->data; cmd->discon_timeout = timeout; - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_DISC_TIMEOUT_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, 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 if_idx, u8 key_index, +int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index, enum crypto_type key_type, u8 key_usage, u8 key_len, - u8 *key_rsc, unsigned int key_rsc_len, - u8 *key_material, + u8 *key_rsc, u8 *key_material, u8 key_op_ctrl, u8 *mac_addr, enum wmi_sync_flag sync_flag) { @@ -2014,7 +1920,7 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index, key_index, key_type, key_usage, key_len, key_op_ctrl); if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) || - (key_material == NULL) || key_rsc_len > 8) + (key_material == NULL)) return -EINVAL; if ((WEP_CRYPT != key_type) && (NULL == key_rsc)) @@ -2032,20 +1938,20 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index, memcpy(cmd->key, key_material, key_len); if (key_rsc != NULL) - memcpy(cmd->key_rsc, key_rsc, key_rsc_len); + memcpy(cmd->key_rsc, key_rsc, sizeof(cmd->key_rsc)); cmd->key_op_ctrl = key_op_ctrl; if (mac_addr) memcpy(cmd->key_mac_addr, mac_addr, ETH_ALEN); - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_ADD_CIPHER_KEY_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_ADD_CIPHER_KEY_CMDID, sync_flag); return ret; } -int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, u8 *krk) +int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 *krk) { struct sk_buff *skb; struct wmi_add_krk_cmd *cmd; @@ -2058,13 +1964,12 @@ int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, u8 *krk) cmd = (struct wmi_add_krk_cmd *) skb->data; memcpy(cmd->krk, krk, WMI_KRK_LEN); - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_ADD_KRK_CMDID, - NO_SYNC_WMIFLAG); + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index) +int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 key_index) { struct sk_buff *skb; struct wmi_delete_cipher_key_cmd *cmd; @@ -2080,13 +1985,13 @@ int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index) cmd = (struct wmi_delete_cipher_key_cmd *) skb->data; cmd->key_index = key_index; - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_DELETE_CIPHER_KEY_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_DELETE_CIPHER_KEY_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, u8 if_idx, const u8 *bssid, +int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, const u8 *bssid, const u8 *pmkid, bool set) { struct sk_buff *skb; @@ -2113,14 +2018,14 @@ int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, u8 if_idx, const u8 *bssid, cmd->enable = PMKID_DISABLE; } - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_PMKID_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG); return ret; } static int ath6kl_wmi_data_sync_send(struct wmi *wmi, struct sk_buff *skb, - enum htc_endpoint_id ep_id, u8 if_idx) + enum htc_endpoint_id ep_id) { struct wmi_data_hdr *data_hdr; int ret; @@ -2132,14 +2037,14 @@ 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 = cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK); + data_hdr->info3 = 0; ret = ath6kl_control_tx(wmi->parent_dev, skb, ep_id); return ret; } -static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) +static int ath6kl_wmi_sync_point(struct wmi *wmi) { struct sk_buff *skb; struct wmi_sync_cmd *cmd; @@ -2195,7 +2100,7 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) * Send sync cmd followed by sync data messages on all * endpoints being used */ - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SYNCHRONIZE_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SYNCHRONIZE_CMDID, NO_SYNC_WMIFLAG); if (ret) @@ -2214,7 +2119,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, if_idx); + ep_id); if (ret) break; @@ -2237,7 +2142,7 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) return ret; } -int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi, u8 if_idx, +int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi, struct wmi_create_pstream_cmd *params) { struct sk_buff *skb; @@ -2326,13 +2231,12 @@ int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi, u8 if_idx, ath6kl_indicate_tx_activity(wmi->parent_dev, params->traffic_class, true); - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_CREATE_PSTREAM_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_CREATE_PSTREAM_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 if_idx, u8 traffic_class, - u8 tsid) +int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 traffic_class, u8 tsid) { struct sk_buff *skb; struct wmi_delete_pstream_cmd *cmd; @@ -2368,7 +2272,7 @@ int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 if_idx, u8 traffic_class, "sending delete_pstream_cmd: traffic class: %d tsid=%d\n", traffic_class, tsid); - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_DELETE_PSTREAM_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_DELETE_PSTREAM_CMDID, SYNC_BEFORE_WMIFLAG); spin_lock_bh(&wmi->lock); @@ -2407,173 +2311,17 @@ 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, 0, skb, WMI_SET_IP_CMDID, - NO_SYNC_WMIFLAG); - return ret; -} - -static void ath6kl_wmi_relinquish_implicit_pstream_credits(struct wmi *wmi) -{ - u16 active_tsids; - u8 stream_exist; - int i; - - /* - * Relinquish credits from all implicitly created pstreams - * since when we go to sleep. If user created explicit - * thinstreams exists with in a fatpipe leave them intact - * for the user to delete. - */ - spin_lock_bh(&wmi->lock); - stream_exist = wmi->fat_pipe_exist; - spin_unlock_bh(&wmi->lock); - - for (i = 0; i < WMM_NUM_AC; i++) { - if (stream_exist & (1 << i)) { - - /* - * FIXME: Is this lock & unlock inside - * for loop correct? may need rework. - */ - spin_lock_bh(&wmi->lock); - active_tsids = wmi->stream_exist_for_ac[i]; - spin_unlock_bh(&wmi->lock); - - /* - * If there are no user created thin streams - * delete the fatpipe - */ - if (!active_tsids) { - stream_exist &= ~(1 << i); - /* - * Indicate inactivity to driver layer for - * this fatpipe (pstream) - */ - ath6kl_indicate_tx_activity(wmi->parent_dev, - i, false); - } - } - } - - /* FIXME: Can we do this assignment without locking ? */ - spin_lock_bh(&wmi->lock); - wmi->fat_pipe_exist = stream_exist; - spin_unlock_bh(&wmi->lock); -} - -int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, - enum ath6kl_host_mode host_mode) -{ - struct sk_buff *skb; - struct wmi_set_host_sleep_mode_cmd *cmd; - int ret; - - if ((host_mode != ATH6KL_HOST_MODE_ASLEEP) && - (host_mode != ATH6KL_HOST_MODE_AWAKE)) { - ath6kl_err("invalid host sleep mode: %d\n", host_mode); - return -EINVAL; - } - - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - cmd = (struct wmi_set_host_sleep_mode_cmd *) skb->data; - - if (host_mode == ATH6KL_HOST_MODE_ASLEEP) { - ath6kl_wmi_relinquish_implicit_pstream_credits(wmi); - cmd->asleep = cpu_to_le32(1); - } else - cmd->awake = cpu_to_le32(1); - - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, - WMI_SET_HOST_SLEEP_MODE_CMDID, - NO_SYNC_WMIFLAG); + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_IP_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, - enum ath6kl_wow_mode wow_mode, - u32 filter, u16 host_req_delay) +static int ath6kl_wmi_get_wow_list_event_rx(struct wmi *wmi, u8 * datap, + int len) { - struct sk_buff *skb; - struct wmi_set_wow_mode_cmd *cmd; - int ret; - - if ((wow_mode != ATH6KL_WOW_MODE_ENABLE) && - wow_mode != ATH6KL_WOW_MODE_DISABLE) { - ath6kl_err("invalid wow mode: %d\n", wow_mode); + if (len < sizeof(struct wmi_get_wow_list_reply)) return -EINVAL; - } - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - cmd = (struct wmi_set_wow_mode_cmd *) skb->data; - cmd->enable_wow = cpu_to_le32(wow_mode); - cmd->filter = cpu_to_le32(filter); - cmd->host_req_delay = cpu_to_le16(host_req_delay); - - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_WOW_MODE_CMDID, - NO_SYNC_WMIFLAG); - return ret; -} - -int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, - u8 list_id, u8 filter_size, - u8 filter_offset, u8 *filter, u8 *mask) -{ - struct sk_buff *skb; - struct wmi_add_wow_pattern_cmd *cmd; - u16 size; - u8 *filter_mask; - int ret; - - /* - * Allocate additional memory in the buffer to hold - * filter and mask value, which is twice of filter_size. - */ - size = sizeof(*cmd) + (2 * filter_size); - - skb = ath6kl_wmi_get_new_buf(size); - if (!skb) - return -ENOMEM; - - cmd = (struct wmi_add_wow_pattern_cmd *) skb->data; - cmd->filter_list_id = list_id; - cmd->filter_size = filter_size; - cmd->filter_offset = filter_offset; - - memcpy(cmd->filter, filter, filter_size); - - filter_mask = (u8 *) (cmd->filter + filter_size); - memcpy(filter_mask, mask, filter_size); - - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_ADD_WOW_PATTERN_CMDID, - NO_SYNC_WMIFLAG); - - return ret; -} - -int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, - u16 list_id, u16 filter_id) -{ - struct sk_buff *skb; - struct wmi_del_wow_pattern_cmd *cmd; - int ret; - - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - cmd = (struct wmi_del_wow_pattern_cmd *) skb->data; - cmd->filter_list_id = cpu_to_le16(list_id); - cmd->filter_id = cpu_to_le16(filter_id); - - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_DEL_WOW_PATTERN_CMDID, - NO_SYNC_WMIFLAG); - return ret; + return 0; } static int ath6kl_wmi_cmd_send_xtnd(struct wmi *wmi, struct sk_buff *skb, @@ -2588,7 +2336,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, 0, skb, WMI_EXTENSION_CMDID, sync_flag); + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_EXTENSION_CMDID, sync_flag); return ret; } @@ -2631,12 +2379,12 @@ 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, u8 if_idx) +int ath6kl_wmi_get_stats_cmd(struct wmi *wmi) { - return ath6kl_wmi_simple_cmd(wmi, if_idx, WMI_GET_STATISTICS_CMDID); + return ath6kl_wmi_simple_cmd(wmi, WMI_GET_STATISTICS_CMDID); } -int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 if_idx, u8 dbM) +int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM) { struct sk_buff *skb; struct wmi_set_tx_pwr_cmd *cmd; @@ -2649,24 +2397,18 @@ int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 if_idx, u8 dbM) cmd = (struct wmi_set_tx_pwr_cmd *) skb->data; cmd->dbM = dbM; - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_TX_PWR_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi, u8 if_idx) +int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi) { - return ath6kl_wmi_simple_cmd(wmi, if_idx, WMI_GET_TX_PWR_CMDID); + return ath6kl_wmi_simple_cmd(wmi, WMI_GET_TX_PWR_CMDID); } -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 if_idx, u8 status, - u8 preamble_policy) +int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status, u8 preamble_policy) { struct sk_buff *skb; struct wmi_set_lpreamble_cmd *cmd; @@ -2680,7 +2422,7 @@ int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 if_idx, u8 status, cmd->status = status; cmd->preamble_policy = preamble_policy; - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_LPREAMBLE_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_LPREAMBLE_CMDID, NO_SYNC_WMIFLAG); return ret; } @@ -2698,12 +2440,11 @@ 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, 0, skb, WMI_SET_RTS_CMDID, - NO_SYNC_WMIFLAG); + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_RTS_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, u8 if_idx, enum wmi_txop_cfg cfg) +int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg) { struct sk_buff *skb; struct wmi_set_wmm_txop_cmd *cmd; @@ -2719,13 +2460,12 @@ int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, u8 if_idx, enum wmi_txop_cfg cfg) cmd = (struct wmi_set_wmm_txop_cmd *) skb->data; cmd->txop_enable = cfg; - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_WMM_TXOP_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_WMM_TXOP_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 if_idx, - u8 keep_alive_intvl) +int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl) { struct sk_buff *skb; struct wmi_set_keepalive_cmd *cmd; @@ -2737,13 +2477,10 @@ int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 if_idx, cmd = (struct wmi_set_keepalive_cmd *) skb->data; cmd->keep_alive_intvl = keep_alive_intvl; + wmi->keep_alive_intvl = keep_alive_intvl; - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_KEEPALIVE_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_KEEPALIVE_CMDID, NO_SYNC_WMIFLAG); - - if (ret == 0) - ath6kl_debug_set_keepalive(wmi->parent_dev, keep_alive_intvl); - return ret; } @@ -2758,7 +2495,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, 0, skb, WMI_TEST_CMDID, NO_SYNC_WMIFLAG); + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_TEST_CMDID, NO_SYNC_WMIFLAG); return ret; } @@ -2791,31 +2528,28 @@ 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, - struct ath6kl_vif *vif) +static int ath6kl_wmi_addba_req_event_rx(struct wmi *wmi, u8 *datap, int len) { struct wmi_addba_req_event *cmd = (struct wmi_addba_req_event *) datap; - aggr_recv_addba_req_evt(vif, cmd->tid, + aggr_recv_addba_req_evt(wmi->parent_dev, 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, - struct ath6kl_vif *vif) +static int ath6kl_wmi_delba_req_event_rx(struct wmi *wmi, u8 *datap, int len) { struct wmi_delba_event *cmd = (struct wmi_delba_event *) datap; - aggr_recv_delba_req_evt(vif, cmd->tid); + aggr_recv_delba_req_evt(wmi->parent_dev, cmd->tid); return 0; } /* AP mode functions */ -int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, - struct wmi_connect_cmd *p) +int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, struct wmi_connect_cmd *p) { struct sk_buff *skb; struct wmi_connect_cmd *cm; @@ -2828,7 +2562,7 @@ int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, cm = (struct wmi_connect_cmd *) skb->data; memcpy(cm, p, sizeof(*cm)); - res = ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_CONFIG_COMMIT_CMDID, + res = ath6kl_wmi_cmd_send(wmip, 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", @@ -2837,8 +2571,7 @@ int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, return res; } -int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac, - u16 reason) +int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 cmd, const u8 *mac, u16 reason) { struct sk_buff *skb; struct wmi_ap_set_mlme_cmd *cm; @@ -2852,12 +2585,11 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac, cm->reason = cpu_to_le16(reason); cm->cmd = cmd; - return ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_SET_MLME_CMDID, + return ath6kl_wmi_cmd_send(wmip, skb, WMI_AP_SET_MLME_CMDID, NO_SYNC_WMIFLAG); } -static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len, - struct ath6kl_vif *vif) +static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len) { struct wmi_pspoll_event *ev; @@ -2866,21 +2598,19 @@ static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len, ev = (struct wmi_pspoll_event *) datap; - ath6kl_pspoll_event(vif, le16_to_cpu(ev->aid)); + ath6kl_pspoll_event(wmi->parent_dev, le16_to_cpu(ev->aid)); return 0; } -static int ath6kl_wmi_dtimexpiry_event_rx(struct wmi *wmi, u8 *datap, int len, - struct ath6kl_vif *vif) +static int ath6kl_wmi_dtimexpiry_event_rx(struct wmi *wmi, u8 *datap, int len) { - ath6kl_dtimexpiry_event(vif); + ath6kl_dtimexpiry_event(wmi->parent_dev); return 0; } -int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u8 if_idx, u16 aid, - bool flag) +int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag) { struct sk_buff *skb; struct wmi_ap_set_pvb_cmd *cmd; @@ -2895,14 +2625,13 @@ int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u8 if_idx, u16 aid, cmd->rsvd = cpu_to_le16(0); cmd->flag = cpu_to_le32(flag); - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_SET_PVB_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_AP_SET_PVB_CMDID, NO_SYNC_WMIFLAG); return 0; } -int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 if_idx, - u8 rx_meta_ver, +int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_ver, bool rx_dot11_hdr, bool defrag_on_host) { struct sk_buff *skb; @@ -2919,14 +2648,14 @@ int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 if_idx, cmd->meta_ver = rx_meta_ver; /* Delete the local aggr state, on host */ - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_RX_FRAME_FORMAT_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_RX_FRAME_FORMAT_CMDID, NO_SYNC_WMIFLAG); return ret; } -int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type, - const u8 *ie, u8 ie_len) +int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 mgmt_frm_type, const u8 *ie, + u8 ie_len) { struct sk_buff *skb; struct wmi_set_appie_cmd *p; @@ -2941,7 +2670,7 @@ int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type, 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, if_idx, skb, WMI_SET_APPIE_CMDID, + return ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG); } @@ -2959,11 +2688,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, 0, skb, WMI_DISABLE_11B_RATES_CMDID, + return ath6kl_wmi_cmd_send(wmi, skb, WMI_DISABLE_11B_RATES_CMDID, NO_SYNC_WMIFLAG); } -int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq, u32 dur) +int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u32 freq, u32 dur) { struct sk_buff *skb; struct wmi_remain_on_chnl_cmd *p; @@ -2977,12 +2706,12 @@ int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, 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, if_idx, skb, WMI_REMAIN_ON_CHNL_CMDID, + return ath6kl_wmi_cmd_send(wmi, skb, WMI_REMAIN_ON_CHNL_CMDID, NO_SYNC_WMIFLAG); } -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_action_cmd(struct wmi *wmi, u32 id, u32 freq, u32 wait, + const u8 *data, u16 data_len) { struct sk_buff *skb; struct wmi_send_action_cmd *p; @@ -3002,7 +2731,6 @@ int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, } kfree(wmi->last_mgmt_tx_frame); - memcpy(buf, data, data_len); wmi->last_mgmt_tx_frame = buf; wmi->last_mgmt_tx_frame_len = data_len; @@ -3014,13 +2742,13 @@ int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, 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, if_idx, skb, WMI_SEND_ACTION_CMDID, + return ath6kl_wmi_cmd_send(wmi, skb, WMI_SEND_ACTION_CMDID, NO_SYNC_WMIFLAG); } -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_send_probe_response_cmd(struct wmi *wmi, u32 freq, + const u8 *dst, + const u8 *data, u16 data_len) { struct sk_buff *skb; struct wmi_p2p_probe_response_cmd *p; @@ -3036,12 +2764,11 @@ int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, 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, if_idx, skb, - WMI_SEND_PROBE_RESPONSE_CMDID, + return ath6kl_wmi_cmd_send(wmi, skb, WMI_SEND_PROBE_RESPONSE_CMDID, NO_SYNC_WMIFLAG); } -int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, u8 if_idx, bool enable) +int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, bool enable) { struct sk_buff *skb; struct wmi_probe_req_report_cmd *p; @@ -3054,11 +2781,11 @@ int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, u8 if_idx, bool enable) enable); p = (struct wmi_probe_req_report_cmd *) skb->data; p->enable = enable ? 1 : 0; - return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_PROBE_REQ_REPORT_CMDID, + return ath6kl_wmi_cmd_send(wmi, skb, WMI_PROBE_REQ_REPORT_CMDID, NO_SYNC_WMIFLAG); } -int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u8 if_idx, u32 info_req_flags) +int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u32 info_req_flags) { struct sk_buff *skb; struct wmi_get_p2p_info *p; @@ -3071,15 +2798,14 @@ int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u8 if_idx, 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, if_idx, skb, WMI_GET_P2P_INFO_CMDID, + return ath6kl_wmi_cmd_send(wmi, skb, WMI_GET_P2P_INFO_CMDID, NO_SYNC_WMIFLAG); } -int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx) +int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi) { ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl_cmd\n"); - return ath6kl_wmi_simple_cmd(wmi, if_idx, - WMI_CANCEL_REMAIN_ON_CHNL_CMDID); + return ath6kl_wmi_simple_cmd(wmi, WMI_CANCEL_REMAIN_ON_CHNL_CMDID); } static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb) @@ -3092,6 +2818,7 @@ static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb) if (skb->len < sizeof(struct wmix_cmd_hdr)) { ath6kl_err("bad packet 1\n"); + wmi->stat.cmd_len_err++; return -EINVAL; } @@ -3113,6 +2840,7 @@ static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb) break; default: ath6kl_warn("unknown cmd id 0x%x\n", id); + wmi->stat.cmd_id_err++; ret = -EINVAL; break; } @@ -3120,19 +2848,12 @@ static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb) return ret; } -static int ath6kl_wmi_roam_tbl_event_rx(struct wmi *wmi, u8 *datap, int len) -{ - return ath6kl_debug_roam_tbl_event(wmi->parent_dev, datap, len); -} - /* Control Path */ 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; @@ -3142,12 +2863,12 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) if (skb->len < sizeof(struct wmi_cmd_hdr)) { ath6kl_err("bad packet 1\n"); dev_kfree_skb(skb); + wmi->stat.cmd_len_err++; return -EINVAL; } 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)); @@ -3158,15 +2879,6 @@ 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"); @@ -3186,11 +2898,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, vif); + ret = ath6kl_wmi_connect_event_rx(wmi, datap, len); break; case WMI_DISCONNECT_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n"); - ret = ath6kl_wmi_disconnect_event_rx(wmi, datap, len, vif); + ret = ath6kl_wmi_disconnect_event_rx(wmi, datap, len); break; case WMI_PEER_NODE_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PEER_NODE_EVENTID\n"); @@ -3198,11 +2910,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, vif); + ret = ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len); break; case WMI_BSSINFO_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n"); - ret = ath6kl_wmi_bssinfo_event_rx(wmi, datap, len, vif); + ret = ath6kl_wmi_bssinfo_event_rx(wmi, datap, len); break; case WMI_REGDOMAIN_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n"); @@ -3214,12 +2926,11 @@ 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, - vif); + ret = ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len); 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, vif); + ret = ath6kl_wmi_scan_complete_rx(wmi, datap, len); break; case WMI_CMDERROR_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CMDERROR_EVENTID\n"); @@ -3227,7 +2938,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, vif); + ret = ath6kl_wmi_stats_event_rx(wmi, datap, len); break; case WMI_RSSI_THRESHOLD_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RSSI_THRESHOLD_EVENTID\n"); @@ -3242,7 +2953,6 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) break; case WMI_REPORT_ROAM_TBL_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_TBL_EVENTID\n"); - ret = ath6kl_wmi_roam_tbl_event_rx(wmi, datap, len); break; case WMI_EXTENSION_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_EXTENSION_EVENTID\n"); @@ -3250,7 +2960,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, vif); + ret = ath6kl_wmi_cac_event_rx(wmi, datap, len); break; case WMI_CHANNEL_CHANGE_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CHANNEL_CHANGE_EVENTID\n"); @@ -3286,6 +2996,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) break; case WMI_GET_WOW_LIST_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_WOW_LIST_EVENTID\n"); + ret = ath6kl_wmi_get_wow_list_event_rx(wmi, datap, len); break; case WMI_GET_PMKID_LIST_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_PMKID_LIST_EVENTID\n"); @@ -3293,25 +3004,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, vif); + ret = ath6kl_wmi_pspoll_event_rx(wmi, datap, len); break; case WMI_DTIMEXPIRY_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n"); - ret = ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len, vif); + ret = ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len); 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, vif); + ret = ath6kl_wmi_addba_req_event_rx(wmi, datap, len); 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, vif); + ret = ath6kl_wmi_delba_req_event_rx(wmi, datap, len); break; case WMI_REPORT_BTCOEX_CONFIG_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, @@ -3327,21 +3038,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, vif); + ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len); 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, vif); + len); 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, vif); + ret = ath6kl_wmi_tx_status_event_rx(wmi, datap, len); 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, vif); + ret = ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len); break; case WMI_P2P_CAPABILITIES_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_CAPABILITIES_EVENTID\n"); @@ -3349,7 +3060,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, vif); + ret = ath6kl_wmi_rx_action_event_rx(wmi, datap, len); break; case WMI_P2P_INFO_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_INFO_EVENTID\n"); @@ -3357,6 +3068,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) break; default: ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", id); + wmi->stat.cmd_id_err++; ret = -EINVAL; break; } @@ -3366,8 +3078,11 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) return ret; } -void ath6kl_wmi_reset(struct wmi *wmi) +static void ath6kl_wmi_qos_state_init(struct wmi *wmi) { + if (!wmi) + return; + spin_lock_bh(&wmi->lock); wmi->fat_pipe_exist = 0; @@ -3388,9 +3103,16 @@ void *ath6kl_wmi_init(struct ath6kl *dev) wmi->parent_dev = dev; + ath6kl_wmi_qos_state_init(wmi); + wmi->pwr_mode = REC_POWER; + wmi->phy_mode = WMI_11G_MODE; + + wmi->pair_crypto_type = NONE_CRYPT; + wmi->grp_crypto_type = NONE_CRYPT; - ath6kl_wmi_reset(wmi); + wmi->ht_allowed[A_BAND_24GHZ] = 1; + wmi->ht_allowed[A_BAND_5GHZ] = 1; return wmi; } diff --git a/trunk/drivers/net/wireless/ath/ath6kl/wmi.h b/trunk/drivers/net/wireless/ath/ath6kl/wmi.h index 76342d5a1906..f8e644d54aa7 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/wmi.h @@ -93,6 +93,11 @@ struct sq_threshold_params { u8 last_rssi_poll_event; }; +struct wmi_stats { + u32 cmd_len_err; + u32 cmd_id_err; +}; + struct wmi_data_sync_bufs { u8 traffic_class; struct sk_buff *skb; @@ -106,26 +111,32 @@ struct wmi_data_sync_bufs { #define WMM_AC_VO 3 /* voice */ struct wmi { + bool ready; u16 stream_exist_for_ac[WMM_NUM_AC]; u8 fat_pipe_exist; struct ath6kl *parent_dev; + struct wmi_stats stat; u8 pwr_mode; + u8 phy_mode; + u8 keep_alive_intvl; spinlock_t lock; enum htc_endpoint_id ep_id; struct sq_threshold_params sq_threshld[SIGNAL_QUALITY_METRICS_NUM_MAX]; + enum crypto_type pair_crypto_type; + enum crypto_type grp_crypto_type; bool is_wmm_enabled; + u8 ht_allowed[A_NUM_BANDS]; u8 traffic_class; bool is_probe_ssid; u8 *last_mgmt_tx_frame; size_t last_mgmt_tx_frame_len; - u8 saved_pwr_mode; }; struct host_app_area { - __le32 wmi_protocol_ver; -} __packed; + u32 wmi_protocol_ver; +}; enum wmi_msg_type { DATA_MSGTYPE = 0x0, @@ -173,8 +184,6 @@ 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; @@ -199,12 +208,6 @@ 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; @@ -247,11 +250,6 @@ 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 @@ -301,8 +299,6 @@ 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; @@ -316,11 +312,6 @@ 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, @@ -585,6 +576,9 @@ enum auth_mode { WPA2_AUTH_CCKM = 0x40, }; +#define WMI_MIN_CRYPTO_TYPE NONE_CRYPT +#define WMI_MAX_CRYPTO_TYPE (AES_CRYPT + 1) + #define WMI_MIN_KEY_INDEX 0 #define WMI_MAX_KEY_INDEX 3 @@ -623,7 +617,6 @@ enum wmi_connect_ctrl_flags_bits { CONNECT_CSA_FOLLOW_BSS = 0x0020, CONNECT_DO_WPA_OFFLOAD = 0x0040, CONNECT_DO_NOT_DEAUTH = 0x0080, - CONNECT_WPS_FLAG = 0x0100, }; struct wmi_connect_cmd { @@ -1372,20 +1365,14 @@ enum wmi_roam_ctrl { WMI_SET_LRSSI_SCAN_PARAMS, }; -enum wmi_roam_mode { - WMI_DEFAULT_ROAM_MODE = 1, /* RSSI based roam */ - WMI_HOST_BIAS_ROAM_MODE = 2, /* Host bias based roam */ - WMI_LOCK_BSS_MODE = 3, /* Lock to the current BSS */ -}; - struct bss_bias { u8 bssid[ETH_ALEN]; - s8 bias; + u8 bias; } __packed; struct bss_bias_info { u8 num_bss; - struct bss_bias bss_bias[0]; + struct bss_bias bss_bias[1]; } __packed; struct low_rssi_scan_params { @@ -1398,11 +1385,10 @@ struct low_rssi_scan_params { struct roam_ctrl_cmd { union { - u8 bssid[ETH_ALEN]; /* WMI_FORCE_ROAM */ - u8 roam_mode; /* WMI_SET_ROAM_MODE */ - struct bss_bias_info bss; /* WMI_SET_HOST_BIAS */ - struct low_rssi_scan_params params; /* WMI_SET_LRSSI_SCAN_PARAMS - */ + u8 bssid[ETH_ALEN]; + u8 roam_mode; + struct bss_bias_info bss; + struct low_rssi_scan_params params; } __packed info; u8 roam_ctrl; } __packed; @@ -1469,10 +1455,6 @@ struct wmi_tkip_micerr_event { u8 is_mcast; } __packed; -enum wmi_scan_status { - WMI_SCAN_STATUS_SUCCESS = 0, -}; - /* WMI_SCAN_COMPLETE_EVENTID */ struct wmi_scan_complete_event { a_sle32 status; @@ -1653,12 +1635,6 @@ struct wmi_bss_roam_info { u8 reserved; } __packed; -struct wmi_target_roam_tbl { - __le16 roam_mode; - __le16 num_entries; - struct wmi_bss_roam_info info[]; -} __packed; - /* WMI_CAC_EVENTID */ enum cac_indication { CAC_INDICATION_ADMISSION = 0x00, @@ -1795,6 +1771,7 @@ struct wmi_set_appie_cmd { #define WSC_REG_ACTIVE 1 #define WSC_REG_INACTIVE 0 +#define WOW_MAX_FILTER_LISTS 1 #define WOW_MAX_FILTERS_PER_LIST 4 #define WOW_PATTERN_SIZE 64 #define WOW_MASK_SIZE 64 @@ -1817,52 +1794,17 @@ struct wmi_set_ip_cmd { __le32 ips[MAX_IP_ADDRS]; } __packed; -enum ath6kl_wow_filters { - WOW_FILTER_SSID = BIT(0), - WOW_FILTER_OPTION_MAGIC_PACKET = BIT(2), - WOW_FILTER_OPTION_EAP_REQ = BIT(3), - WOW_FILTER_OPTION_PATTERNS = BIT(4), - WOW_FILTER_OPTION_OFFLOAD_ARP = BIT(5), - WOW_FILTER_OPTION_OFFLOAD_NS = BIT(6), - WOW_FILTER_OPTION_OFFLOAD_GTK = BIT(7), - WOW_FILTER_OPTION_8021X_4WAYHS = BIT(8), - WOW_FILTER_OPTION_NLO_DISCVRY = BIT(9), - WOW_FILTER_OPTION_NWK_DISASSOC = BIT(10), - WOW_FILTER_OPTION_GTK_ERROR = BIT(11), - WOW_FILTER_OPTION_TEST_MODE = BIT(15), -}; +/* WMI_GET_WOW_LIST_CMD reply */ +struct wmi_get_wow_list_reply { + /* number of patterns in reply */ + u8 num_filters; -enum ath6kl_host_mode { - ATH6KL_HOST_MODE_AWAKE, - ATH6KL_HOST_MODE_ASLEEP, -}; - -struct wmi_set_host_sleep_mode_cmd { - __le32 awake; - __le32 asleep; -} __packed; - -enum ath6kl_wow_mode { - ATH6KL_WOW_MODE_DISABLE, - ATH6KL_WOW_MODE_ENABLE, -}; - -struct wmi_set_wow_mode_cmd { - __le32 enable_wow; - __le32 filter; - __le16 host_req_delay; -} __packed; - -struct wmi_add_wow_pattern_cmd { - u8 filter_list_id; - u8 filter_size; - u8 filter_offset; - u8 filter[0]; -} __packed; + /* this is filter # x of total num_filters */ + u8 this_filter_num; -struct wmi_del_wow_pattern_cmd { - __le16 filter_list_id; - __le16 filter_id; + u8 wow_mode; + u8 host_mode; + struct wow_filter wow_filters[1]; } __packed; /* WMI_SET_AKMP_PARAMS_CMD */ @@ -2221,21 +2163,20 @@ 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 if_idx); + u8 meta_ver, void *tx_meta_info); 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, u8 if_idx, - struct sk_buff *skb, u32 layer2_priority, - bool wmm_enabled, u8 *ac); +int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb, + u32 layer2_priority, bool wmm_enabled, + u8 *ac); int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb); -int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb, +int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb, enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag); -int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx, - enum network_type nw_type, +int ath6kl_wmi_connect_cmd(struct wmi *wmi, enum network_type nw_type, enum dot11_auth_mode dot11_auth_mode, enum auth_mode auth_mode, enum crypto_type pairwise_crypto, @@ -2244,124 +2185,98 @@ int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx, 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 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, +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, 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, u8 if_idx, u16 fg_start_sec, +int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, 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 if_idx, u8 filter, - u32 ie_mask); -int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag, +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, u8 ssid_len, u8 *ssid); -int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx, - u16 listen_interval, +int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, 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, u8 if_idx, u16 idle_period, +int ath6kl_wmi_powermode_cmd(struct wmi *wmi, 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, u16 ps_fail_event_policy); -int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi, u8 if_idx, +int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 timeout); +int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi, 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_delete_pstream_cmd(struct wmi *wmi, 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 if_idx, u8 status, +int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status, u8 preamble_policy); 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, u8 if_idx); -int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index, +int ath6kl_wmi_get_stats_cmd(struct wmi *wmi); +int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index, enum crypto_type key_type, u8 key_usage, u8 key_len, - u8 *key_rsc, unsigned int key_rsc_len, - u8 *key_material, + 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 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, +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, const u8 *pmkid, bool set); -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_tx_pwr_cmd(struct wmi *wmi, u8 dbM); +int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi); -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_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_test_cmd(struct wmi *wmi, void *buf, size_t len); s32 ath6kl_wmi_get_rate(s8 rate_index); int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd); -int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, - enum ath6kl_host_mode host_mode); -int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, - enum ath6kl_wow_mode wow_mode, - u32 filter, u16 host_req_delay); -int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, - u8 list_id, u8 filter_size, - u8 filter_offset, u8 *filter, u8 *mask); -int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, - u16 list_id, u16 filter_id); int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); -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, u8 if_idx, - struct wmi_connect_cmd *p); +int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, struct wmi_connect_cmd *p); -int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, - const u8 *mac, u16 reason); +int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 cmd, const u8 *mac, u16 reason); -int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u8 if_idx, u16 aid, bool flag); +int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag); -int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 if_idx, - u8 rx_meta_version, +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 if_idx, u8 mgmt_frm_type, - const u8 *ie, u8 ie_len); +int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, 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, u8 if_idx, u32 freq, - u32 dur); +int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u32 freq, u32 dur); -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_action_cmd(struct wmi *wmi, u32 id, u32 freq, u32 wait, + 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_send_probe_response_cmd(struct wmi *wmi, u32 freq, + const u8 *dst, + const u8 *data, u16 data_len); -int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, u8 if_idx, bool enable); +int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, bool enable); -int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u8 if_idx, u32 info_req_flags); +int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u32 info_req_flags); -int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx); +int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi); -int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type, - const u8 *ie, u8 ie_len); +int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, 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); -void ath6kl_wmi_reset(struct wmi *wmi); #endif /* WMI_H */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/btcoex.c b/trunk/drivers/net/wireless/ath/ath9k/btcoex.c index 5a6361da9818..6635c377dc00 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/trunk/drivers/net/wireless/ath/ath9k/btcoex.c @@ -35,20 +35,6 @@ struct ath_btcoex_config { bool bt_hold_rx_clear; }; -static const u32 ar9003_wlan_weights[ATH_BTCOEX_STOMP_MAX] - [AR9300_NUM_WLAN_WEIGHTS] = { - { 0xfffffff0, 0xfffffff0, 0xfffffff0, 0xfffffff0 }, /* STOMP_ALL */ - { 0x88888880, 0x88888880, 0x88888880, 0x88888880 }, /* STOMP_LOW */ - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* STOMP_NONE */ -}; - -static const u32 ar9462_wlan_weights[ATH_BTCOEX_STOMP_MAX] - [AR9300_NUM_WLAN_WEIGHTS] = { - { 0x01017d01, 0x41414101, 0x41414101, 0x41414141 }, /* STOMP_ALL */ - { 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */ - { 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */ - { 0x01017d01, 0x013b0101, 0x3b3b0101, 0x3b3b013b }, /* STOMP_LOW_FTP */ -}; void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) { @@ -165,26 +151,27 @@ EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) { - struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; + struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; u32 val; - int i; /* * Program coex mode and weight registers to * enable coex 3-wire */ - REG_WRITE(ah, AR_BT_COEX_MODE, btcoex->bt_coex_mode); - REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex->bt_coex_mode2); + REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_hw->bt_coex_mode); + REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2); if (AR_SREV_9300_20_OR_LATER(ah)) { - REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, btcoex->wlan_weight[0]); - REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, btcoex->wlan_weight[1]); - for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) - REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS(i), - btcoex->bt_weight[i]); + REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, ah->bt_coex_wlan_weight[0]); + REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, ah->bt_coex_wlan_weight[1]); + REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, ah->bt_coex_bt_weight[0]); + REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, ah->bt_coex_bt_weight[1]); + REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, ah->bt_coex_bt_weight[2]); + REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, ah->bt_coex_bt_weight[3]); + } else - REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex->bt_coex_weights); + REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights); @@ -197,23 +184,10 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1); REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0); - ath9k_hw_cfg_output(ah, btcoex->wlanactive_gpio, + ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio, AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL); } -static void ath9k_hw_btcoex_enable_mci(struct ath_hw *ah) -{ - struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; - int i; - - for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) - REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i), - btcoex->wlan_weight[i]); - - REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1); - btcoex->enabled = true; -} - void ath9k_hw_btcoex_enable(struct ath_hw *ah) { struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; @@ -227,9 +201,6 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah) case ATH_BTCOEX_CFG_3WIRE: ath9k_hw_btcoex_enable_3wire(ah); break; - case ATH_BTCOEX_CFG_MCI: - ath9k_hw_btcoex_enable_mci(ah); - return; } REG_RMW(ah, AR_GPIO_PDPU, @@ -243,15 +214,7 @@ EXPORT_SYMBOL(ath9k_hw_btcoex_enable); void ath9k_hw_btcoex_disable(struct ath_hw *ah) { struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; - int i; - - btcoex_hw->enabled = false; - if (btcoex_hw->scheme == ATH_BTCOEX_CFG_MCI) { - ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); - for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) - REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i), - btcoex_hw->wlan_weight[i]); - } + ath9k_hw_set_gpio(ah, btcoex_hw->wlanactive_gpio, 0); ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio, @@ -264,27 +227,49 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah) if (AR_SREV_9300_20_OR_LATER(ah)) { REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, 0); REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, 0); - for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) - REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS(i), 0); + REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, 0); + REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, 0); + REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, 0); + REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, 0); } else REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0); } + + ah->btcoex_hw.enabled = false; } EXPORT_SYMBOL(ath9k_hw_btcoex_disable); static void ar9003_btcoex_bt_stomp(struct ath_hw *ah, enum ath_stomp_type stomp_type) { - struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; - const u32 *weight = AR_SREV_9462(ah) ? ar9003_wlan_weights[stomp_type] : - ar9462_wlan_weights[stomp_type]; - int i; - - for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) { - btcoex->bt_weight[i] = AR9300_BT_WGHT; - btcoex->wlan_weight[i] = weight[i]; + ah->bt_coex_bt_weight[0] = AR9300_BT_WGHT; + ah->bt_coex_bt_weight[1] = AR9300_BT_WGHT; + ah->bt_coex_bt_weight[2] = AR9300_BT_WGHT; + ah->bt_coex_bt_weight[3] = AR9300_BT_WGHT; + + + switch (stomp_type) { + case ATH_BTCOEX_STOMP_ALL: + ah->bt_coex_wlan_weight[0] = AR9300_STOMP_ALL_WLAN_WGHT0; + ah->bt_coex_wlan_weight[1] = AR9300_STOMP_ALL_WLAN_WGHT1; + break; + case ATH_BTCOEX_STOMP_LOW: + ah->bt_coex_wlan_weight[0] = AR9300_STOMP_LOW_WLAN_WGHT0; + ah->bt_coex_wlan_weight[1] = AR9300_STOMP_LOW_WLAN_WGHT1; + break; + case ATH_BTCOEX_STOMP_NONE: + ah->bt_coex_wlan_weight[0] = AR9300_STOMP_NONE_WLAN_WGHT0; + ah->bt_coex_wlan_weight[1] = AR9300_STOMP_NONE_WLAN_WGHT1; + break; + + default: + ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, + "Invalid Stomptype\n"); + break; } + + ath9k_hw_btcoex_enable(ah); } /* @@ -316,5 +301,7 @@ void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, "Invalid Stomptype\n"); break; } + + ath9k_hw_btcoex_enable(ah); } EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp); diff --git a/trunk/drivers/net/wireless/ath/ath9k/btcoex.h b/trunk/drivers/net/wireless/ath/ath9k/btcoex.h index d5e5db1faad9..234f77689b14 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/trunk/drivers/net/wireless/ath/ath9k/btcoex.h @@ -36,22 +36,18 @@ #define ATH_BT_CNT_THRESHOLD 3 #define ATH_BT_CNT_SCAN_THRESHOLD 15 -#define AR9300_NUM_BT_WEIGHTS 4 -#define AR9300_NUM_WLAN_WEIGHTS 4 /* Defines the BT AR_BT_COEX_WGHT used */ enum ath_stomp_type { + ATH_BTCOEX_NO_STOMP, ATH_BTCOEX_STOMP_ALL, ATH_BTCOEX_STOMP_LOW, - ATH_BTCOEX_STOMP_NONE, - ATH_BTCOEX_STOMP_LOW_FTP, - ATH_BTCOEX_STOMP_MAX + ATH_BTCOEX_STOMP_NONE }; enum ath_btcoex_scheme { ATH_BTCOEX_CFG_NONE, ATH_BTCOEX_CFG_2WIRE, ATH_BTCOEX_CFG_3WIRE, - ATH_BTCOEX_CFG_MCI, }; struct ath_btcoex_hw { @@ -63,8 +59,6 @@ struct ath_btcoex_hw { u32 bt_coex_mode; /* Register setting for AR_BT_COEX_MODE */ u32 bt_coex_weights; /* Register setting for AR_BT_COEX_WEIGHT */ u32 bt_coex_mode2; /* Register setting for AR_BT_COEX_MODE2 */ - u32 bt_weight[AR9300_NUM_BT_WEIGHTS]; - u32 wlan_weight[AR9300_NUM_WLAN_WEIGHTS]; }; void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah); diff --git a/trunk/drivers/net/wireless/ath/ath9k/gpio.c b/trunk/drivers/net/wireless/ath/ath9k/gpio.c index e4ae08e07719..2c279dcaf4ba 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/gpio.c +++ b/trunk/drivers/net/wireless/ath/ath9k/gpio.c @@ -198,7 +198,6 @@ static void ath_btcoex_period_timer(unsigned long data) ath9k_hw_btcoex_bt_stomp(ah, is_btscan ? ATH_BTCOEX_STOMP_ALL : btcoex->bt_stomp_type); - ath9k_hw_btcoex_enable(ah); spin_unlock_bh(&btcoex->btcoex_lock); if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) { @@ -241,7 +240,6 @@ static void ath_btcoex_no_stomp_timer(void *arg) else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); - ath9k_hw_btcoex_enable(ah); spin_unlock_bh(&btcoex->btcoex_lock); ath9k_ps_restore(sc); } diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index ce606b618e0b..e3a02eb8e0cc 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -80,7 +80,6 @@ static void ath_btcoex_period_work(struct work_struct *work) ath9k_hw_btcoex_bt_stomp(priv->ah, is_btscan ? ATH_BTCOEX_STOMP_ALL : btcoex->bt_stomp_type); - ath9k_hw_btcoex_enable(priv->ah); timer_period = is_btscan ? btcoex->btscan_no_stomp : btcoex->btcoex_no_stomp; ieee80211_queue_delayed_work(priv->hw, &priv->duty_cycle_work, @@ -109,7 +108,6 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work) ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); - ath9k_hw_btcoex_enable(priv->ah); } void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv) diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.h b/trunk/drivers/net/wireless/ath/ath9k/hw.h index 3cb878c28ccf..33e8f2f9d425 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.h +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.h @@ -59,6 +59,9 @@ #define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa #define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab +#define AR9300_NUM_BT_WEIGHTS 4 +#define AR9300_NUM_WLAN_WEIGHTS 4 + #define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1) #define ATH_DEFAULT_NOISE_FLOOR -95 @@ -799,6 +802,8 @@ struct ath_hw { /* Bluetooth coexistance */ struct ath_btcoex_hw btcoex_hw; + u32 bt_coex_bt_weight[AR9300_NUM_BT_WEIGHTS]; + u32 bt_coex_wlan_weight[AR9300_NUM_WLAN_WEIGHTS]; u32 intr_txqs; u8 txchainmask; diff --git a/trunk/drivers/net/wireless/ath/ath9k/reg.h b/trunk/drivers/net/wireless/ath/ath9k/reg.h index 45910975d853..8fcb7e9e8399 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/reg.h +++ b/trunk/drivers/net/wireless/ath/ath9k/reg.h @@ -1752,10 +1752,19 @@ enum { #define AR_BT_COEX_WL_WEIGHTS0 0x8174 #define AR_BT_COEX_WL_WEIGHTS1 0x81c4 -#define AR_MCI_COEX_WL_WEIGHTS(_i) (0x18b0 + (_i << 2)) -#define AR_BT_COEX_BT_WEIGHTS(_i) (0x83ac + (_i << 2)) -#define AR9300_BT_WGHT 0xcccc4444 +#define AR_BT_COEX_BT_WEIGHTS0 0x83ac +#define AR_BT_COEX_BT_WEIGHTS1 0x83b0 +#define AR_BT_COEX_BT_WEIGHTS2 0x83b4 +#define AR_BT_COEX_BT_WEIGHTS3 0x83b8 + +#define AR9300_BT_WGHT 0xcccc4444 +#define AR9300_STOMP_ALL_WLAN_WGHT0 0xfffffff0 +#define AR9300_STOMP_ALL_WLAN_WGHT1 0xfffffff0 +#define AR9300_STOMP_LOW_WLAN_WGHT0 0x88888880 +#define AR9300_STOMP_LOW_WLAN_WGHT1 0x88888880 +#define AR9300_STOMP_NONE_WLAN_WGHT0 0x00000000 +#define AR9300_STOMP_NONE_WLAN_WGHT1 0x00000000 #define AR_BT_COEX_MODE2 0x817c #define AR_BT_BCN_MISS_THRESH 0x000000ff diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c index 39e305443d7e..025fa0eb6f47 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c @@ -16,8 +16,6 @@ * File contents: support functions for PCI/PCIe */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include @@ -351,9 +349,9 @@ #define PCI_FORCEHT(si) (PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID)) #ifdef BCMDBG -#define SI_MSG(fmt, ...) pr_debug(fmt, ##__VA_ARGS__) +#define SI_MSG(args) printk args #else -#define SI_MSG(fmt, ...) no_printk(fmt, ##__VA_ARGS__) +#define SI_MSG(args) #endif /* BCMDBG */ #define GOODCOREADDR(x, b) \ @@ -1075,7 +1073,7 @@ static struct si_info *ai_doattach(struct si_info *sii, /* scan for cores */ if (socitype == SOCI_AI) { - SI_MSG("Found chip type AI (0x%08x)\n", w); + SI_MSG(("Found chip type AI (0x%08x)\n", w)); /* pass chipc address instead of original core base */ ai_scan(&sii->pub, cc); } else { @@ -1131,7 +1129,7 @@ static struct si_info *ai_doattach(struct si_info *sii, * set chipControl register bit 15 */ if (sih->chiprev == 0) { - SI_MSG("Applying 43224A0 WARs\n"); + SI_MSG(("Applying 43224A0 WARs\n")); ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, chipcontrol), CCTRL43224_GPIO_TOGGLE, @@ -1140,7 +1138,7 @@ static struct si_info *ai_doattach(struct si_info *sii, CCTRL_43224A0_12MA_LED_DRIVE); } if (sih->chiprev >= 1) { - SI_MSG("Applying 43224B0+ WARs\n"); + SI_MSG(("Applying 43224B0+ WARs\n")); si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE, CCTRL_43224B0_12MA_LED_DRIVE); } @@ -1151,7 +1149,7 @@ static struct si_info *ai_doattach(struct si_info *sii, * enable 12 mA drive strenth for 4313 and * set chipControl register bit 1 */ - SI_MSG("Applying 4313 WARs\n"); + SI_MSG(("Applying 4313 WARs\n")); si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE, CCTRL_4313_12MA_LED_DRIVE); } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.c index 0bb8c37e979e..e286fb4d4813 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.c @@ -13,9 +13,6 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -171,25 +168,26 @@ /* debug/trace */ #ifdef BCMDBG -#define DMA_ERROR(fmt, ...) \ -do { \ - if (*di->msg_level & 1) \ - pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \ -} while (0) -#define DMA_TRACE(fmt, ...) \ -do { \ - if (*di->msg_level & 2) \ - pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \ -} while (0) +#define DMA_ERROR(args) \ + do { \ + if (!(*di->msg_level & 1)) \ + ; \ + else \ + printk args; \ + } while (0) +#define DMA_TRACE(args) \ + do { \ + if (!(*di->msg_level & 2)) \ + ; \ + else \ + printk args; \ + } while (0) #else -#define DMA_ERROR(fmt, ...) \ - no_printk(fmt, ##__VA_ARGS__) -#define DMA_TRACE(fmt, ...) \ - no_printk(fmt, ##__VA_ARGS__) +#define DMA_ERROR(args) +#define DMA_TRACE(args) #endif /* BCMDBG */ -#define DMA_NONE(fmt, ...) \ - no_printk(fmt, ##__VA_ARGS__) +#define DMA_NONE(args) #define MAXNAMEL 8 /* 8 char names */ @@ -363,7 +361,7 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags) uint dmactrlflags; if (di == NULL) { - DMA_ERROR("NULL dma handle\n"); + DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n")); return 0; } @@ -414,13 +412,13 @@ static bool _dma_isaddrext(struct dma_info *di) /* not all tx or rx channel are available */ if (di->d64txregs != NULL) { if (!_dma64_addrext(di->d64txregs)) - DMA_ERROR("%s: DMA64 tx doesn't have AE set\n", - di->name); + DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have " + "AE set\n", di->name)); return true; } else if (di->d64rxregs != NULL) { if (!_dma64_addrext(di->d64rxregs)) - DMA_ERROR("%s: DMA64 rx doesn't have AE set\n", - di->name); + DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have " + "AE set\n", di->name)); return true; } @@ -521,8 +519,8 @@ static bool dma64_alloc(struct dma_info *di, uint direction) va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, &alloced, &di->txdpaorig); if (va == NULL) { - DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n", - di->name); + DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd)" + " failed\n", di->name)); return false; } align = (1 << align_bits); @@ -535,8 +533,8 @@ static bool dma64_alloc(struct dma_info *di, uint direction) va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, &alloced, &di->rxdpaorig); if (va == NULL) { - DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n", - di->name); + DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd)" + " failed\n", di->name)); return false; } align = (1 << align_bits); @@ -585,10 +583,11 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, */ _dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0); - DMA_TRACE("%s: %s flags 0x%x ntxd %d nrxd %d rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d dmaregstx %p dmaregsrx %p\n", - name, "DMA64", - di->dma.dmactrlflags, ntxd, nrxd, rxbufsize, - rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx); + DMA_TRACE(("%s: dma_attach: %s flags 0x%x ntxd %d nrxd %d " + "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " + "dmaregstx %p dmaregsrx %p\n", name, "DMA64", + di->dma.dmactrlflags, ntxd, nrxd, rxbufsize, + rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx)); /* make a private copy of our callers name */ strncpy(di->name, name, MAXNAMEL); @@ -646,8 +645,8 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, di->dmadesc_align = 4; /* 16 byte alignment */ } - DMA_NONE("DMA descriptor align_needed %d, align %d\n", - di->aligndesc_4k, di->dmadesc_align); + DMA_NONE(("DMA descriptor align_needed %d, align %d\n", + di->aligndesc_4k, di->dmadesc_align)); /* allocate tx packet pointer vector */ if (ntxd) { @@ -685,21 +684,21 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, if ((di->ddoffsetlow != 0) && !di->addrext) { if (di->txdpa > SI_PCI_DMA_SZ) { - DMA_ERROR("%s: txdpa 0x%x: addrext not supported\n", - di->name, (u32)di->txdpa); + DMA_ERROR(("%s: dma_attach: txdpa 0x%x: addrext not " + "supported\n", di->name, (u32)di->txdpa)); goto fail; } if (di->rxdpa > SI_PCI_DMA_SZ) { - DMA_ERROR("%s: rxdpa 0x%x: addrext not supported\n", - di->name, (u32)di->rxdpa); + DMA_ERROR(("%s: dma_attach: rxdpa 0x%x: addrext not " + "supported\n", di->name, (u32)di->rxdpa)); goto fail; } } - DMA_TRACE("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n", - di->ddoffsetlow, di->ddoffsethigh, - di->dataoffsetlow, di->dataoffsethigh, - di->addrext); + DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x " + "dataoffsethigh " "0x%x addrext %d\n", di->ddoffsetlow, + di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh, + di->addrext)); return (struct dma_pub *) di; @@ -745,7 +744,7 @@ void dma_detach(struct dma_pub *pub) { struct dma_info *di = (struct dma_info *)pub; - DMA_TRACE("%s:\n", di->name); + DMA_TRACE(("%s: dma_detach\n", di->name)); /* free dma descriptor rings */ if (di->txd64) @@ -813,7 +812,7 @@ static void _dma_rxenable(struct dma_info *di) uint dmactrlflags = di->dma.dmactrlflags; u32 control; - DMA_TRACE("%s:\n", di->name); + DMA_TRACE(("%s: dma_rxenable\n", di->name)); control = (R_REG(&di->d64rxregs->control) & D64_RC_AE) | @@ -833,7 +832,7 @@ void dma_rxinit(struct dma_pub *pub) { struct dma_info *di = (struct dma_info *)pub; - DMA_TRACE("%s:\n", di->name); + DMA_TRACE(("%s: dma_rxinit\n", di->name)); if (di->nrxd == 0) return; @@ -927,7 +926,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) return 0; len = le16_to_cpu(*(__le16 *) (p->data)); - DMA_TRACE("%s: dma_rx len %d\n", di->name, len); + DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); dma_spin_for_len(len, p); /* set actual length */ @@ -954,14 +953,14 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK, struct dma64desc); - DMA_ERROR("rxin %d rxout %d, hw_curr %d\n", - di->rxin, di->rxout, cur); + DMA_ERROR(("dma_rx, rxin %d rxout %d, hw_curr %d\n", + di->rxin, di->rxout, cur)); } #endif /* BCMDBG */ if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { - DMA_ERROR("%s: bad frame length (%d)\n", - di->name, len); + DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", + di->name, len)); skb_queue_walk_safe(&dma_frames, p, next) { skb_unlink(p, &dma_frames); brcmu_pkt_buf_free_skb(p); @@ -978,7 +977,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) static bool dma64_rxidle(struct dma_info *di) { - DMA_TRACE("%s:\n", di->name); + DMA_TRACE(("%s: dma_rxidle\n", di->name)); if (di->nrxd == 0) return true; @@ -1018,7 +1017,7 @@ bool dma_rxfill(struct dma_pub *pub) n = di->nrxpost - nrxdactive(di, rxin, rxout); - DMA_TRACE("%s: post %d\n", di->name, n); + DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); if (di->rxbufsize > BCMEXTRAHDROOM) extra_offset = di->rxextrahdrroom; @@ -1031,9 +1030,11 @@ bool dma_rxfill(struct dma_pub *pub) p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset); if (p == NULL) { - DMA_ERROR("%s: out of rxbufs\n", di->name); + DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", + di->name)); if (i == 0 && dma64_rxidle(di)) { - DMA_ERROR("%s: ring is empty !\n", di->name); + DMA_ERROR(("%s: rxfill64: ring is empty !\n", + di->name)); ring_empty = true; } di->dma.rxnobuf++; @@ -1078,7 +1079,7 @@ void dma_rxreclaim(struct dma_pub *pub) struct dma_info *di = (struct dma_info *)pub; struct sk_buff *p; - DMA_TRACE("%s:\n", di->name); + DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); while ((p = _dma_getnextrxp(di, true))) brcmu_pkt_buf_free_skb(p); @@ -1109,7 +1110,7 @@ void dma_txinit(struct dma_pub *pub) struct dma_info *di = (struct dma_info *)pub; u32 control = D64_XC_XE; - DMA_TRACE("%s:\n", di->name); + DMA_TRACE(("%s: dma_txinit\n", di->name)); if (di->ntxd == 0) return; @@ -1141,7 +1142,7 @@ void dma_txsuspend(struct dma_pub *pub) { struct dma_info *di = (struct dma_info *)pub; - DMA_TRACE("%s:\n", di->name); + DMA_TRACE(("%s: dma_txsuspend\n", di->name)); if (di->ntxd == 0) return; @@ -1153,7 +1154,7 @@ void dma_txresume(struct dma_pub *pub) { struct dma_info *di = (struct dma_info *)pub; - DMA_TRACE("%s:\n", di->name); + DMA_TRACE(("%s: dma_txresume\n", di->name)); if (di->ntxd == 0) return; @@ -1175,11 +1176,11 @@ void dma_txreclaim(struct dma_pub *pub, enum txd_range range) struct dma_info *di = (struct dma_info *)pub; struct sk_buff *p; - DMA_TRACE("%s: %s\n", - di->name, - range == DMA_RANGE_ALL ? "all" : - range == DMA_RANGE_TRANSMITTED ? "transmitted" : - "transferred"); + DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, + (range == DMA_RANGE_ALL) ? "all" : + ((range == + DMA_RANGE_TRANSMITTED) ? "transmitted" : + "transferred"))); if (di->txin == di->txout) return; @@ -1249,7 +1250,7 @@ int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit) u32 flags = 0; dma_addr_t pa; - DMA_TRACE("%s:\n", di->name); + DMA_TRACE(("%s: dma_txfast\n", di->name)); txout = di->txout; @@ -1313,7 +1314,7 @@ int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit) return 0; outoftxd: - DMA_ERROR("%s: out of txds !!!\n", di->name); + DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name)); brcmu_pkt_buf_free_skb(p0); di->dma.txavail = 0; di->dma.txnobuf++; @@ -1337,11 +1338,11 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) u16 active_desc; struct sk_buff *txp; - DMA_TRACE("%s: %s\n", - di->name, - range == DMA_RANGE_ALL ? "all" : - range == DMA_RANGE_TRANSMITTED ? "transmitted" : - "transferred"); + DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, + (range == DMA_RANGE_ALL) ? "all" : + ((range == + DMA_RANGE_TRANSMITTED) ? "transmitted" : + "transferred"))); if (di->ntxd == 0) return NULL; @@ -1401,8 +1402,8 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) return txp; bogus: - DMA_NONE("bogus curr: start %d end %d txout %d\n", - start, end, di->txout); + DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d " + "force %d\n", start, end, di->txout, forceall)); return NULL; } diff --git a/trunk/drivers/net/wireless/hostap/hostap_ioctl.c b/trunk/drivers/net/wireless/hostap/hostap_ioctl.c index 46a8c291c08a..12de46407c71 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/trunk/drivers/net/wireless/hostap/hostap_ioctl.c @@ -3871,8 +3871,8 @@ static void prism2_get_drvinfo(struct net_device *dev, iface = netdev_priv(dev); local = iface->local; - strlcpy(info->driver, "hostap", sizeof(info->driver)); - snprintf(info->fw_version, sizeof(info->fw_version), + strncpy(info->driver, "hostap", sizeof(info->driver) - 1); + snprintf(info->fw_version, sizeof(info->fw_version) - 1, "%d.%d.%d", (local->sta_fw_ver >> 16) & 0xff, (local->sta_fw_ver >> 8) & 0xff, local->sta_fw_ver & 0xff); diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c index a0e5c21d3657..127e9c63beaf 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c @@ -5981,8 +5981,8 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev, struct ipw2100_priv *priv = libipw_priv(dev); char fw_ver[64], ucode_ver[64]; - strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); - strlcpy(info->version, DRV_VERSION, sizeof(info->version)); + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); ipw2100_get_fwversion(priv, fw_ver, sizeof(fw_ver)); ipw2100_get_ucodeversion(priv, ucode_ver, sizeof(ucode_ver)); @@ -5990,8 +5990,7 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev, snprintf(info->fw_version, sizeof(info->fw_version), "%s:%d:%s", fw_ver, priv->eeprom_version, ucode_ver); - strlcpy(info->bus_info, pci_name(priv->pci_dev), - sizeof(info->bus_info)); + strcpy(info->bus_info, pci_name(priv->pci_dev)); } static u32 ipw2100_ethtool_get_link(struct net_device *dev) diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c index 018a8deb88a8..99575884ff52 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c @@ -10548,8 +10548,8 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev, char date[32]; u32 len; - strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); - strlcpy(info->version, DRV_VERSION, sizeof(info->version)); + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); len = sizeof(vers); ipw_get_ordinal(p, IPW_ORD_STAT_FW_VERSION, vers, &len); @@ -10558,8 +10558,7 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev, snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)", vers, date); - strlcpy(info->bus_info, pci_name(p->pci_dev), - sizeof(info->bus_info)); + strcpy(info->bus_info, pci_name(p->pci_dev)); info->eedump_len = IPW_EEPROM_IMAGE_SIZE; } diff --git a/trunk/drivers/net/wireless/iwlegacy/Kconfig b/trunk/drivers/net/wireless/iwlegacy/Kconfig index aef65cd47661..2a1ae109ff25 100644 --- a/trunk/drivers/net/wireless/iwlegacy/Kconfig +++ b/trunk/drivers/net/wireless/iwlegacy/Kconfig @@ -43,23 +43,6 @@ config IWLWIFI_LEGACY_DEBUGFS is a low-impact option that allows getting insight into the driver's state at runtime. -config IWLWIFI_LEGACY_DEVICE_TRACING - bool "iwlwifilegacy legacy device access tracing" - depends on IWLWIFI_LEGACY - depends on EVENT_TRACING - help - Say Y here to trace all commands, including TX frames and IO - accesses, sent to the device. If you say yes, iwlwifilegacy will - register with the ftrace framework for event tracing and dump - all this information to the ringbuffer, you may need to - increase the ringbuffer size. See the ftrace documentation - for more information. - - When tracing is not enabled, this option still has some - (though rather small) overhead. - - If unsure, say Y so we can help you better when problems - occur. endmenu config IWL4965 diff --git a/trunk/drivers/net/wireless/iwlegacy/Makefile b/trunk/drivers/net/wireless/iwlegacy/Makefile index d56aeb38c211..4f67e45f22c0 100644 --- a/trunk/drivers/net/wireless/iwlegacy/Makefile +++ b/trunk/drivers/net/wireless/iwlegacy/Makefile @@ -3,12 +3,9 @@ iwl-legacy-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o iwl-legacy-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-legacy-objs += iwl-scan.o iwl-led.o iwl-legacy-$(CONFIG_IWLWIFI_LEGACY_DEBUGFS) += iwl-debugfs.o -iwl-legacy-$(CONFIG_IWLWIFI_LEGACY_DEVICE_TRACING) += iwl-devtrace.o iwl-legacy-objs += $(iwl-legacy-m) -CFLAGS_iwl-devtrace.o := -I$(src) - # 4965 obj-$(CONFIG_IWL4965) += iwl4965.o iwl4965-objs := iwl-4965.o iwl4965-base.o iwl-4965-rs.o iwl-4965-led.o diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-4965-tx.c b/trunk/drivers/net/wireless/iwlegacy/iwl-4965-tx.c index 7f12e3638bae..e421fdfed8c3 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-4965-tx.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-4965-tx.c @@ -513,12 +513,6 @@ int iwl4965_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, firstlen, PCI_DMA_BIDIRECTIONAL); - trace_iwlwifi_legacy_dev_tx(priv, - &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], - sizeof(struct iwl_tfd), - &out_cmd->hdr, firstlen, - skb->data + hdr_len, secondlen); - /* Tell device the write index *just past* this latest filled TFD */ q->write_ptr = iwl_legacy_queue_inc_wrap(q->write_ptr, q->n_bd); iwl_legacy_txq_update_write_ptr(priv, txq); diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-devtrace.c b/trunk/drivers/net/wireless/iwlegacy/iwl-devtrace.c deleted file mode 100644 index acec99197ce0..000000000000 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-devtrace.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include - -/* sparse doesn't like tracepoint macros */ -#ifndef __CHECKER__ -#include "iwl-dev.h" - -#define CREATE_TRACE_POINTS -#include "iwl-devtrace.h" - -EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_iowrite8); -EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ioread32); -EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_iowrite32); -EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_rx); -EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_tx); -EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_error); -#endif diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-devtrace.h b/trunk/drivers/net/wireless/iwlegacy/iwl-devtrace.h deleted file mode 100644 index a443725ba6be..000000000000 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-devtrace.h +++ /dev/null @@ -1,210 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#if !defined(__IWLWIFI_LEGACY_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ) -#define __IWLWIFI_LEGACY_DEVICE_TRACE - -#include - -#if !defined(CONFIG_IWLWIFI_LEGACY_DEVICE_TRACING) || defined(__CHECKER__) -#undef TRACE_EVENT -#define TRACE_EVENT(name, proto, ...) \ -static inline void trace_ ## name(proto) {} -#endif - - -#define PRIV_ENTRY __field(struct iwl_priv *, priv) -#define PRIV_ASSIGN (__entry->priv = priv) - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM iwlwifi_legacy_io - -TRACE_EVENT(iwlwifi_legacy_dev_ioread32, - TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val), - TP_ARGS(priv, offs, val), - TP_STRUCT__entry( - PRIV_ENTRY - __field(u32, offs) - __field(u32, val) - ), - TP_fast_assign( - PRIV_ASSIGN; - __entry->offs = offs; - __entry->val = val; - ), - TP_printk("[%p] read io[%#x] = %#x", __entry->priv, - __entry->offs, __entry->val) -); - -TRACE_EVENT(iwlwifi_legacy_dev_iowrite8, - TP_PROTO(struct iwl_priv *priv, u32 offs, u8 val), - TP_ARGS(priv, offs, val), - TP_STRUCT__entry( - PRIV_ENTRY - __field(u32, offs) - __field(u8, val) - ), - TP_fast_assign( - PRIV_ASSIGN; - __entry->offs = offs; - __entry->val = val; - ), - TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, - __entry->offs, __entry->val) -); - -TRACE_EVENT(iwlwifi_legacy_dev_iowrite32, - TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val), - TP_ARGS(priv, offs, val), - TP_STRUCT__entry( - PRIV_ENTRY - __field(u32, offs) - __field(u32, val) - ), - TP_fast_assign( - PRIV_ASSIGN; - __entry->offs = offs; - __entry->val = val; - ), - TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, - __entry->offs, __entry->val) -); - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM iwlwifi_legacy_ucode - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM iwlwifi - -TRACE_EVENT(iwlwifi_legacy_dev_hcmd, - TP_PROTO(struct iwl_priv *priv, void *hcmd, size_t len, u32 flags), - TP_ARGS(priv, hcmd, len, flags), - TP_STRUCT__entry( - PRIV_ENTRY - __dynamic_array(u8, hcmd, len) - __field(u32, flags) - ), - TP_fast_assign( - PRIV_ASSIGN; - memcpy(__get_dynamic_array(hcmd), hcmd, len); - __entry->flags = flags; - ), - TP_printk("[%p] hcmd %#.2x (%ssync)", - __entry->priv, ((u8 *)__get_dynamic_array(hcmd))[0], - __entry->flags & CMD_ASYNC ? "a" : "") -); - -TRACE_EVENT(iwlwifi_legacy_dev_rx, - TP_PROTO(struct iwl_priv *priv, void *rxbuf, size_t len), - TP_ARGS(priv, rxbuf, len), - TP_STRUCT__entry( - PRIV_ENTRY - __dynamic_array(u8, rxbuf, len) - ), - TP_fast_assign( - PRIV_ASSIGN; - memcpy(__get_dynamic_array(rxbuf), rxbuf, len); - ), - TP_printk("[%p] RX cmd %#.2x", - __entry->priv, ((u8 *)__get_dynamic_array(rxbuf))[4]) -); - -TRACE_EVENT(iwlwifi_legacy_dev_tx, - TP_PROTO(struct iwl_priv *priv, void *tfd, size_t tfdlen, - void *buf0, size_t buf0_len, - void *buf1, size_t buf1_len), - TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), - TP_STRUCT__entry( - PRIV_ENTRY - - __field(size_t, framelen) - __dynamic_array(u8, tfd, tfdlen) - - /* - * Do not insert between or below these items, - * we want to keep the frame together (except - * for the possible padding). - */ - __dynamic_array(u8, buf0, buf0_len) - __dynamic_array(u8, buf1, buf1_len) - ), - TP_fast_assign( - PRIV_ASSIGN; - __entry->framelen = buf0_len + buf1_len; - memcpy(__get_dynamic_array(tfd), tfd, tfdlen); - memcpy(__get_dynamic_array(buf0), buf0, buf0_len); - memcpy(__get_dynamic_array(buf1), buf1, buf1_len); - ), - TP_printk("[%p] TX %.2x (%zu bytes)", - __entry->priv, - ((u8 *)__get_dynamic_array(buf0))[0], - __entry->framelen) -); - -TRACE_EVENT(iwlwifi_legacy_dev_ucode_error, - TP_PROTO(struct iwl_priv *priv, u32 desc, u32 time, - u32 data1, u32 data2, u32 line, u32 blink1, - u32 blink2, u32 ilink1, u32 ilink2), - TP_ARGS(priv, desc, time, data1, data2, line, - blink1, blink2, ilink1, ilink2), - TP_STRUCT__entry( - PRIV_ENTRY - __field(u32, desc) - __field(u32, time) - __field(u32, data1) - __field(u32, data2) - __field(u32, line) - __field(u32, blink1) - __field(u32, blink2) - __field(u32, ilink1) - __field(u32, ilink2) - ), - TP_fast_assign( - PRIV_ASSIGN; - __entry->desc = desc; - __entry->time = time; - __entry->data1 = data1; - __entry->data2 = data2; - __entry->line = line; - __entry->blink1 = blink1; - __entry->blink2 = blink2; - __entry->ilink1 = ilink1; - __entry->ilink2 = ilink2; - ), - TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, " - "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X", - __entry->priv, __entry->desc, __entry->time, __entry->data1, - __entry->data2, __entry->line, __entry->blink1, - __entry->blink2, __entry->ilink1, __entry->ilink2) -); - -#endif /* __IWLWIFI_DEVICE_TRACE */ - -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH . -#undef TRACE_INCLUDE_FILE -#define TRACE_INCLUDE_FILE iwl-devtrace -#include diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-io.h b/trunk/drivers/net/wireless/iwlegacy/iwl-io.h index 5cc5d342914f..868ef01e2058 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-io.h +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-io.h @@ -33,7 +33,6 @@ #include "iwl-dev.h" #include "iwl-debug.h" -#include "iwl-devtrace.h" /* * IO, register, and NIC memory access functions @@ -65,7 +64,6 @@ static inline void _iwl_legacy_write8(struct iwl_priv *priv, u32 ofs, u8 val) { - trace_iwlwifi_legacy_dev_iowrite8(priv, ofs, val); iowrite8(val, priv->hw_base + ofs); } @@ -86,7 +84,6 @@ __iwl_legacy_write8(const char *f, u32 l, struct iwl_priv *priv, static inline void _iwl_legacy_write32(struct iwl_priv *priv, u32 ofs, u32 val) { - trace_iwlwifi_legacy_dev_iowrite32(priv, ofs, val); iowrite32(val, priv->hw_base + ofs); } @@ -107,7 +104,6 @@ __iwl_legacy_write32(const char *f, u32 l, struct iwl_priv *priv, static inline u32 _iwl_legacy_read32(struct iwl_priv *priv, u32 ofs) { u32 val = ioread32(priv->hw_base + ofs); - trace_iwlwifi_legacy_dev_ioread32(priv, ofs, val); return val; } diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-tx.c b/trunk/drivers/net/wireless/iwlegacy/iwl-tx.c index ef9e268bf8a0..e1a559b8630f 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-tx.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-tx.c @@ -539,9 +539,6 @@ int iwl_legacy_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) dma_unmap_addr_set(out_meta, mapping, phys_addr); dma_unmap_len_set(out_meta, len, fix_size); - trace_iwlwifi_legacy_dev_hcmd(priv, &out_cmd->hdr, - fix_size, cmd->flags); - priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, phys_addr, fix_size, 1, U32_PAD(cmd->len)); diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl3945-base.c b/trunk/drivers/net/wireless/iwlegacy/iwl3945-base.c index b282d869a546..7507819a25ad 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl3945-base.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl3945-base.c @@ -1246,7 +1246,6 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; len += sizeof(u32); /* account for status word */ - trace_iwlwifi_legacy_dev_rx(priv, pkt, len); /* Reclaim a command buffer only if this packet is a response * to a (driver-originated) command. @@ -1403,8 +1402,6 @@ void iwl3945_dump_nic_error_log(struct iwl_priv *priv) "%-13s (0x%X) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n", iwl3945_desc_lookup(desc), desc, time, blink1, blink2, ilink1, ilink2, data1); - trace_iwlwifi_legacy_dev_ucode_error(priv, desc, time, data1, 0, - 0, blink1, blink2, ilink1, ilink2); } } diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c b/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c index d2fba9eae153..fd2f7a40dd9a 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -679,7 +679,6 @@ void iwl4965_rx_handle(struct iwl_priv *priv) len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; len += sizeof(u32); /* account for status word */ - trace_iwlwifi_legacy_dev_rx(priv, pkt, len); /* Reclaim a command buffer only if this packet is a response * to a (driver-originated) command. @@ -1569,10 +1568,6 @@ void iwl4965_dump_nic_error_log(struct iwl_priv *priv) time = iwl_legacy_read_targ_mem(priv, base + 11 * sizeof(u32)); hcmd = iwl_legacy_read_targ_mem(priv, base + 22 * sizeof(u32)); - trace_iwlwifi_legacy_dev_ucode_error(priv, desc, - time, data1, data2, line, - blink1, blink2, ilink1, ilink2); - IWL_ERR(priv, "Desc Time " "data1 data2 line\n"); IWL_ERR(priv, "%-28s (0x%04X) %010u 0x%08X 0x%08X %u\n", diff --git a/trunk/drivers/net/wireless/libertas/ethtool.c b/trunk/drivers/net/wireless/libertas/ethtool.c index f955b2d66ed6..885ddc1c4fed 100644 --- a/trunk/drivers/net/wireless/libertas/ethtool.c +++ b/trunk/drivers/net/wireless/libertas/ethtool.c @@ -13,14 +13,13 @@ static void lbs_ethtool_get_drvinfo(struct net_device *dev, { struct lbs_private *priv = dev->ml_priv; - snprintf(info->fw_version, sizeof(info->fw_version), - "%u.%u.%u.p%u", + snprintf(info->fw_version, 32, "%u.%u.%u.p%u", priv->fwrelease >> 24 & 0xff, priv->fwrelease >> 16 & 0xff, priv->fwrelease >> 8 & 0xff, priv->fwrelease & 0xff); - strlcpy(info->driver, "libertas", sizeof(info->driver)); - strlcpy(info->version, lbs_driver_version, sizeof(info->version)); + strcpy(info->driver, "libertas"); + strcpy(info->version, lbs_driver_version); } /* diff --git a/trunk/drivers/net/wireless/mwifiex/Kconfig b/trunk/drivers/net/wireless/mwifiex/Kconfig index 2a078cea830a..8f2797aa0c60 100644 --- a/trunk/drivers/net/wireless/mwifiex/Kconfig +++ b/trunk/drivers/net/wireless/mwifiex/Kconfig @@ -10,12 +10,12 @@ config MWIFIEX mwifiex. config MWIFIEX_SDIO - tristate "Marvell WiFi-Ex Driver for SD8787/SD8797" + tristate "Marvell WiFi-Ex Driver for SD8787" depends on MWIFIEX && MMC select FW_LOADER ---help--- This adds support for wireless adapters based on Marvell - 8787/8797 chipsets with SDIO interface. + 8787 chipset with SDIO interface. If you choose to build it as a module, it will be called mwifiex_sdio. diff --git a/trunk/drivers/net/wireless/mwifiex/cfp.c b/trunk/drivers/net/wireless/mwifiex/cfp.c index 1782a77f15dc..f2e6de03805c 100644 --- a/trunk/drivers/net/wireless/mwifiex/cfp.c +++ b/trunk/drivers/net/wireless/mwifiex/cfp.c @@ -75,32 +75,18 @@ static u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 }; * This function maps an index in supported rates table into * the corresponding data rate. */ -u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, - u8 ht_info) +u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info) { - /* - * For every mcs_rate line, the first 8 bytes are for stream 1x1, - * and all 16 bytes are for stream 2x2. - */ - u16 mcs_rate[4][16] = { - /* LGI 40M */ - { 0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e, - 0x36, 0x6c, 0xa2, 0xd8, 0x144, 0x1b0, 0x1e6, 0x21c }, - - /* SGI 40M */ - { 0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c, - 0x3c, 0x78, 0xb4, 0xf0, 0x168, 0x1e0, 0x21c, 0x258 }, - - /* LGI 20M */ - { 0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82, - 0x1a, 0x34, 0x4e, 0x68, 0x9c, 0xd0, 0xea, 0x104 }, - - /* SGI 20M */ - { 0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90, - 0x1c, 0x39, 0x56, 0x73, 0xad, 0xe7, 0x104, 0x120 } - }; - u32 mcs_num_supp = - (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) ? 16 : 8; + u16 mcs_rate[4][8] = { + {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e} + , /* LG 40M */ + {0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c} + , /* SG 40M */ + {0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82} + , /* LG 20M */ + {0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90} + }; /* SG 20M */ + u32 rate; if (ht_info & BIT(0)) { @@ -109,7 +95,7 @@ u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, rate = 0x0D; /* MCS 32 SGI rate */ else rate = 0x0C; /* MCS 32 LGI rate */ - } else if (index < mcs_num_supp) { + } else if (index < 8) { if (ht_info & BIT(1)) { if (ht_info & BIT(2)) /* SGI, 40M */ diff --git a/trunk/drivers/net/wireless/mwifiex/fw.h b/trunk/drivers/net/wireless/mwifiex/fw.h index 62b863907698..35cb29cbd96e 100644 --- a/trunk/drivers/net/wireless/mwifiex/fw.h +++ b/trunk/drivers/net/wireless/mwifiex/fw.h @@ -165,7 +165,6 @@ enum MWIFIEX_802_11_WEP_STATUS { #define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f) #define SETHT_MCS32(x) (x[4] |= 1) -#define HT_STREAM_2X2 0x22 #define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4)) diff --git a/trunk/drivers/net/wireless/mwifiex/main.h b/trunk/drivers/net/wireless/mwifiex/main.h index 3861a617c0e1..30f138b6fa4c 100644 --- a/trunk/drivers/net/wireless/mwifiex/main.h +++ b/trunk/drivers/net/wireless/mwifiex/main.h @@ -775,8 +775,7 @@ struct mwifiex_chan_freq_power * struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211( struct mwifiex_private *priv, u8 band, u32 freq); -u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, - u8 ht_info); +u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info); u32 mwifiex_find_freq_from_band_chan(u8, u8); int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask, u8 **buffer); diff --git a/trunk/drivers/net/wireless/mwifiex/sdio.c b/trunk/drivers/net/wireless/mwifiex/sdio.c index 702452b505c3..ffaf3f3a57df 100644 --- a/trunk/drivers/net/wireless/mwifiex/sdio.c +++ b/trunk/drivers/net/wireless/mwifiex/sdio.c @@ -256,13 +256,10 @@ static int mwifiex_sdio_resume(struct device *dev) /* Device ID for SD8787 */ #define SDIO_DEVICE_ID_MARVELL_8787 (0x9119) -/* Device ID for SD8797 */ -#define SDIO_DEVICE_ID_MARVELL_8797 (0x9129) /* WLAN IDs */ static const struct sdio_device_id mwifiex_ids[] = { {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797)}, {}, }; @@ -1576,16 +1573,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) sdio_set_drvdata(func, card); adapter->dev = &func->dev; - - switch (func->device) { - case SDIO_DEVICE_ID_MARVELL_8797: - strcpy(adapter->fw_name, SD8797_DEFAULT_FW_NAME); - break; - case SDIO_DEVICE_ID_MARVELL_8787: - default: - strcpy(adapter->fw_name, SD8787_DEFAULT_FW_NAME); - break; - } + strcpy(adapter->fw_name, SD8787_DEFAULT_FW_NAME); return 0; @@ -1786,5 +1774,4 @@ MODULE_AUTHOR("Marvell International Ltd."); MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION); MODULE_VERSION(SDIO_VERSION); MODULE_LICENSE("GPL v2"); -MODULE_FIRMWARE(SD8787_DEFAULT_FW_NAME); -MODULE_FIRMWARE(SD8797_DEFAULT_FW_NAME); +MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); diff --git a/trunk/drivers/net/wireless/mwifiex/sdio.h b/trunk/drivers/net/wireless/mwifiex/sdio.h index a3fb322205b0..3f711801e58a 100644 --- a/trunk/drivers/net/wireless/mwifiex/sdio.h +++ b/trunk/drivers/net/wireless/mwifiex/sdio.h @@ -29,7 +29,6 @@ #include "main.h" #define SD8787_DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin" -#define SD8797_DEFAULT_FW_NAME "mrvl/sd8797_uapsta.bin" #define BLOCK_MODE 1 #define BYTE_MODE 0 diff --git a/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c b/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c index e812db8b695c..7a16b0c417af 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -508,7 +508,7 @@ static int mwifiex_ret_802_11_tx_rate_query(struct mwifiex_private *priv, priv->tx_htinfo = resp->params.tx_rate.ht_info; if (!priv->is_data_rate_auto) priv->data_rate = - mwifiex_index_to_data_rate(priv, priv->tx_rate, + mwifiex_index_to_data_rate(priv->tx_rate, priv->tx_htinfo); return 0; diff --git a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c index 4b6f5539657d..ea4a29b7e331 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -832,8 +832,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, if (!ret) { if (rate->is_rate_auto) - rate->rate = mwifiex_index_to_data_rate(priv, - priv->tx_rate, priv->tx_htinfo); + rate->rate = mwifiex_index_to_data_rate(priv->tx_rate, + priv->tx_htinfo); else rate->rate = priv->data_rate; } else { diff --git a/trunk/drivers/net/wireless/p54/p54spi.c b/trunk/drivers/net/wireless/p54/p54spi.c index a454d487b14f..f18df82eeb92 100644 --- a/trunk/drivers/net/wireless/p54/p54spi.c +++ b/trunk/drivers/net/wireless/p54/p54spi.c @@ -581,7 +581,11 @@ static void p54spi_op_stop(struct ieee80211_hw *dev) struct p54s_priv *priv = dev->priv; unsigned long flags; - mutex_lock(&priv->mutex); + if (mutex_lock_interruptible(&priv->mutex)) { + /* FIXME: how to handle this error? */ + return; + } + WARN_ON(priv->fw_state != FW_STATE_READY); cancel_work_sync(&priv->work); diff --git a/trunk/drivers/net/wireless/prism54/islpci_dev.c b/trunk/drivers/net/wireless/prism54/islpci_dev.c index 8a3cf4fe376f..5d0f61508a2e 100644 --- a/trunk/drivers/net/wireless/prism54/islpci_dev.c +++ b/trunk/drivers/net/wireless/prism54/islpci_dev.c @@ -793,8 +793,8 @@ islpci_set_multicast_list(struct net_device *dev) static void islpci_ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); - strlcpy(info->version, DRV_VERSION, sizeof(info->version)); + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); } static const struct ethtool_ops islpci_ethtool_ops = { diff --git a/trunk/include/net/nfc/nci.h b/trunk/include/net/nfc/nci.h index b61eb6c9df14..cdbe67139343 100644 --- a/trunk/include/net/nfc/nci.h +++ b/trunk/include/net/nfc/nci.h @@ -34,30 +34,30 @@ #define NCI_MAX_NUM_CONN 10 /* NCI Status Codes */ -#define NCI_STATUS_OK 0x00 -#define NCI_STATUS_REJECTED 0x01 -#define NCI_STATUS_RF_FRAME_CORRUPTED 0x02 -#define NCI_STATUS_FAILED 0x03 -#define NCI_STATUS_NOT_INITIALIZED 0x04 -#define NCI_STATUS_SYNTAX_ERROR 0x05 -#define NCI_STATUS_SEMANTIC_ERROR 0x06 -#define NCI_STATUS_UNKNOWN_GID 0x07 -#define NCI_STATUS_UNKNOWN_OID 0x08 -#define NCI_STATUS_INVALID_PARAM 0x09 -#define NCI_STATUS_MESSAGE_SIZE_EXCEEDED 0x0a +#define NCI_STATUS_OK 0x00 +#define NCI_STATUS_REJECTED 0x01 +#define NCI_STATUS_RF_FRAME_CORRUPTED 0x02 +#define NCI_STATUS_FAILED 0x03 +#define NCI_STATUS_NOT_INITIALIZED 0x04 +#define NCI_STATUS_SYNTAX_ERROR 0x05 +#define NCI_STATUS_SEMANTIC_ERROR 0x06 +#define NCI_STATUS_UNKNOWN_GID 0x07 +#define NCI_STATUS_UNKNOWN_OID 0x08 +#define NCI_STATUS_INVALID_PARAM 0x09 +#define NCI_STATUS_MESSAGE_SIZE_EXCEEDED 0x0a /* Discovery Specific Status Codes */ -#define NCI_STATUS_DISCOVERY_ALREADY_STARTED 0xa0 -#define NCI_STATUS_DISCOVERY_TARGET_ACTIVATION_FAILED 0xa1 -#define NCI_STATUS_DISCOVERY_TEAR_DOWN 0xa2 +#define NCI_STATUS_DISCOVERY_ALREADY_STARTED 0xa0 +#define NCI_STATUS_DISCOVERY_TARGET_ACTIVATION_FAILED 0xa1 +#define NCI_STATUS_DISCOVERY_TEAR_DOWN 0xa2 /* RF Interface Specific Status Codes */ -#define NCI_STATUS_RF_TRANSMISSION_ERROR 0xb0 -#define NCI_STATUS_RF_PROTOCOL_ERROR 0xb1 -#define NCI_STATUS_RF_TIMEOUT_ERROR 0xb2 +#define NCI_STATUS_RF_TRANSMISSION_ERROR 0xb0 +#define NCI_STATUS_RF_PROTOCOL_ERROR 0xb1 +#define NCI_STATUS_RF_TIMEOUT_ERROR 0xb2 /* NFCEE Interface Specific Status Codes */ -#define NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED 0xc0 -#define NCI_STATUS_NFCEE_INTERFACE_ACTIVATION_FAILED 0xc1 -#define NCI_STATUS_NFCEE_TRANSMISSION_ERROR 0xc2 -#define NCI_STATUS_NFCEE_PROTOCOL_ERROR 0xc3 +#define NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED 0xc0 +#define NCI_STATUS_NFCEE_INTERFACE_ACTIVATION_FAILED 0xc1 +#define NCI_STATUS_NFCEE_TRANSMISSION_ERROR 0xc2 +#define NCI_STATUS_NFCEE_PROTOCOL_ERROR 0xc3 #define NCI_STATUS_NFCEE_TIMEOUT_ERROR 0xc4 /* NCI RF Technology and Mode */ @@ -97,9 +97,9 @@ /* NCI RF Interfaces */ #define NCI_RF_INTERFACE_NFCEE_DIRECT 0x00 -#define NCI_RF_INTERFACE_FRAME 0x01 -#define NCI_RF_INTERFACE_ISO_DEP 0x02 -#define NCI_RF_INTERFACE_NFC_DEP 0x03 +#define NCI_RF_INTERFACE_FRAME 0x01 +#define NCI_RF_INTERFACE_ISO_DEP 0x02 +#define NCI_RF_INTERFACE_NFC_DEP 0x03 /* NCI Reset types */ #define NCI_RESET_TYPE_KEEP_CONFIG 0x00 @@ -118,22 +118,22 @@ /* NCI Discovery Types */ #define NCI_DISCOVERY_TYPE_POLL_A_PASSIVE 0x00 -#define NCI_DISCOVERY_TYPE_POLL_B_PASSIVE 0x01 -#define NCI_DISCOVERY_TYPE_POLL_F_PASSIVE 0x02 -#define NCI_DISCOVERY_TYPE_POLL_A_ACTIVE 0x03 -#define NCI_DISCOVERY_TYPE_POLL_F_ACTIVE 0x05 -#define NCI_DISCOVERY_TYPE_WAKEUP_A_ACTIVE 0x09 -#define NCI_DISCOVERY_TYPE_LISTEN_A_PASSIVE 0x80 -#define NCI_DISCOVERY_TYPE_LISTEN_B_PASSIVE 0x81 -#define NCI_DISCOVERY_TYPE_LISTEN_F_PASSIVE 0x82 -#define NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE 0x83 -#define NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE 0x85 +#define NCI_DISCOVERY_TYPE_POLL_B_PASSIVE 0x01 +#define NCI_DISCOVERY_TYPE_POLL_F_PASSIVE 0x02 +#define NCI_DISCOVERY_TYPE_POLL_A_ACTIVE 0x03 +#define NCI_DISCOVERY_TYPE_POLL_F_ACTIVE 0x05 +#define NCI_DISCOVERY_TYPE_WAKEUP_A_ACTIVE 0x09 +#define NCI_DISCOVERY_TYPE_LISTEN_A_PASSIVE 0x80 +#define NCI_DISCOVERY_TYPE_LISTEN_B_PASSIVE 0x81 +#define NCI_DISCOVERY_TYPE_LISTEN_F_PASSIVE 0x82 +#define NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE 0x83 +#define NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE 0x85 /* NCI Deactivation Type */ -#define NCI_DEACTIVATE_TYPE_IDLE_MODE 0x00 -#define NCI_DEACTIVATE_TYPE_SLEEP_MODE 0x01 -#define NCI_DEACTIVATE_TYPE_SLEEP_AF_MODE 0x02 -#define NCI_DEACTIVATE_TYPE_DISCOVERY 0x03 +#define NCI_DEACTIVATE_TYPE_IDLE_MODE 0x00 +#define NCI_DEACTIVATE_TYPE_SLEEP_MODE 0x01 +#define NCI_DEACTIVATE_TYPE_SLEEP_AF_MODE 0x02 +#define NCI_DEACTIVATE_TYPE_DISCOVERY 0x03 /* Message Type (MT) */ #define NCI_MT_DATA_PKT 0x00 @@ -165,10 +165,10 @@ #define nci_conn_id(hdr) (__u8)(((hdr)[0])&0x0f) /* GID values */ -#define NCI_GID_CORE 0x0 -#define NCI_GID_RF_MGMT 0x1 -#define NCI_GID_NFCEE_MGMT 0x2 -#define NCI_GID_PROPRIETARY 0xf +#define NCI_GID_CORE 0x0 +#define NCI_GID_RF_MGMT 0x1 +#define NCI_GID_NFCEE_MGMT 0x2 +#define NCI_GID_PROPRIETARY 0xf /* ---- NCI Packet structures ---- */ #define NCI_CTRL_HDR_SIZE 3 diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index b34ca0cbdf6c..12a6d4bb5d37 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -474,7 +474,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL); synchronize_rcu(); kfree(old_beacon); - kfree_skb(old_probe_resp); + kfree(old_probe_resp); /* down all dependent devices, that is VLANs */ list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, diff --git a/trunk/net/mac80211/mesh_hwmp.c b/trunk/net/mac80211/mesh_hwmp.c index 8a81591f0013..a7afb2d32def 100644 --- a/trunk/net/mac80211/mesh_hwmp.c +++ b/trunk/net/mac80211/mesh_hwmp.c @@ -871,7 +871,6 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) if (mpath->flags & MESH_PATH_REQ_QUEUED) { spin_unlock_bh(&mpath->state_lock); spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); - kfree(preq_node); return; } diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index da17c3008782..b25567a32f92 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -1357,6 +1357,9 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) ieee80211_set_disassoc(sdata, true, true); mutex_unlock(&ifmgd->mtx); + mutex_lock(&local->mtx); + ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); /* * must be outside lock due to cfg80211, * but that's not a problem. @@ -1365,10 +1368,6 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) IEEE80211_STYPE_DEAUTH, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, NULL, true); - - mutex_lock(&local->mtx); - ieee80211_recalc_idle(local); - mutex_unlock(&local->mtx); } void ieee80211_beacon_connection_loss_work(struct work_struct *work) @@ -2135,6 +2134,9 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, ieee80211_set_disassoc(sdata, true, true); mutex_unlock(&ifmgd->mtx); + mutex_lock(&local->mtx); + ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); /* * must be outside lock due to cfg80211, * but that's not a problem. @@ -2142,11 +2144,6 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, ieee80211_send_deauth_disassoc(sdata, bssid, IEEE80211_STYPE_DEAUTH, reason, NULL, true); - - mutex_lock(&local->mtx); - ieee80211_recalc_idle(local); - mutex_unlock(&local->mtx); - mutex_lock(&ifmgd->mtx); } diff --git a/trunk/net/mac80211/offchannel.c b/trunk/net/mac80211/offchannel.c index 767d26b3f98b..13427b194ced 100644 --- a/trunk/net/mac80211/offchannel.c +++ b/trunk/net/mac80211/offchannel.c @@ -211,6 +211,8 @@ static void ieee80211_hw_roc_start(struct work_struct *work) return; } + ieee80211_recalc_idle(local); + if (local->hw_roc_skb) { sdata = IEEE80211_DEV_TO_SUB_IF(local->hw_roc_dev); ieee80211_tx_skb(sdata, local->hw_roc_skb); @@ -224,8 +226,6 @@ static void ieee80211_hw_roc_start(struct work_struct *work) GFP_KERNEL); } - ieee80211_recalc_idle(local); - mutex_unlock(&local->mtx); } diff --git a/trunk/net/mac80211/rc80211_minstrel_ht.c b/trunk/net/mac80211/rc80211_minstrel_ht.c index ff5f7b84e825..cdb28535716b 100644 --- a/trunk/net/mac80211/rc80211_minstrel_ht.c +++ b/trunk/net/mac80211/rc80211_minstrel_ht.c @@ -36,17 +36,8 @@ /* Transmit duration for the raw data part of an average sized packet */ #define MCS_DURATION(streams, sgi, bps) MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps))) -/* - * Define group sort order: HT40 -> SGI -> #streams - */ -#define GROUP_IDX(_streams, _sgi, _ht40) \ - MINSTREL_MAX_STREAMS * 2 * _ht40 + \ - MINSTREL_MAX_STREAMS * _sgi + \ - _streams - 1 - /* MCS rate information for an MCS group */ -#define MCS_GROUP(_streams, _sgi, _ht40) \ - [GROUP_IDX(_streams, _sgi, _ht40)] = { \ +#define MCS_GROUP(_streams, _sgi, _ht40) { \ .streams = _streams, \ .flags = \ (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ @@ -67,9 +58,6 @@ * To enable sufficiently targeted rate sampling, MCS rates are divided into * groups, based on the number of streams and flags (HT40, SGI) that they * use. - * - * Sortorder has to be fixed for GROUP_IDX macro to be applicable: - * HT40 -> SGI -> #streams */ const struct mcs_group minstrel_mcs_groups[] = { MCS_GROUP(1, 0, 0), @@ -114,9 +102,21 @@ minstrel_ewma(int old, int new, int weight) static int minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate) { - return GROUP_IDX((rate->idx / MCS_GROUP_RATES) + 1, - !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), - !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); + int streams = (rate->idx / MCS_GROUP_RATES) + 1; + u32 flags = IEEE80211_TX_RC_SHORT_GI | IEEE80211_TX_RC_40_MHZ_WIDTH; + int i; + + for (i = 0; i < ARRAY_SIZE(minstrel_mcs_groups); i++) { + if (minstrel_mcs_groups[i].streams != streams) + continue; + if (minstrel_mcs_groups[i].flags != (rate->flags & flags)) + continue; + + return i; + } + + WARN_ON(1); + return 0; } static inline struct minstrel_rate_stats * @@ -130,7 +130,7 @@ minstrel_get_ratestats(struct minstrel_ht_sta *mi, int index) * Recalculate success probabilities and counters for a rate using EWMA */ static void -minstrel_calc_rate_ewma(struct minstrel_rate_stats *mr) +minstrel_calc_rate_ewma(struct minstrel_priv *mp, struct minstrel_rate_stats *mr) { if (unlikely(mr->attempts > 0)) { mr->sample_skipped = 0; @@ -156,7 +156,8 @@ minstrel_calc_rate_ewma(struct minstrel_rate_stats *mr) * the expected number of retransmissions and their expected length */ static void -minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate) +minstrel_ht_calc_tp(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, + int group, int rate) { struct minstrel_rate_stats *mr; unsigned int usecs; @@ -225,8 +226,8 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) mr = &mg->rates[i]; mr->retry_updated = false; index = MCS_GROUP_RATES * group + i; - minstrel_calc_rate_ewma(mr); - minstrel_ht_calc_tp(mi, group, i); + minstrel_calc_rate_ewma(mp, mr); + minstrel_ht_calc_tp(mp, mi, group, i); if (!mr->cur_tp) continue; @@ -299,10 +300,10 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) static bool minstrel_ht_txstat_valid(struct ieee80211_tx_rate *rate) { - if (rate->idx < 0) + if (!rate->count) return false; - if (!rate->count) + if (rate->idx < 0) return false; return !!(rate->flags & IEEE80211_TX_RC_MCS); @@ -356,7 +357,7 @@ minstrel_downgrade_rate(struct minstrel_ht_sta *mi, unsigned int *idx, } static void -minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb) +minstrel_aggr_check(struct minstrel_priv *mp, struct ieee80211_sta *pubsta, struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct sta_info *sta = container_of(pubsta, struct sta_info, sta); @@ -454,7 +455,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) { minstrel_ht_update_stats(mp, mi); if (!(info->flags & IEEE80211_TX_CTL_AMPDU)) - minstrel_aggr_check(sta, skb); + minstrel_aggr_check(mp, sta, skb); } } @@ -514,6 +515,7 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, static void minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, struct ieee80211_tx_rate *rate, int index, + struct ieee80211_tx_rate_control *txrc, bool sample, bool rtscts) { const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; @@ -626,11 +628,11 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, if (sample_idx >= 0) { sample = true; minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx, - true, false); + txrc, true, false); info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; } else { minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate, - false, false); + txrc, false, false); } if (mp->hw->max_rates >= 3) { @@ -641,13 +643,13 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, */ if (sample_idx >= 0) minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate, - false, false); + txrc, false, false); else minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2, - false, true); + txrc, false, true); minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, - false, !sample); + txrc, false, !sample); ar[3].count = 0; ar[3].idx = -1; @@ -658,7 +660,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, * max_tp_rate -> max_prob_rate by default. */ minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_prob_rate, - false, !sample); + txrc, false, !sample); ar[2].count = 0; ar[2].idx = -1; diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index 431988361553..2b413d38daa7 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -571,6 +571,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) switch (tx->key->conf.cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: + if (ieee80211_is_auth(hdr->frame_control)) + break; case WLAN_CIPHER_SUITE_TKIP: if (!ieee80211_is_data_present(hdr->frame_control)) tx->key = NULL;