diff --git a/[refs] b/[refs]
index 778c0234425f..5463ad5089f2 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 76ed94be65c8bd80b565865c186dd9f24bb2f23b
+refs/heads/master: 9fd481e03c1e9c76c814b88b9ea1cbda9afb0812
diff --git a/trunk/Documentation/DocBook/80211.tmpl b/trunk/Documentation/DocBook/80211.tmpl
index 2014155c899d..445289cd0e65 100644
--- a/trunk/Documentation/DocBook/80211.tmpl
+++ b/trunk/Documentation/DocBook/80211.tmpl
@@ -433,18 +433,8 @@
Insert notes about VLAN interfaces with hw crypto here or
in the hw crypto chapter.
-
- support for powersaving clients
-!Pinclude/net/mac80211.h AP support for powersaving clients
-
!Finclude/net/mac80211.h ieee80211_get_buffered_bc
!Finclude/net/mac80211.h ieee80211_beacon_get
-!Finclude/net/mac80211.h ieee80211_sta_eosp_irqsafe
-!Finclude/net/mac80211.h ieee80211_frame_release_type
-!Finclude/net/mac80211.h ieee80211_sta_ps_transition
-!Finclude/net/mac80211.h ieee80211_sta_ps_transition_ni
-!Finclude/net/mac80211.h ieee80211_sta_set_buffered
-!Finclude/net/mac80211.h ieee80211_sta_block_awake
@@ -470,6 +460,7 @@
!Finclude/net/mac80211.h sta_notify_cmd
!Finclude/net/mac80211.h ieee80211_find_sta
!Finclude/net/mac80211.h ieee80211_find_sta_by_ifaddr
+!Finclude/net/mac80211.h ieee80211_sta_block_awake
diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt
index 1cf3dbdb1538..dfd6a9f4a583 100644
--- a/trunk/Documentation/feature-removal-schedule.txt
+++ b/trunk/Documentation/feature-removal-schedule.txt
@@ -555,8 +555,3 @@ Why: This driver has been superseded by g_mass_storage.
Who: Alan Stern
----------------------------
-What: iwlagn alias support
-When: 3.5
-Why: The iwlagn module has been renamed iwlwifi. The alias will be around
- for backward compatibility for several cycles and then dropped.
-Who: Don Fry
\ No newline at end of file
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index a31c6140a961..1789ce22ea8c 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -3413,7 +3413,7 @@ M: Wey-Yi Guy
M: Intel Linux Wireless
L: linux-wireless@vger.kernel.org
W: http://intellinuxwireless.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git
S: Supported
F: drivers/net/wireless/iwlwifi/
diff --git a/trunk/drivers/bluetooth/btusb.c b/trunk/drivers/bluetooth/btusb.c
index 9cbac6b445e1..2755c1a9c38e 100644
--- a/trunk/drivers/bluetooth/btusb.c
+++ b/trunk/drivers/bluetooth/btusb.c
@@ -708,8 +708,7 @@ static int btusb_send_frame(struct sk_buff *skb)
break;
case HCI_ACLDATA_PKT:
- if (!data->bulk_tx_ep || (hdev->conn_hash.acl_num < 1 &&
- hdev->conn_hash.le_num < 1))
+ if (!data->bulk_tx_ep)
return -ENODEV;
urb = usb_alloc_urb(0, GFP_ATOMIC);
diff --git a/trunk/drivers/net/wireless/Makefile b/trunk/drivers/net/wireless/Makefile
index 4cf0ad312da1..7bba6a82b875 100644
--- a/trunk/drivers/net/wireless/Makefile
+++ b/trunk/drivers/net/wireless/Makefile
@@ -41,7 +41,7 @@ obj-$(CONFIG_ADM8211) += adm8211.o
obj-$(CONFIG_MWL8K) += mwl8k.o
-obj-$(CONFIG_IWLWIFI) += iwlwifi/
+obj-$(CONFIG_IWLAGN) += iwlwifi/
obj-$(CONFIG_IWLWIFI_LEGACY) += iwlegacy/
obj-$(CONFIG_RT2X00) += rt2x00/
diff --git a/trunk/drivers/net/wireless/adm8211.c b/trunk/drivers/net/wireless/adm8211.c
index 3b752d9fb3cd..43ebc44fc82c 100644
--- a/trunk/drivers/net/wireless/adm8211.c
+++ b/trunk/drivers/net/wireless/adm8211.c
@@ -1249,8 +1249,7 @@ static int adm8211_hw_reset(struct ieee80211_hw *dev)
return 0;
}
-static u64 adm8211_get_tsft(struct ieee80211_hw *dev,
- struct ieee80211_vif *vif)
+static u64 adm8211_get_tsft(struct ieee80211_hw *dev)
{
struct adm8211_priv *priv = dev->priv;
u32 tsftl;
diff --git a/trunk/drivers/net/wireless/at76c50x-usb.c b/trunk/drivers/net/wireless/at76c50x-usb.c
index 39322d4121b7..298601436ee2 100644
--- a/trunk/drivers/net/wireless/at76c50x-usb.c
+++ b/trunk/drivers/net/wireless/at76c50x-usb.c
@@ -500,9 +500,10 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
#define HEX2STR_BUFFERS 4
#define HEX2STR_MAX_LEN 64
+#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
/* Convert binary data into hex string */
-static char *hex2str(void *buf, size_t len)
+static char *hex2str(void *buf, int len)
{
static atomic_t a = ATOMIC_INIT(0);
static char bufs[HEX2STR_BUFFERS][3 * HEX2STR_MAX_LEN + 1];
@@ -513,17 +514,18 @@ static char *hex2str(void *buf, size_t len)
if (len > HEX2STR_MAX_LEN)
len = HEX2STR_MAX_LEN;
- if (len == 0)
- goto exit;
+ if (len <= 0) {
+ ret[0] = '\0';
+ return ret;
+ }
while (len--) {
- obuf = pack_hex_byte(obuf, *ibuf++);
+ *obuf++ = BIN2HEX(*ibuf >> 4);
+ *obuf++ = BIN2HEX(*ibuf & 0xf);
*obuf++ = '-';
+ ibuf++;
}
- obuf--;
-
-exit:
- *obuf = '\0';
+ *(--obuf) = '\0';
return ret;
}
diff --git a/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 6ed4c0717e3e..0560234ec3f6 100644
--- a/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -563,7 +563,7 @@ ath5k_get_stats(struct ieee80211_hw *hw,
static int
-ath5k_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
+ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct ath5k_hw *ah = hw->priv;
@@ -602,7 +602,7 @@ ath5k_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
static u64
-ath5k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+ath5k_get_tsf(struct ieee80211_hw *hw)
{
struct ath5k_hw *ah = hw->priv;
@@ -611,7 +611,7 @@ ath5k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
static void
-ath5k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u64 tsf)
+ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
{
struct ath5k_hw *ah = hw->priv;
@@ -620,7 +620,7 @@ ath5k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u64 tsf)
static void
-ath5k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+ath5k_reset_tsf(struct ieee80211_hw *hw)
{
struct ath5k_hw *ah = hw->priv;
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/Makefile b/trunk/drivers/net/wireless/ath/ath6kl/Makefile
index 8f7a0d1c290c..e1bb07ea8e80 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/Makefile
+++ b/trunk/drivers/net/wireless/ath/ath6kl/Makefile
@@ -31,7 +31,5 @@ ath6kl-y += init.o
ath6kl-y += main.o
ath6kl-y += txrx.o
ath6kl-y += wmi.o
+ath6kl-y += node.o
ath6kl-y += sdio.o
-ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o
-
-ccflags-y += -D__CHECK_ENDIAN__
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/bmi.c b/trunk/drivers/net/wireless/ath/ath6kl/bmi.c
index c5d11cc536e0..84676697d7eb 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/bmi.c
+++ b/trunk/drivers/net/wireless/ath/ath6kl/bmi.c
@@ -62,14 +62,14 @@ static int ath6kl_get_bmi_cmd_credits(struct ath6kl *ar)
return 0;
}
-static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar)
+static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar, bool need_timeout)
{
unsigned long timeout;
u32 rx_word = 0;
int ret = 0;
timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
- while (time_before(jiffies, timeout) && !rx_word) {
+ while ((!need_timeout || time_before(jiffies, timeout)) && !rx_word) {
ret = hif_read_write_sync(ar, RX_LOOKAHEAD_VALID_ADDRESS,
(u8 *)&rx_word, sizeof(rx_word),
HIF_RD_SYNC_BYTE_INC);
@@ -109,7 +109,8 @@ static int ath6kl_bmi_send_buf(struct ath6kl *ar, u8 *buf, u32 len)
return ret;
}
-static int ath6kl_bmi_recv_buf(struct ath6kl *ar, u8 *buf, u32 len)
+static int ath6kl_bmi_recv_buf(struct ath6kl *ar,
+ u8 *buf, u32 len, bool want_timeout)
{
int ret;
u32 addr;
@@ -161,7 +162,7 @@ static int ath6kl_bmi_recv_buf(struct ath6kl *ar, u8 *buf, u32 len)
* a function of Host processor speed.
*/
if (len >= 4) { /* NB: Currently, always true */
- ret = ath6kl_bmi_get_rx_lkahd(ar);
+ ret = ath6kl_bmi_get_rx_lkahd(ar, want_timeout);
if (ret)
return ret;
}
@@ -219,7 +220,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
}
ret = ath6kl_bmi_recv_buf(ar, (u8 *)&targ_info->version,
- sizeof(targ_info->version));
+ sizeof(targ_info->version), true);
if (ret) {
ath6kl_err("Unable to recv target info: %d\n", ret);
return ret;
@@ -229,7 +230,8 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
/* Determine how many bytes are in the Target's targ_info */
ret = ath6kl_bmi_recv_buf(ar,
(u8 *)&targ_info->byte_count,
- sizeof(targ_info->byte_count));
+ sizeof(targ_info->byte_count),
+ true);
if (ret) {
ath6kl_err("unable to read target info byte count: %d\n",
ret);
@@ -250,7 +252,8 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
((u8 *)targ_info) +
sizeof(targ_info->byte_count),
sizeof(*targ_info) -
- sizeof(targ_info->byte_count));
+ sizeof(targ_info->byte_count),
+ true);
if (ret) {
ath6kl_err("Unable to read target info (%d bytes): %d\n",
@@ -308,7 +311,7 @@ int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
ret);
return ret;
}
- ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len);
+ ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len, true);
if (ret) {
ath6kl_err("Unable to read from the device: %d\n",
ret);
@@ -421,7 +424,7 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param)
return ret;
}
- ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param));
+ ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), false);
if (ret) {
ath6kl_err("Unable to read from the device: %d\n", ret);
return ret;
@@ -501,7 +504,7 @@ int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param)
return ret;
}
- ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param));
+ ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), true);
if (ret) {
ath6kl_err("Unable to read from the device: %d\n", ret);
return ret;
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/bmi.h b/trunk/drivers/net/wireless/ath/ath6kl/bmi.h
index 96851d5df24b..83546d76d979 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/bmi.h
+++ b/trunk/drivers/net/wireless/ath/ath6kl/bmi.h
@@ -139,8 +139,8 @@
*/
#define TARGET_VERSION_SENTINAL 0xffffffff
-#define TARGET_TYPE_AR6003 3
-#define TARGET_TYPE_AR6004 5
+#define TARGET_TYPE_AR6003 3
+
#define BMI_ROMPATCH_INSTALL 9
/*
* Semantics: Install a ROM Patch.
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 8d9fbd4a62b7..14559ffb1453 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -17,12 +17,6 @@
#include "core.h"
#include "cfg80211.h"
#include "debug.h"
-#include "hif-ops.h"
-#include "testmode.h"
-
-static unsigned int ath6kl_p2p;
-
-module_param(ath6kl_p2p, uint, 0644);
#define RATETAB_ENT(_rate, _rateid, _flags) { \
.bitrate = (_rate), \
@@ -158,7 +152,8 @@ static int ath6kl_set_auth_type(struct ath6kl *ar,
break;
case NL80211_AUTHTYPE_AUTOMATIC:
- ar->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
+ ar->dot11_auth_mode = OPEN_AUTH;
+ ar->auto_auth_stage = AUTH_OPEN_IN_PROGRESS;
break;
default:
@@ -172,8 +167,7 @@ static int ath6kl_set_auth_type(struct ath6kl *ar,
static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast)
{
u8 *ar_cipher = ucast ? &ar->prwise_crypto : &ar->grp_crypto;
- u8 *ar_cipher_len = ucast ? &ar->prwise_crypto_len :
- &ar->grp_crypto_len;
+ u8 *ar_cipher_len = ucast ? &ar->prwise_crypto_len : &ar->grp_crpto_len;
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
__func__, cipher, ucast);
@@ -360,7 +354,6 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
}
if (!ar->usr_bss_filter) {
- clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) {
ath6kl_err("couldn't set bss filtering\n");
up(&ar->sem);
@@ -377,14 +370,14 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
__func__,
ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
ar->prwise_crypto_len, ar->grp_crypto,
- ar->grp_crypto_len, ar->ch_hint);
+ ar->grp_crpto_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->grp_crypto, ar->grp_crpto_len,
ar->ssid_len, ar->ssid,
ar->req_bssid, ar->ch_hint,
ar->connect_ctrl_flags);
@@ -414,53 +407,6 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
return 0;
}
-static int ath6kl_add_bss_if_needed(struct ath6kl *ar, const u8 *bssid,
- struct ieee80211_channel *chan,
- const u8 *beacon_ie, size_t beacon_ie_len)
-{
- struct cfg80211_bss *bss;
- u8 *ie;
-
- bss = cfg80211_get_bss(ar->wdev->wiphy, chan, bssid,
- ar->ssid, ar->ssid_len, WLAN_CAPABILITY_ESS,
- WLAN_CAPABILITY_ESS);
- if (bss == NULL) {
- /*
- * Since cfg80211 may not yet know about the BSS,
- * generate a partial entry until the first BSS info
- * event becomes available.
- *
- * Prepend SSID element since it is not included in the Beacon
- * IEs from the target.
- */
- ie = kmalloc(2 + ar->ssid_len + beacon_ie_len, GFP_KERNEL);
- if (ie == NULL)
- return -ENOMEM;
- ie[0] = WLAN_EID_SSID;
- ie[1] = ar->ssid_len;
- memcpy(ie + 2, ar->ssid, ar->ssid_len);
- memcpy(ie + 2 + ar->ssid_len, beacon_ie, beacon_ie_len);
- bss = cfg80211_inform_bss(ar->wdev->wiphy, chan,
- bssid, 0, WLAN_CAPABILITY_ESS, 100,
- ie, 2 + ar->ssid_len + beacon_ie_len,
- 0, GFP_KERNEL);
- if (bss)
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added dummy bss for "
- "%pM prior to indicating connect/roamed "
- "event\n", bssid);
- kfree(ie);
- } else
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss "
- "entry\n");
-
- if (bss == NULL)
- return -ENOMEM;
-
- cfg80211_put_bss(bss);
-
- return 0;
-}
-
void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
u8 *bssid, u16 listen_intvl,
u16 beacon_intvl,
@@ -468,7 +414,19 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
u8 beacon_ie_len, u8 assoc_req_len,
u8 assoc_resp_len, u8 *assoc_info)
{
- struct ieee80211_channel *chan;
+ u16 size = 0;
+ u16 capability = 0;
+ struct cfg80211_bss *bss = NULL;
+ struct ieee80211_mgmt *mgmt = NULL;
+ struct ieee80211_channel *ibss_ch = NULL;
+ s32 signal = 50 * 100;
+ u8 ie_buf_len = 0;
+ unsigned char ie_buf[256];
+ unsigned char *ptr_ie_buf = ie_buf;
+ unsigned char *ieeemgmtbuf = NULL;
+ u8 source_mac[ETH_ALEN];
+ u16 capa_mask;
+ u16 capa_val;
/* capinfo + listen interval */
u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
@@ -483,12 +441,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
assoc_req_len -= assoc_req_ie_offset;
assoc_resp_len -= assoc_resp_ie_offset;
- /*
- * Store Beacon interval here; DTIM period will be available only once
- * a Beacon frame from the AP is seen.
- */
- ar->assoc_bss_beacon_int = beacon_intvl;
- clear_bit(DTIM_PERIOD_AVAIL, &ar->flag);
+ ar->auto_auth_stage = AUTH_IDLE;
if (nw_type & ADHOC_NETWORK) {
if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
@@ -499,26 +452,110 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
}
if (nw_type & INFRA_NETWORK) {
- if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
- ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
+ if (ar->wdev->iftype != NL80211_IFTYPE_STATION) {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"%s: ath6k not in station mode\n", __func__);
return;
}
}
- chan = ieee80211_get_channel(ar->wdev->wiphy, (int) channel);
+ if (nw_type & ADHOC_NETWORK) {
+ capa_mask = WLAN_CAPABILITY_IBSS;
+ capa_val = WLAN_CAPABILITY_IBSS;
+ } else {
+ capa_mask = WLAN_CAPABILITY_ESS;
+ capa_val = WLAN_CAPABILITY_ESS;
+ }
+ /* Before informing the join/connect event, make sure that
+ * bss entry is present in scan list, if it not present
+ * construct and insert into scan list, otherwise that
+ * event will be dropped on the way by cfg80211, due to
+ * this keys will not be plumbed in case of WEP and
+ * application will not be aware of join/connect status. */
+ bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid,
+ ar->wdev->ssid, ar->wdev->ssid_len,
+ capa_mask, capa_val);
+
+ /*
+ * Earlier we were updating the cfg about bss by making a beacon frame
+ * only if the entry for bss is not there. This can have some issue if
+ * ROAM event is generated and a heavy traffic is ongoing. The ROAM
+ * event is handled through a work queue and by the time it really gets
+ * handled, BSS would have been aged out. So it is better to update the
+ * cfg about BSS irrespective of its entry being present right now or
+ * not.
+ */
if (nw_type & ADHOC_NETWORK) {
- cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
+ /* construct 802.11 mgmt beacon */
+ if (ptr_ie_buf) {
+ *ptr_ie_buf++ = WLAN_EID_SSID;
+ *ptr_ie_buf++ = ar->ssid_len;
+ memcpy(ptr_ie_buf, ar->ssid, ar->ssid_len);
+ ptr_ie_buf += ar->ssid_len;
+
+ *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
+ *ptr_ie_buf++ = 2; /* length */
+ *ptr_ie_buf++ = 0; /* ATIM window */
+ *ptr_ie_buf++ = 0; /* ATIM window */
+
+ /* TODO: update ibss params and include supported rates,
+ * DS param set, extened support rates, wmm. */
+
+ ie_buf_len = ptr_ie_buf - ie_buf;
+ }
+
+ capability |= WLAN_CAPABILITY_IBSS;
+
+ if (ar->prwise_crypto == WEP_CRYPT)
+ capability |= WLAN_CAPABILITY_PRIVACY;
+
+ memcpy(source_mac, ar->net_dev->dev_addr, ETH_ALEN);
+ ptr_ie_buf = ie_buf;
+ } else {
+ capability = *(u16 *) (&assoc_info[beacon_ie_len]);
+ memcpy(source_mac, bssid, ETH_ALEN);
+ ptr_ie_buf = assoc_req_ie;
+ ie_buf_len = assoc_req_len;
+ }
+
+ size = offsetof(struct ieee80211_mgmt, u)
+ + sizeof(mgmt->u.beacon)
+ + ie_buf_len;
+
+ ieeemgmtbuf = kzalloc(size, GFP_ATOMIC);
+ if (!ieeemgmtbuf) {
+ ath6kl_err("ieee mgmt buf alloc error\n");
+ cfg80211_put_bss(bss);
return;
}
- 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");
+ mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_BEACON);
+ memset(mgmt->da, 0xff, ETH_ALEN); /* broadcast addr */
+ memcpy(mgmt->sa, source_mac, ETH_ALEN);
+ memcpy(mgmt->bssid, bssid, ETH_ALEN);
+ mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_intvl);
+ mgmt->u.beacon.capab_info = cpu_to_le16(capability);
+ memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
+
+ ibss_ch = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: inform bss with bssid %pM channel %d beacon_intvl %d capability 0x%x\n",
+ __func__, mgmt->bssid, ibss_ch->hw_value,
+ beacon_intvl, capability);
+
+ bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
+ ibss_ch, mgmt,
+ size, signal, GFP_KERNEL);
+ kfree(ieeemgmtbuf);
+ cfg80211_put_bss(bss);
+
+ if (nw_type & ADHOC_NETWORK) {
+ cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
return;
}
@@ -531,7 +568,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
WLAN_STATUS_SUCCESS, GFP_KERNEL);
} else if (ar->sme_state == SME_CONNECTED) {
/* inform roam event to cfg80211 */
- cfg80211_roamed(ar->net_dev, chan, bssid,
+ cfg80211_roamed(ar->net_dev, ibss_ch, bssid,
assoc_req_ie, assoc_req_len,
assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
}
@@ -568,8 +605,6 @@ static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
up(&ar->sem);
- ar->sme_state = SME_DISCONNECTED;
-
return 0;
}
@@ -577,6 +612,9 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
u8 *bssid, u8 assoc_resp_len,
u8 *assoc_info, u16 proto_reason)
{
+ struct ath6kl_key *key = NULL;
+ u16 status;
+
if (ar->scan_req) {
cfg80211_scan_done(ar->scan_req, true);
ar->scan_req = NULL;
@@ -594,64 +632,164 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
}
if (ar->nw_type & INFRA_NETWORK) {
- if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
- ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
+ if (ar->wdev->iftype != NL80211_IFTYPE_STATION) {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"%s: ath6k not in station mode\n", __func__);
return;
}
}
- /*
- * Send a disconnect command to target when a disconnect event is
- * received with reason code other than 3 (DISCONNECT_CMD - disconnect
- * request from host) to make the firmware stop trying to connect even
- * after giving disconnect event. There will be one more disconnect
- * event for this disconnect command with reason code DISCONNECT_CMD
- * which will be notified to cfg80211.
- */
+ if (!test_bit(CONNECT_PEND, &ar->flag)) {
+ if (reason != DISCONNECT_CMD)
+ ath6kl_wmi_disconnect_cmd(ar->wmi);
- if (reason != DISCONNECT_CMD) {
+ return;
+ }
+
+ if (reason == NO_NETWORK_AVAIL) {
+ /* connect cmd failed */
ath6kl_wmi_disconnect_cmd(ar->wmi);
return;
}
- clear_bit(CONNECT_PEND, &ar->flag);
+ if (reason != DISCONNECT_CMD)
+ return;
- 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 (ar->sme_state == SME_CONNECTED) {
- cfg80211_disconnected(ar->net_dev, reason,
- NULL, 0, GFP_KERNEL);
+ if (!ar->auto_auth_stage) {
+ clear_bit(CONNECT_PEND, &ar->flag);
+
+ if (ar->sme_state == SME_CONNECTING) {
+ cfg80211_connect_result(ar->net_dev,
+ bssid, NULL, 0,
+ NULL, 0,
+ WLAN_STATUS_UNSPECIFIED_FAILURE,
+ GFP_KERNEL);
+ } else {
+ cfg80211_disconnected(ar->net_dev, reason,
+ NULL, 0, GFP_KERNEL);
+ }
+
+ ar->sme_state = SME_DISCONNECTED;
+ return;
}
- ar->sme_state = SME_DISCONNECTED;
+ if (ar->dot11_auth_mode != OPEN_AUTH)
+ return;
+
+ /*
+ * If the current auth algorithm is open, try shared and
+ * make autoAuthStage idle. We do not make it leap for now
+ * being.
+ */
+ key = &ar->keys[ar->def_txkey_index];
+ if (down_interruptible(&ar->sem)) {
+ ath6kl_err("busy, couldn't get access\n");
+ return;
+ }
+
+ ar->dot11_auth_mode = SHARED_AUTH;
+ ar->auto_auth_stage = AUTH_IDLE;
+
+ ath6kl_wmi_addkey_cmd(ar->wmi,
+ ar->def_txkey_index,
+ ar->prwise_crypto,
+ GROUP_USAGE | TX_USAGE,
+ key->key_len, NULL,
+ key->key,
+ KEY_OP_INIT_VAL, NULL,
+ NO_SYNC_WMIFLAG);
+
+ 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_crpto_len,
+ ar->ssid_len,
+ ar->ssid,
+ ar->req_bssid,
+ ar->ch_hint,
+ ar->connect_ctrl_flags);
+ up(&ar->sem);
+}
+
+static inline bool is_ch_11a(u16 ch)
+{
+ return (!((ch >= 2412) && (ch <= 2484)));
+}
+
+/* struct ath6kl_node_table::nt_nodelock is locked when calling this */
+void ath6kl_cfg80211_scan_node(struct wiphy *wiphy, struct bss *ni)
+{
+ u16 size;
+ unsigned char *ieeemgmtbuf = NULL;
+ struct ieee80211_mgmt *mgmt;
+ struct ieee80211_channel *channel;
+ struct ieee80211_supported_band *band;
+ struct ath6kl_common_ie *cie;
+ s32 signal;
+ int freq;
+
+ cie = &ni->ni_cie;
+
+ if (is_ch_11a(cie->ie_chan))
+ band = wiphy->bands[IEEE80211_BAND_5GHZ]; /* 11a */
+ else if ((cie->ie_erp) || (cie->ie_xrates))
+ band = wiphy->bands[IEEE80211_BAND_2GHZ]; /* 11g */
+ else
+ band = wiphy->bands[IEEE80211_BAND_2GHZ]; /* 11b */
+
+ size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
+ ieeemgmtbuf = kmalloc(size, GFP_ATOMIC);
+ if (!ieeemgmtbuf) {
+ ath6kl_err("ieee mgmt buf alloc error\n");
+ return;
+ }
+
+ /*
+ * TODO: Update target to include 802.11 mac header while sending
+ * bss info. Target removes 802.11 mac header while sending the bss
+ * info to host, cfg80211 needs it, for time being just filling the
+ * da, sa and bssid fields alone.
+ */
+ mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
+ memset(mgmt->da, 0xff, ETH_ALEN); /*broadcast addr */
+ memcpy(mgmt->sa, ni->ni_macaddr, ETH_ALEN);
+ memcpy(mgmt->bssid, ni->ni_macaddr, ETH_ALEN);
+ memcpy(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
+ ni->ni_buf, ni->ni_framelen);
+
+ freq = cie->ie_chan;
+ channel = ieee80211_get_channel(wiphy, freq);
+ signal = ni->ni_snr * 100;
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: bssid %pM ch %d freq %d size %d\n", __func__,
+ mgmt->bssid, channel->hw_value, freq, size);
+ cfg80211_inform_bss_frame(wiphy, channel, mgmt,
+ size, signal, GFP_ATOMIC);
+
+ kfree(ieeemgmtbuf);
}
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);
- s8 n_channels = 0;
- u16 *channels = NULL;
int ret = 0;
if (!ath6kl_cfg80211_ready(ar))
return -EIO;
if (!ar->usr_bss_filter) {
- clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
- ret = ath6kl_wmi_bssfilter_cmd(
- ar->wmi,
- (test_bit(CONNECTED, &ar->flag) ?
- ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
- if (ret) {
+ if (ath6kl_wmi_bssfilter_cmd(ar->wmi,
+ (test_bit(CONNECTED, &ar->flag) ?
+ ALL_BUT_BSS_FILTER :
+ ALL_BSS_FILTER), 0) != 0) {
ath6kl_err("couldn't set bss filtering\n");
- return ret;
+ return -EIO;
}
}
@@ -668,46 +806,13 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
request->ssids[i].ssid);
}
- if (request->ie) {
- 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 "
- "scan");
- return ret;
- }
- }
-
- /*
- * Scan only the requested channels if the request specifies a set of
- * channels. If the list is longer than the target supports, do not
- * configure the list and instead, scan all available channels.
- */
- if (request->n_channels > 0 &&
- request->n_channels <= WMI_MAX_CHANNELS) {
- u8 i;
-
- n_channels = request->n_channels;
-
- channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
- if (channels == NULL) {
- ath6kl_warn("failed to set scan channels, "
- "scan all channels");
- n_channels = 0;
- }
-
- for (i = 0; i < n_channels; i++)
- channels[i] = request->channels[i]->center_freq;
- }
-
- ret = ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, 0,
- false, 0, 0, n_channels, channels);
- if (ret)
+ if (ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, 0,
+ false, 0, 0, 0, NULL) != 0) {
ath6kl_err("wmi_startscan_cmd failed\n");
- else
- ar->scan_req = request;
+ ret = -EIO;
+ }
- kfree(channels);
+ ar->scan_req = request;
return ret;
}
@@ -726,6 +831,9 @@ void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)
goto out;
}
+ /* Translate data to cfg80211 mgmt format */
+ wlan_iterate_nodes(&ar->scan_table, ar->wdev->wiphy);
+
cfg80211_scan_done(ar->scan_req, false);
if (ar->scan_req->n_ssids && ar->scan_req->ssids[0].ssid_len) {
@@ -810,40 +918,6 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
key_usage, key->seq_len);
ar->def_txkey_index = key_index;
-
- 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, &ar->flag)) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
- "key configuration until AP mode has been "
- "started\n");
- /*
- * The key will be set in ath6kl_connect_ap_mode() once
- * the connected event is received from the target.
- */
- return 0;
- }
- }
-
- 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
- * (ath6kl_install_statioc_wep_keys).
- */
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration "
- "until AP mode has been started\n");
- ar->wep_key_list[key_index].key_len = key->key_len;
- memcpy(ar->wep_key_list[key_index].key, key->key, key->key_len);
- return 0;
- }
-
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,
@@ -928,7 +1002,6 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
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);
@@ -953,16 +1026,9 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
key_usage = GROUP_USAGE;
if (ar->prwise_crypto == WEP_CRYPT)
key_usage |= TX_USAGE;
- if (unicast)
- key_type = ar->prwise_crypto;
- if (multicast)
- key_type = ar->grp_crypto;
-
- if (ar->next_mode == AP_NETWORK && !test_bit(CONNECTED, &ar->flag))
- return 0; /* Delay until AP mode has been started */
status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
- key_type, key_usage,
+ ar->prwise_crypto, key_usage,
key->key_len, key->seq, key->key,
KEY_OP_INIT_VAL, NULL,
SYNC_BOTH_WMIFLAG);
@@ -1117,15 +1183,6 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
case NL80211_IFTYPE_ADHOC:
ar->next_mode = ADHOC_NETWORK;
break;
- case NL80211_IFTYPE_AP:
- ar->next_mode = AP_NETWORK;
- break;
- case NL80211_IFTYPE_P2P_CLIENT:
- ar->next_mode = INFRA_NETWORK;
- break;
- case NL80211_IFTYPE_P2P_GO:
- ar->next_mode = AP_NETWORK;
- break;
default:
ath6kl_err("invalid interface type %u\n", type);
return -EOPNOTSUPP;
@@ -1189,13 +1246,13 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
__func__,
ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
ar->prwise_crypto_len, ar->grp_crypto,
- ar->grp_crypto_len, ar->ch_hint);
+ ar->grp_crpto_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->grp_crypto, ar->grp_crpto_len,
ar->ssid_len, ar->ssid,
ar->req_bssid, ar->ch_hint,
ar->connect_ctrl_flags);
@@ -1365,23 +1422,12 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
} else {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "invalid rate from stats: %d\n", rate);
- ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
+ ath6kl_warn("invalid rate: %d\n", rate);
return 0;
}
sinfo->filled |= STATION_INFO_TX_BITRATE;
- 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 = ar->assoc_bss_dtim_period;
- sinfo->bss_param.beacon_interval = ar->assoc_bss_beacon_int;
- }
-
return 0;
}
@@ -1409,402 +1455,6 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
return 0;
}
-#ifdef CONFIG_PM
-static int ar6k_cfg80211_suspend(struct wiphy *wiphy,
- struct cfg80211_wowlan *wow)
-{
- struct ath6kl *ar = wiphy_priv(wiphy);
-
- return ath6kl_hif_suspend(ar);
-}
-#endif
-
-static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
- struct ieee80211_channel *chan,
- enum nl80211_channel_type channel_type)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
-
- if (!ath6kl_cfg80211_ready(ar))
- return -EIO;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
- __func__, chan->center_freq, chan->hw_value);
- ar->next_chan = chan->center_freq;
-
- return 0;
-}
-
-static bool ath6kl_is_p2p_ie(const u8 *pos)
-{
- return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
- pos[2] == 0x50 && pos[3] == 0x6f &&
- pos[4] == 0x9a && pos[5] == 0x09;
-}
-
-static int ath6kl_set_ap_probe_resp_ies(struct ath6kl *ar, const u8 *ies,
- size_t ies_len)
-{
- const u8 *pos;
- u8 *buf = NULL;
- size_t len = 0;
- int ret;
-
- /*
- * Filter out P2P IE(s) since they will be included depending on
- * the Probe Request frame in ath6kl_send_go_probe_resp().
- */
-
- 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_p2p_ie(pos)) {
- memcpy(buf + len, pos, 2 + pos[1]);
- len += 2 + pos[1];
- }
- pos += 2 + pos[1];
- }
- }
-
- ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_RESP,
- buf, len);
- kfree(buf);
- return ret;
-}
-
-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 ieee80211_mgmt *mgmt;
- u8 *ies;
- int ies_len;
- struct wmi_connect_cmd p;
- int res;
- int i;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add);
-
- if (!ath6kl_cfg80211_ready(ar))
- return -EIO;
-
- if (ar->next_mode != AP_NETWORK)
- return -EOPNOTSUPP;
-
- if (info->beacon_ies) {
- 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(ar, info->proberesp_ies,
- info->proberesp_ies_len);
- if (res)
- return res;
- }
- if (info->assocresp_ies) {
- res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_ASSOC_RESP,
- info->assocresp_ies,
- info->assocresp_ies_len);
- if (res)
- return res;
- }
-
- if (!add)
- return 0;
-
- ar->ap_mode_bkey.valid = false;
-
- /* TODO:
- * info->interval
- * info->dtim_period
- */
-
- if (info->head == NULL)
- return -EINVAL;
- mgmt = (struct ieee80211_mgmt *) info->head;
- ies = mgmt->u.beacon.variable;
- if (ies > info->head + info->head_len)
- return -EINVAL;
- ies_len = info->head + info->head_len - ies;
-
- if (info->ssid == NULL)
- return -EINVAL;
- 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 */
-
- ar->dot11_auth_mode = OPEN_AUTH;
-
- memset(&p, 0, sizeof(p));
-
- for (i = 0; i < info->crypto.n_akm_suites; i++) {
- switch (info->crypto.akm_suites[i]) {
- case WLAN_AKM_SUITE_8021X:
- if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
- p.auth_mode |= WPA_AUTH;
- if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
- p.auth_mode |= WPA2_AUTH;
- break;
- case WLAN_AKM_SUITE_PSK:
- if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
- p.auth_mode |= WPA_PSK_AUTH;
- if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
- p.auth_mode |= WPA2_PSK_AUTH;
- break;
- }
- }
- if (p.auth_mode == 0)
- p.auth_mode = NONE_AUTH;
- ar->auth_mode = p.auth_mode;
-
- for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
- switch (info->crypto.ciphers_pairwise[i]) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- p.prwise_crypto_type |= WEP_CRYPT;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- p.prwise_crypto_type |= TKIP_CRYPT;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- p.prwise_crypto_type |= AES_CRYPT;
- break;
- }
- }
- if (p.prwise_crypto_type == 0) {
- p.prwise_crypto_type = NONE_CRYPT;
- ath6kl_set_cipher(ar, 0, true);
- } else if (info->crypto.n_ciphers_pairwise == 1)
- ath6kl_set_cipher(ar, info->crypto.ciphers_pairwise[0], true);
-
- switch (info->crypto.cipher_group) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- p.grp_crypto_type = WEP_CRYPT;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- p.grp_crypto_type = TKIP_CRYPT;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- p.grp_crypto_type = AES_CRYPT;
- break;
- default:
- p.grp_crypto_type = NONE_CRYPT;
- break;
- }
- ath6kl_set_cipher(ar, info->crypto.cipher_group, false);
-
- p.nw_type = AP_NETWORK;
- ar->nw_type = ar->next_mode;
-
- p.ssid_len = ar->ssid_len;
- memcpy(p.ssid, ar->ssid, ar->ssid_len);
- p.dot11_auth_mode = ar->dot11_auth_mode;
- p.ch = cpu_to_le16(ar->next_chan);
-
- res = ath6kl_wmi_ap_profile_commit(ar->wmi, &p);
- if (res < 0)
- return res;
-
- return 0;
-}
-
-static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev,
- struct beacon_parameters *info)
-{
- return ath6kl_ap_beacon(wiphy, dev, info, true);
-}
-
-static int ath6kl_set_beacon(struct wiphy *wiphy, struct net_device *dev,
- struct beacon_parameters *info)
-{
- return ath6kl_ap_beacon(wiphy, dev, info, false);
-}
-
-static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
-
- if (ar->nw_type != AP_NETWORK)
- return -EOPNOTSUPP;
- if (!test_bit(CONNECTED, &ar->flag))
- return -ENOTCONN;
-
- ath6kl_wmi_disconnect_cmd(ar->wmi);
- clear_bit(CONNECTED, &ar->flag);
-
- return 0;
-}
-
-static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
- u8 *mac, struct station_parameters *params)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
-
- if (ar->nw_type != AP_NETWORK)
- return -EOPNOTSUPP;
-
- /* Use this only for authorizing/unauthorizing a station */
- if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
- return -EOPNOTSUPP;
-
- if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
- return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_AUTHORIZE,
- mac, 0);
- return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_UNAUTHORIZE, mac,
- 0);
-}
-
-static int ath6kl_remain_on_channel(struct wiphy *wiphy,
- struct net_device *dev,
- struct ieee80211_channel *chan,
- enum nl80211_channel_type channel_type,
- unsigned int duration,
- u64 *cookie)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
-
- /* TODO: if already pending or ongoing remain-on-channel,
- * return -EBUSY */
- *cookie = 1; /* only a single pending request is supported */
-
- return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, chan->center_freq,
- duration);
-}
-
-static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
- struct net_device *dev,
- u64 cookie)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
-
- if (cookie != 1)
- return -ENOENT;
-
- return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi);
-}
-
-static int ath6kl_send_go_probe_resp(struct ath6kl *ar, const u8 *buf,
- size_t len, unsigned int freq)
-{
- const u8 *pos;
- u8 *p2p;
- int p2p_len;
- int ret;
- const struct ieee80211_mgmt *mgmt;
-
- mgmt = (const struct ieee80211_mgmt *) buf;
-
- /* Include P2P IE(s) from the frame generated in user space. */
-
- p2p = kmalloc(len, GFP_KERNEL);
- if (p2p == NULL)
- return -ENOMEM;
- p2p_len = 0;
-
- pos = mgmt->u.probe_resp.variable;
- while (pos + 1 < buf + len) {
- if (pos + 2 + pos[1] > buf + len)
- break;
- if (ath6kl_is_p2p_ie(pos)) {
- memcpy(p2p + p2p_len, pos, 2 + pos[1]);
- p2p_len += 2 + pos[1];
- }
- pos += 2 + pos[1];
- }
-
- ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, freq, mgmt->da,
- p2p, p2p_len);
- kfree(p2p);
- return ret;
-}
-
-static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
- struct ieee80211_channel *chan, bool offchan,
- enum nl80211_channel_type channel_type,
- bool channel_type_valid, unsigned int wait,
- const u8 *buf, size_t len, u64 *cookie)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- u32 id;
- const struct ieee80211_mgmt *mgmt;
-
- mgmt = (const struct ieee80211_mgmt *) buf;
- if (buf + len >= mgmt->u.probe_resp.variable &&
- ar->nw_type == AP_NETWORK && test_bit(CONNECTED, &ar->flag) &&
- 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(ar, buf, len,
- chan->center_freq);
- }
-
- 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 = ar->send_action_id++;
- }
-
- *cookie = id;
- return ath6kl_wmi_send_action_cmd(ar->wmi, id, chan->center_freq, wait,
- buf, len);
-}
-
-static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
- struct net_device *dev,
- u16 frame_type, bool reg)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
- __func__, frame_type, reg);
- if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
- /*
- * Note: This notification callback is not allowed to sleep, so
- * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
- * hardcode target to report Probe Request frames all the time.
- */
- ar->probe_req_report = reg;
- }
-}
-
-static const struct ieee80211_txrx_stypes
-ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
- [NL80211_IFTYPE_STATION] = {
- .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
- },
- [NL80211_IFTYPE_P2P_CLIENT] = {
- .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
- },
- [NL80211_IFTYPE_P2P_GO] = {
- .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
- },
-};
-
static struct cfg80211_ops ath6kl_cfg80211_ops = {
.change_virtual_intf = ath6kl_cfg80211_change_iface,
.scan = ath6kl_cfg80211_scan,
@@ -1824,26 +1474,12 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
.set_pmksa = ath6kl_set_pmksa,
.del_pmksa = ath6kl_del_pmksa,
.flush_pmksa = ath6kl_flush_pmksa,
- CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
-#ifdef CONFIG_PM
- .suspend = ar6k_cfg80211_suspend,
-#endif
- .set_channel = ath6kl_set_channel,
- .add_beacon = ath6kl_add_beacon,
- .set_beacon = ath6kl_set_beacon,
- .del_beacon = ath6kl_del_beacon,
- .change_station = ath6kl_change_station,
- .remain_on_channel = ath6kl_remain_on_channel,
- .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
- .mgmt_tx = ath6kl_mgmt_tx,
- .mgmt_frame_register = ath6kl_mgmt_frame_register,
};
struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
{
int ret = 0;
struct wireless_dev *wdev;
- struct ath6kl *ar;
wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
if (!wdev) {
@@ -1859,25 +1495,13 @@ struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
return NULL;
}
- ar = wiphy_priv(wdev->wiphy);
- ar->p2p = !!ath6kl_p2p;
-
- wdev->wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
-
- wdev->wiphy->max_remain_on_channel_duration = 5000;
-
/* set device pointer for wiphy */
set_wiphy_dev(wdev->wiphy, dev);
wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
- if (ar->p2p) {
- wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
- BIT(NL80211_IFTYPE_P2P_CLIENT);
- }
+ BIT(NL80211_IFTYPE_ADHOC);
/* max num of ssids that can be probed during scanning */
wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
- wdev->wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/common.h b/trunk/drivers/net/wireless/ath/ath6kl/common.h
index b92f0e5d2336..6b0d45642fe3 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/common.h
+++ b/trunk/drivers/net/wireless/ath/ath6kl/common.h
@@ -75,11 +75,94 @@ enum crypto_type {
AES_CRYPT = 0x08,
};
+#define ATH6KL_NODE_HASHSIZE 32
+/* simple hash is enough for variation of macaddr */
+#define ATH6KL_NODE_HASH(addr) \
+ (((const u8 *)(addr))[ETH_ALEN - 1] % \
+ ATH6KL_NODE_HASHSIZE)
+
+/*
+ * Table of ath6kl_node instances. Each ieee80211com
+ * has at least one for holding the scan candidates.
+ * When operating as an access point or in ibss mode there
+ * is a second table for associated stations or neighbors.
+ */
+struct ath6kl_node_table {
+ spinlock_t nt_nodelock; /* on node table */
+ struct bss *nt_node_first; /* information of all nodes */
+ struct bss *nt_node_last; /* information of all nodes */
+ struct bss *nt_hash[ATH6KL_NODE_HASHSIZE];
+ const char *nt_name; /* for debugging */
+ u32 nt_node_age; /* node aging time */
+};
+
+#define WLAN_NODE_INACT_TIMEOUT_MSEC 120000
+#define WLAN_NODE_INACT_CNT 4
+
+struct ath6kl_common_ie {
+ u16 ie_chan;
+ u8 *ie_tstamp;
+ u8 *ie_ssid;
+ u8 *ie_rates;
+ u8 *ie_xrates;
+ u8 *ie_country;
+ u8 *ie_wpa;
+ u8 *ie_rsn;
+ u8 *ie_wmm;
+ u8 *ie_ath;
+ u16 ie_capInfo;
+ u16 ie_beaconInt;
+ u8 *ie_tim;
+ u8 *ie_chswitch;
+ u8 ie_erp;
+ u8 *ie_wsc;
+ u8 *ie_htcap;
+ u8 *ie_htop;
+};
+
+struct bss {
+ u8 ni_macaddr[ETH_ALEN];
+ u8 ni_snr;
+ s16 ni_rssi;
+ struct bss *ni_list_next;
+ struct bss *ni_list_prev;
+ struct bss *ni_hash_next;
+ struct bss *ni_hash_prev;
+ struct ath6kl_common_ie ni_cie;
+ u8 *ni_buf;
+ u16 ni_framelen;
+ struct ath6kl_node_table *ni_table;
+ u32 ni_refcnt;
+
+ u32 ni_tstamp;
+ u32 ni_actcnt;
+};
+
struct htc_endpoint_credit_dist;
struct ath6kl;
enum htc_credit_dist_reason;
struct htc_credit_state_info;
+struct bss *wlan_node_alloc(int wh_size);
+void wlan_node_free(struct bss *ni);
+void wlan_setup_node(struct ath6kl_node_table *nt, struct bss *ni,
+ const u8 *mac_addr);
+struct bss *wlan_find_node(struct ath6kl_node_table *nt,
+ const u8 *mac_addr);
+void wlan_node_reclaim(struct ath6kl_node_table *nt, struct bss *ni);
+void wlan_free_allnodes(struct ath6kl_node_table *nt);
+void wlan_iterate_nodes(struct ath6kl_node_table *nt, void *arg);
+
+void wlan_node_table_init(struct ath6kl_node_table *nt);
+void wlan_node_table_cleanup(struct ath6kl_node_table *nt);
+
+void wlan_refresh_inactive_nodes(struct ath6kl *ar);
+
+struct bss *wlan_find_ssid_node(struct ath6kl_node_table *nt, u8 *ssid,
+ u32 ssid_len, bool is_wpa2, bool match_ssid);
+
+void wlan_node_return(struct ath6kl_node_table *nt, struct bss *ni);
+
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,
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/core.h b/trunk/drivers/net/wireless/ath/ath6kl/core.h
index 6d8a4845baaf..74170229523f 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/core.h
+++ b/trunk/drivers/net/wireless/ath/ath6kl/core.h
@@ -21,12 +21,10 @@
#include
#include
#include
-#include
#include
#include "htc.h"
#include "wmi.h"
#include "bmi.h"
-#include "target.h"
#define MAX_ATH6KL 1
#define ATH6KL_MAX_RX_BUFFERS 16
@@ -44,9 +42,6 @@
#define ATH6KL_MAX_ENDPOINTS 4
#define MAX_NODE_NUM 15
-/* Extra bytes for htc header alignment */
-#define ATH6KL_HTC_ALIGN_BYTES 3
-
/* MAX_HI_COOKIE_NUM are reserved for high priority traffic */
#define MAX_DEF_COOKIE_NUM 180
#define MAX_HI_COOKIE_NUM 18 /* 10% of MAX_COOKIE_NUM */
@@ -58,35 +53,6 @@
#define A_DEFAULT_LISTEN_INTERVAL 100
#define A_MAX_WOW_LISTEN_INTERVAL 1000
-/* includes also the null byte */
-#define ATH6KL_FIRMWARE_MAGIC "QCA-ATH6KL"
-
-enum ath6kl_fw_ie_type {
- ATH6KL_FW_IE_FW_VERSION = 0,
- ATH6KL_FW_IE_TIMESTAMP = 1,
- ATH6KL_FW_IE_OTP_IMAGE = 2,
- ATH6KL_FW_IE_FW_IMAGE = 3,
- ATH6KL_FW_IE_PATCH_IMAGE = 4,
- ATH6KL_FW_IE_RESERVED_RAM_SIZE = 5,
- ATH6KL_FW_IE_CAPABILITIES = 6,
- ATH6KL_FW_IE_PATCH_ADDR = 7,
-};
-
-enum ath6kl_fw_capability {
- ATH6KL_FW_CAPABILITY_HOST_P2P = 0,
-
- /* this needs to be last */
- ATH6KL_FW_CAPABILITY_MAX,
-};
-
-#define ATH6KL_CAPABILITY_LEN (ALIGN(ATH6KL_FW_CAPABILITY_MAX, 32) / 32)
-
-struct ath6kl_fw_ie {
- __le32 id;
- __le32 len;
- u8 data[0];
-};
-
/* AR6003 1.0 definitions */
#define AR6003_REV1_VERSION 0x300002ba
@@ -95,9 +61,7 @@ struct ath6kl_fw_ie {
#define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS 0x57e910
#define AR6003_REV2_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77"
#define AR6003_REV2_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77"
-#define AR6003_REV2_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin"
#define AR6003_REV2_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin"
-#define AR6003_REV2_FIRMWARE_2_FILE "ath6k/AR6003/hw2.0/fw-2.bin"
#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin"
#define AR6003_REV2_DEFAULT_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin"
@@ -105,21 +69,11 @@ struct ath6kl_fw_ie {
#define AR6003_REV3_VERSION 0x30000582
#define AR6003_REV3_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin"
#define AR6003_REV3_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin"
-#define AR6003_REV3_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin"
#define AR6003_REV3_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin"
-#define AR6003_REV3_FIRMWARE_2_FILE "ath6k/AR6003/hw2.1.1/fw-2.bin"
#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin"
#define AR6003_REV3_DEFAULT_BOARD_DATA_FILE \
"ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
-/* AR6004 1.0 definitions */
-#define AR6004_REV1_VERSION 0x30000623
-#define AR6004_REV1_FIRMWARE_FILE "ath6k/AR6004/hw6.1/fw.ram.bin"
-#define AR6004_REV1_FIRMWARE_2_FILE "ath6k/AR6004/hw6.1/fw-2.bin"
-#define AR6004_REV1_BOARD_DATA_FILE "ath6k/AR6004/hw6.1/bdata.bin"
-#define AR6004_REV1_DEFAULT_BOARD_DATA_FILE "ath6k/AR6004/hw6.1/bdata.DB132.bin"
-#define AR6004_REV1_EPPING_FIRMWARE_FILE "ath6k/AR6004/hw6.1/endpointping.bin"
-
/* Per STA data, used in AP mode */
#define STA_PS_AWAKE BIT(0)
#define STA_PS_SLEEP BIT(1)
@@ -371,13 +325,26 @@ struct ath6kl_mbox_info {
#define ATH6KL_KEY_RECV 0x02
#define ATH6KL_KEY_DEFAULT 0x80 /* default xmit key */
-/* Initial group key for AP mode */
+/*
+ * WPA/RSN get/set key request. Specify the key/cipher
+ * type and whether the key is to be used for sending and/or
+ * receiving. The key index should be set only when working
+ * with global keys (use IEEE80211_KEYIX_NONE for ``no index'').
+ * Otherwise a unicast/pairwise key is specified by the bssid
+ * (on a station) or mac address (on an ap). They key length
+ * must include any MIC key data; otherwise it should be no
+ * more than ATH6KL_KEYBUF_SIZE.
+ */
struct ath6kl_req_key {
- bool valid;
- u8 key_index;
- int key_type;
- u8 key[WLAN_MAX_KEY_LEN];
- u8 key_len;
+ u8 ik_type; /* key/cipher type */
+ u8 ik_pad;
+ u16 ik_keyix; /* key index */
+ u8 ik_keylen; /* key length in bytes */
+ u8 ik_flags;
+ u8 ik_macaddr[ETH_ALEN];
+ u64 ik_keyrsc; /* key receive sequence counter */
+ u64 ik_keytsc; /* key transmit sequence counter */
+ u8 ik_keydata[ATH6KL_KEYBUF_SIZE + ATH6KL_MICBUF_SIZE];
};
/* Flag info */
@@ -394,9 +361,6 @@ struct ath6kl_req_key {
#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 {
struct device *dev;
@@ -419,7 +383,7 @@ struct ath6kl {
u8 prwise_crypto;
u8 prwise_crypto_len;
u8 grp_crypto;
- u8 grp_crypto_len;
+ u8 grp_crpto_len;
u8 def_txkey_index;
struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
u8 bssid[ETH_ALEN];
@@ -428,7 +392,6 @@ struct ath6kl {
u16 bss_ch;
u16 listen_intvl_b;
u16 listen_intvl_t;
- u8 lrssi_roam_threshold;
struct ath6kl_version version;
u32 target_type;
u8 tx_pwr;
@@ -469,18 +432,7 @@ struct ath6kl {
enum wlan_low_pwr_state wlan_pwr_state;
struct wmi_scan_params_cmd sc_params;
#define AR_MCAST_FILTER_MAC_ADDR_SIZE 4
- struct {
- void *rx_report;
- size_t rx_report_len;
- } tm;
-
- struct {
- u32 dataset_patch_addr;
- u32 app_load_addr;
- u32 app_start_override_addr;
- u32 board_ext_data_addr;
- u32 reserved_ram_size;
- } hw;
+ u8 auto_auth_stage;
u16 conf_flags;
wait_queue_head_t event_wq;
@@ -502,35 +454,9 @@ struct ath6kl {
u8 *fw_patch;
size_t fw_patch_len;
- unsigned long fw_capabilities[ATH6KL_CAPABILITY_LEN];
-
struct workqueue_struct *ath6kl_wq;
- 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 {
- struct circ_buf fwlog_buf;
- spinlock_t fwlog_lock;
- void *fwlog_tmp;
- u32 fwlog_mask;
- unsigned int dbgfs_diag_reg;
- u32 diag_reg_addr_wr;
- u32 diag_reg_val_wr;
-
- struct {
- unsigned int invalid_rate;
- } war_stats;
- } debug;
-#endif /* CONFIG_ATH6KL_DEBUG */
+ struct ath6kl_node_table scan_table;
};
static inline void *ath6kl_priv(struct net_device *dev)
@@ -548,19 +474,6 @@ static inline void ath6kl_deposit_credit_to_ep(struct htc_credit_state_info
cred_info->cur_free_credits -= credits;
}
-static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
- u32 item_offset)
-{
- u32 addr = 0;
-
- if (ar->target_type == TARGET_TYPE_AR6003)
- addr = ATH6KL_AR6003_HI_START_ADDR + item_offset;
- else if (ar->target_type == TARGET_TYPE_AR6004)
- addr = ATH6KL_AR6004_HI_START_ADDR + item_offset;
-
- 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);
@@ -574,11 +487,9 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
struct htc_packet *packet);
void ath6kl_stop_txrx(struct ath6kl *ar);
void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar);
-int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value);
-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);
+int ath6kl_access_datadiag(struct ath6kl *ar, u32 address,
+ u8 *data, u32 length, bool read);
+int ath6kl_read_reg_diag(struct ath6kl *ar, u32 *address, u32 *data);
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,
@@ -609,10 +520,6 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel,
u16 beacon_int, enum network_type net_type,
u8 beacon_ie_len, u8 assoc_req_len,
u8 assoc_resp_len, u8 *assoc_info);
-void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel);
-void ath6kl_connect_ap_mode_sta(struct ath6kl *ar, u16 aid, u8 *mac_addr,
- u8 keymgmt, u8 ucipher, u8 auth,
- u8 assoc_req_len, u8 *assoc_info);
void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason,
u8 *bssid, u8 assoc_resp_len,
u8 *assoc_info, u16 prot_reason_status);
@@ -627,11 +534,11 @@ void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid);
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_target_failure(struct ath6kl *ar);
+void ath6kl_cfg80211_scan_node(struct wiphy *wiphy, struct bss *ni);
#endif /* CORE_H */
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/debug.c b/trunk/drivers/net/wireless/ath/ath6kl/debug.c
index ba3f23d71150..316136c8b903 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/trunk/drivers/net/wireless/ath/ath6kl/debug.c
@@ -15,26 +15,7 @@
*/
#include "core.h"
-
-#include
-#include
-#include
-
#include "debug.h"
-#include "target.h"
-
-struct ath6kl_fwlog_slot {
- __le32 timestamp;
- __le32 length;
-
- /* max ATH6KL_FWLOG_PAYLOAD_SIZE bytes */
- u8 payload[0];
-};
-
-#define ATH6KL_FWLOG_SIZE 32768
-#define ATH6KL_FWLOG_SLOT_SIZE (sizeof(struct ath6kl_fwlog_slot) + \
- ATH6KL_FWLOG_PAYLOAD_SIZE)
-#define ATH6KL_FWLOG_VALID_MASK 0x1ffff
int ath6kl_printk(const char *level, const char *fmt, ...)
{
@@ -55,27 +36,6 @@ int ath6kl_printk(const char *level, const char *fmt, ...)
}
#ifdef CONFIG_ATH6KL_DEBUG
-
-#define REG_OUTPUT_LEN_PER_LINE 25
-#define REGTYPE_STR_LEN 100
-
-struct ath6kl_diag_reg_info {
- u32 reg_start;
- u32 reg_end;
- const char *reg_info;
-};
-
-static const struct ath6kl_diag_reg_info diag_reg[] = {
- { 0x20000, 0x200fc, "General DMA and Rx registers" },
- { 0x28000, 0x28900, "MAC PCU register & keycache" },
- { 0x20800, 0x20a40, "QCU" },
- { 0x21000, 0x212f0, "DCU" },
- { 0x4000, 0x42e4, "RTC" },
- { 0x540000, 0x540000 + (256 * 1024), "RAM" },
- { 0x29800, 0x2B210, "Base Band" },
- { 0x1C000, 0x1C748, "Analog" },
-};
-
void ath6kl_dump_registers(struct ath6kl_device *dev,
struct ath6kl_irq_proc_registers *irq_proc_reg,
struct ath6kl_irq_enable_reg *irq_enable_reg)
@@ -187,748 +147,4 @@ void dump_cred_dist_stats(struct htc_target *target)
target->cred_dist_cntxt->cur_free_credits);
}
-static int ath6kl_debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war)
-{
- switch (war) {
- case ATH6KL_WAR_INVALID_RATE:
- ar->debug.war_stats.invalid_rate++;
- break;
- }
-}
-
-static ssize_t read_file_war_stats(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- char *buf;
- unsigned int len = 0, buf_len = 1500;
- ssize_t ret_cnt;
-
- buf = kzalloc(buf_len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- len += scnprintf(buf + len, buf_len - len, "\n");
- len += scnprintf(buf + len, buf_len - len, "%25s\n",
- "Workaround stats");
- len += scnprintf(buf + len, buf_len - len, "%25s\n\n",
- "=================");
- len += scnprintf(buf + len, buf_len - len, "%20s %10u\n",
- "Invalid rates", ar->debug.war_stats.invalid_rate);
-
- if (WARN_ON(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_war_stats = {
- .read = read_file_war_stats,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static void ath6kl_debug_fwlog_add(struct ath6kl *ar, const void *buf,
- size_t buf_len)
-{
- struct circ_buf *fwlog = &ar->debug.fwlog_buf;
- size_t space;
- int i;
-
- /* entries must all be equal size */
- if (WARN_ON(buf_len != ATH6KL_FWLOG_SLOT_SIZE))
- return;
-
- space = CIRC_SPACE(fwlog->head, fwlog->tail, ATH6KL_FWLOG_SIZE);
- if (space < buf_len)
- /* discard oldest slot */
- fwlog->tail = (fwlog->tail + ATH6KL_FWLOG_SLOT_SIZE) &
- (ATH6KL_FWLOG_SIZE - 1);
-
- for (i = 0; i < buf_len; i += space) {
- space = CIRC_SPACE_TO_END(fwlog->head, fwlog->tail,
- ATH6KL_FWLOG_SIZE);
-
- if ((size_t) space > buf_len - i)
- space = buf_len - i;
-
- memcpy(&fwlog->buf[fwlog->head], buf, space);
- fwlog->head = (fwlog->head + space) & (ATH6KL_FWLOG_SIZE - 1);
- }
-
-}
-
-void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len)
-{
- struct ath6kl_fwlog_slot *slot = ar->debug.fwlog_tmp;
- size_t slot_len;
-
- if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE))
- return;
-
- spin_lock_bh(&ar->debug.fwlog_lock);
-
- slot->timestamp = cpu_to_le32(jiffies);
- slot->length = cpu_to_le32(len);
- memcpy(slot->payload, buf, len);
-
- slot_len = sizeof(*slot) + len;
-
- if (slot_len < ATH6KL_FWLOG_SLOT_SIZE)
- memset(slot->payload + len, 0,
- ATH6KL_FWLOG_SLOT_SIZE - slot_len);
-
- ath6kl_debug_fwlog_add(ar, slot, ATH6KL_FWLOG_SLOT_SIZE);
-
- spin_unlock_bh(&ar->debug.fwlog_lock);
-}
-
-static bool ath6kl_debug_fwlog_empty(struct ath6kl *ar)
-{
- return CIRC_CNT(ar->debug.fwlog_buf.head,
- ar->debug.fwlog_buf.tail,
- ATH6KL_FWLOG_SLOT_SIZE) == 0;
-}
-
-static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct circ_buf *fwlog = &ar->debug.fwlog_buf;
- size_t len = 0, buf_len = count;
- ssize_t ret_cnt;
- char *buf;
- int ccnt;
-
- buf = vmalloc(buf_len);
- if (!buf)
- return -ENOMEM;
-
- /* read undelivered logs from firmware */
- ath6kl_read_fwlogs(ar);
-
- spin_lock_bh(&ar->debug.fwlog_lock);
-
- while (len < buf_len && !ath6kl_debug_fwlog_empty(ar)) {
- ccnt = CIRC_CNT_TO_END(fwlog->head, fwlog->tail,
- ATH6KL_FWLOG_SIZE);
-
- if ((size_t) ccnt > buf_len - len)
- ccnt = buf_len - len;
-
- memcpy(buf + len, &fwlog->buf[fwlog->tail], ccnt);
- len += ccnt;
-
- fwlog->tail = (fwlog->tail + ccnt) &
- (ATH6KL_FWLOG_SIZE - 1);
- }
-
- spin_unlock_bh(&ar->debug.fwlog_lock);
-
- if (WARN_ON(len > buf_len))
- len = buf_len;
-
- ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
-
- vfree(buf);
-
- return ret_cnt;
-}
-
-static const struct file_operations fops_fwlog = {
- .open = ath6kl_debugfs_open,
- .read = ath6kl_fwlog_read,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_fwlog_mask_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), "0x%x\n", ar->debug.fwlog_mask);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t ath6kl_fwlog_mask_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- int ret;
-
- ret = kstrtou32_from_user(user_buf, count, 0, &ar->debug.fwlog_mask);
- if (ret)
- return ret;
-
- ret = ath6kl_wmi_config_debug_module_cmd(ar->wmi,
- ATH6KL_FWLOG_VALID_MASK,
- ar->debug.fwlog_mask);
- if (ret)
- return ret;
-
- return count;
-}
-
-static const struct file_operations fops_fwlog_mask = {
- .open = ath6kl_debugfs_open,
- .read = ath6kl_fwlog_mask_read,
- .write = ath6kl_fwlog_mask_write,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct target_stats *tgt_stats = &ar->target_stats;
- char *buf;
- unsigned int len = 0, buf_len = 1500;
- int i;
- long left;
- ssize_t ret_cnt;
-
- buf = kzalloc(buf_len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- if (down_interruptible(&ar->sem)) {
- kfree(buf);
- return -EBUSY;
- }
-
- set_bit(STATS_UPDATE_PEND, &ar->flag);
-
- if (ath6kl_wmi_get_stats_cmd(ar->wmi)) {
- up(&ar->sem);
- kfree(buf);
- return -EIO;
- }
-
- left = wait_event_interruptible_timeout(ar->event_wq,
- !test_bit(STATS_UPDATE_PEND,
- &ar->flag), WMI_TIMEOUT);
-
- up(&ar->sem);
-
- if (left <= 0) {
- kfree(buf);
- return -ETIMEDOUT;
- }
-
- len += scnprintf(buf + len, buf_len - len, "\n");
- len += scnprintf(buf + len, buf_len - len, "%25s\n",
- "Target Tx stats");
- len += scnprintf(buf + len, buf_len - len, "%25s\n\n",
- "=================");
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Ucast packets", tgt_stats->tx_ucast_pkt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Bcast packets", tgt_stats->tx_bcast_pkt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Ucast byte", tgt_stats->tx_ucast_byte);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Bcast byte", tgt_stats->tx_bcast_byte);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Rts success cnt", tgt_stats->tx_rts_success_cnt);
- for (i = 0; i < 4; i++)
- len += scnprintf(buf + len, buf_len - len,
- "%18s %d %10llu\n", "PER on ac",
- i, tgt_stats->tx_pkt_per_ac[i]);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Error", tgt_stats->tx_err);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Fail count", tgt_stats->tx_fail_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Retry count", tgt_stats->tx_retry_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Multi retry cnt", tgt_stats->tx_mult_retry_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Rts fail cnt", tgt_stats->tx_rts_fail_cnt);
- len += scnprintf(buf + len, buf_len - len, "%25s %10llu\n\n",
- "TKIP counter measure used",
- tgt_stats->tkip_cnter_measures_invoked);
-
- len += scnprintf(buf + len, buf_len - len, "%25s\n",
- "Target Rx stats");
- len += scnprintf(buf + len, buf_len - len, "%25s\n",
- "=================");
-
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Ucast packets", tgt_stats->rx_ucast_pkt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
- "Ucast Rate", tgt_stats->rx_ucast_rate);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Bcast packets", tgt_stats->rx_bcast_pkt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Ucast byte", tgt_stats->rx_ucast_byte);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Bcast byte", tgt_stats->rx_bcast_byte);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Fragmented pkt", tgt_stats->rx_frgment_pkt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Error", tgt_stats->rx_err);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "CRC Err", tgt_stats->rx_crc_err);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Key chache miss", tgt_stats->rx_key_cache_miss);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Decrypt Err", tgt_stats->rx_decrypt_err);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Duplicate frame", tgt_stats->rx_dupl_frame);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Tkip Mic failure", tgt_stats->tkip_local_mic_fail);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "TKIP format err", tgt_stats->tkip_fmt_err);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "CCMP format Err", tgt_stats->ccmp_fmt_err);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n",
- "CCMP Replay Err", tgt_stats->ccmp_replays);
-
- len += scnprintf(buf + len, buf_len - len, "%25s\n",
- "Misc Target stats");
- len += scnprintf(buf + len, buf_len - len, "%25s\n",
- "=================");
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Beacon Miss count", tgt_stats->cs_bmiss_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Num Connects", tgt_stats->cs_connect_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Num disconnects", tgt_stats->cs_discon_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
- "Beacon avg rssi", tgt_stats->cs_ave_beacon_rssi);
-
- 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_tgt_stats = {
- .read = read_file_tgt_stats,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-#define print_credit_info(fmt_str, ep_list_field) \
- (len += scnprintf(buf + len, buf_len - len, fmt_str, \
- ep_list->ep_list_field))
-#define CREDIT_INFO_DISPLAY_STRING_LEN 200
-#define CREDIT_INFO_LEN 128
-
-static ssize_t read_file_credit_dist_stats(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;
- struct htc_endpoint_credit_dist *ep_list;
- char *buf;
- unsigned int buf_len, len = 0;
- ssize_t ret_cnt;
-
- buf_len = CREDIT_INFO_DISPLAY_STRING_LEN +
- get_queue_depth(&target->cred_dist_list) * CREDIT_INFO_LEN;
- buf = kzalloc(buf_len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- len += scnprintf(buf + len, buf_len - len, "%25s%5d\n",
- "Total Avail Credits: ",
- target->cred_dist_cntxt->total_avail_credits);
- len += scnprintf(buf + len, buf_len - len, "%25s%5d\n",
- "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"
- " Seek_cred Cred_sz Cred_per_msg Cred_to_dist"
- " qdepth\n");
-
- list_for_each_entry(ep_list, &target->cred_dist_list, list) {
- print_credit_info(" %2d", endpoint);
- print_credit_info("%10x", dist_flags);
- print_credit_info("%8d", cred_norm);
- print_credit_info("%9d", cred_min);
- print_credit_info("%9d", credits);
- print_credit_info("%10d", cred_assngd);
- print_credit_info("%13d", seek_cred);
- print_credit_info("%12d", cred_sz);
- 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(&((struct htc_endpoint *)
- ep_list->htc_rsvd)->txq));
- }
-
- 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_credit_dist_stats = {
- .read = read_file_credit_dist_stats,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static unsigned long ath6kl_get_num_reg(void)
-{
- int i;
- unsigned long n_reg = 0;
-
- for (i = 0; i < ARRAY_SIZE(diag_reg); i++)
- n_reg = n_reg +
- (diag_reg[i].reg_end - diag_reg[i].reg_start) / 4 + 1;
-
- return n_reg;
-}
-
-static bool ath6kl_dbg_is_diag_reg_valid(u32 reg_addr)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(diag_reg); i++) {
- if (reg_addr >= diag_reg[i].reg_start &&
- reg_addr <= diag_reg[i].reg_end)
- return true;
- }
-
- return false;
-}
-
-static ssize_t ath6kl_regread_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- u8 buf[50];
- unsigned int len = 0;
-
- if (ar->debug.dbgfs_diag_reg)
- len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n",
- ar->debug.dbgfs_diag_reg);
- else
- len += scnprintf(buf + len, sizeof(buf) - len,
- "All diag registers\n");
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t ath6kl_regread_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- u8 buf[50];
- unsigned int len;
- unsigned long reg_addr;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
-
- buf[len] = '\0';
-
- if (strict_strtoul(buf, 0, ®_addr))
- return -EINVAL;
-
- if ((reg_addr % 4) != 0)
- return -EINVAL;
-
- if (reg_addr && !ath6kl_dbg_is_diag_reg_valid(reg_addr))
- return -EINVAL;
-
- ar->debug.dbgfs_diag_reg = reg_addr;
-
- return count;
-}
-
-static const struct file_operations fops_diag_reg_read = {
- .read = ath6kl_regread_read,
- .write = ath6kl_regread_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static int ath6kl_regdump_open(struct inode *inode, struct file *file)
-{
- struct ath6kl *ar = inode->i_private;
- u8 *buf;
- unsigned long int reg_len;
- unsigned int len = 0, n_reg;
- u32 addr;
- __le32 reg_val;
- int i, status;
-
- /* Dump all the registers if no register is specified */
- if (!ar->debug.dbgfs_diag_reg)
- n_reg = ath6kl_get_num_reg();
- else
- n_reg = 1;
-
- reg_len = n_reg * REG_OUTPUT_LEN_PER_LINE;
- if (n_reg > 1)
- reg_len += REGTYPE_STR_LEN;
-
- buf = vmalloc(reg_len);
- if (!buf)
- return -ENOMEM;
-
- if (n_reg == 1) {
- addr = ar->debug.dbgfs_diag_reg;
-
- status = ath6kl_diag_read32(ar,
- TARG_VTOP(ar->target_type, addr),
- (u32 *)®_val);
- if (status)
- goto fail_reg_read;
-
- len += scnprintf(buf + len, reg_len - len,
- "0x%06x 0x%08x\n", addr, le32_to_cpu(reg_val));
- goto done;
- }
-
- for (i = 0; i < ARRAY_SIZE(diag_reg); i++) {
- len += scnprintf(buf + len, reg_len - len,
- "%s\n", diag_reg[i].reg_info);
- for (addr = diag_reg[i].reg_start;
- addr <= diag_reg[i].reg_end; addr += 4) {
- status = ath6kl_diag_read32(ar,
- TARG_VTOP(ar->target_type, addr),
- (u32 *)®_val);
- if (status)
- goto fail_reg_read;
-
- len += scnprintf(buf + len, reg_len - len,
- "0x%06x 0x%08x\n",
- addr, le32_to_cpu(reg_val));
- }
- }
-
-done:
- file->private_data = buf;
- return 0;
-
-fail_reg_read:
- ath6kl_warn("Unable to read memory:%u\n", addr);
- vfree(buf);
- return -EIO;
-}
-
-static ssize_t ath6kl_regdump_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- u8 *buf = file->private_data;
- return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
-}
-
-static int ath6kl_regdump_release(struct inode *inode, struct file *file)
-{
- vfree(file->private_data);
- return 0;
-}
-
-static const struct file_operations fops_reg_dump = {
- .open = ath6kl_regdump_open,
- .read = ath6kl_regdump_read,
- .release = ath6kl_regdump_release,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_lrssi_roam_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- unsigned long lrssi_roam_threshold;
- 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 (strict_strtoul(buf, 0, &lrssi_roam_threshold))
- return -EINVAL;
-
- ar->lrssi_roam_threshold = lrssi_roam_threshold;
-
- ath6kl_wmi_set_roam_lrssi_cmd(ar->wmi, ar->lrssi_roam_threshold);
-
- return count;
-}
-
-static ssize_t ath6kl_lrssi_roam_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- char buf[32];
- unsigned int len;
-
- len = snprintf(buf, sizeof(buf), "%u\n", ar->lrssi_roam_threshold);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_lrssi_roam_threshold = {
- .read = ath6kl_lrssi_roam_read,
- .write = ath6kl_lrssi_roam_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_regwrite_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- u8 buf[32];
- unsigned int len = 0;
-
- len = scnprintf(buf, sizeof(buf), "Addr: 0x%x Val: 0x%x\n",
- ar->debug.diag_reg_addr_wr, ar->debug.diag_reg_val_wr);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t ath6kl_regwrite_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- char buf[32];
- char *sptr, *token;
- unsigned int len = 0;
- u32 reg_addr, reg_val;
-
- 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 (kstrtou32(token, 0, ®_addr))
- return -EINVAL;
-
- if (!ath6kl_dbg_is_diag_reg_valid(reg_addr))
- return -EINVAL;
-
- if (kstrtou32(sptr, 0, ®_val))
- return -EINVAL;
-
- ar->debug.diag_reg_addr_wr = reg_addr;
- ar->debug.diag_reg_val_wr = reg_val;
-
- if (ath6kl_diag_write32(ar, ar->debug.diag_reg_addr_wr,
- cpu_to_le32(ar->debug.diag_reg_val_wr)))
- return -EIO;
-
- return count;
-}
-
-static const struct file_operations fops_diag_reg_write = {
- .read = ath6kl_regwrite_read,
- .write = ath6kl_regwrite_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);
- if (ar->debug.fwlog_buf.buf == NULL)
- return -ENOMEM;
-
- ar->debug.fwlog_tmp = kmalloc(ATH6KL_FWLOG_SLOT_SIZE, GFP_KERNEL);
- if (ar->debug.fwlog_tmp == NULL) {
- vfree(ar->debug.fwlog_buf.buf);
- return -ENOMEM;
- }
-
- spin_lock_init(&ar->debug.fwlog_lock);
-
- /*
- * Actually we are lying here but don't know how to read the mask
- * value from the firmware.
- */
- ar->debug.fwlog_mask = 0;
-
- ar->debugfs_phy = debugfs_create_dir("ath6kl",
- ar->wdev->wiphy->debugfsdir);
- if (!ar->debugfs_phy) {
- vfree(ar->debug.fwlog_buf.buf);
- kfree(ar->debug.fwlog_tmp);
- return -ENOMEM;
- }
-
- debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar,
- &fops_tgt_stats);
-
- debugfs_create_file("credit_dist_stats", S_IRUSR, ar->debugfs_phy, ar,
- &fops_credit_dist_stats);
-
- debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar,
- &fops_fwlog);
-
- debugfs_create_file("fwlog_mask", S_IRUSR | S_IWUSR, ar->debugfs_phy,
- ar, &fops_fwlog_mask);
-
- debugfs_create_file("reg_addr", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar,
- &fops_diag_reg_read);
-
- debugfs_create_file("reg_dump", S_IRUSR, ar->debugfs_phy, ar,
- &fops_reg_dump);
-
- debugfs_create_file("lrssi_roam_threshold", S_IRUSR | S_IWUSR,
- ar->debugfs_phy, ar, &fops_lrssi_roam_threshold);
-
- debugfs_create_file("reg_write", S_IRUSR | S_IWUSR,
- ar->debugfs_phy, ar, &fops_diag_reg_write);
-
- debugfs_create_file("war_stats", S_IRUSR, ar->debugfs_phy, ar,
- &fops_war_stats);
-
- return 0;
-}
-
-void ath6kl_debug_cleanup(struct ath6kl *ar)
-{
- vfree(ar->debug.fwlog_buf.buf);
- kfree(ar->debug.fwlog_tmp);
-}
-
#endif
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/debug.h b/trunk/drivers/net/wireless/ath/ath6kl/debug.h
index 9288a3ce1e39..66b399962f01 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/trunk/drivers/net/wireless/ath/ath6kl/debug.h
@@ -34,12 +34,8 @@ enum ATH6K_DEBUG_MASK {
ATH6KL_DBG_TRC = BIT(11), /* generic func tracing */
ATH6KL_DBG_SCATTER = BIT(12), /* hif scatter tracing */
ATH6KL_DBG_WLAN_CFG = BIT(13), /* cfg80211 i/f file tracing */
- ATH6KL_DBG_RAW_BYTES = BIT(14), /* dump tx/rx frames */
+ ATH6KL_DBG_RAW_BYTES = BIT(14), /* dump tx/rx and wmi frames */
ATH6KL_DBG_AGGR = BIT(15), /* aggregation */
- ATH6KL_DBG_SDIO = BIT(16),
- ATH6KL_DBG_SDIO_DUMP = BIT(17),
- ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */
- ATH6KL_DBG_WMI_DUMP = BIT(19),
ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */
};
@@ -56,10 +52,6 @@ extern int ath6kl_printk(const char *level, const char *fmt, ...)
#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask)
-enum ath6kl_war {
- ATH6KL_WAR_INVALID_RATE,
-};
-
#ifdef CONFIG_ATH6KL_DEBUG
#define ath6kl_dbg(mask, fmt, ...) \
({ \
@@ -73,14 +65,12 @@ enum ath6kl_war {
})
static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
- const char *msg, const char *prefix,
- const void *buf, size_t len)
+ const char *msg, const void *buf,
+ size_t len)
{
if (debug_mask & mask) {
- if (msg)
- ath6kl_dbg(mask, "%s\n", msg);
-
- print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
+ ath6kl_dbg(mask, "%s\n", msg);
+ print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len);
}
}
@@ -88,11 +78,6 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
struct ath6kl_irq_proc_registers *irq_proc_reg,
struct ath6kl_irq_enable_reg *irq_en_reg);
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_init(struct ath6kl *ar);
-void ath6kl_debug_cleanup(struct ath6kl *ar);
-
#else
static inline int ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask,
const char *fmt, ...)
@@ -101,8 +86,8 @@ static inline int ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask,
}
static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
- const char *msg, const char *prefix,
- const void *buf, size_t len)
+ const char *msg, const void *buf,
+ size_t len)
{
}
@@ -115,24 +100,6 @@ static inline void ath6kl_dump_registers(struct ath6kl_device *dev,
static inline void dump_cred_dist_stats(struct htc_target *target)
{
}
-
-static inline void ath6kl_debug_fwlog_event(struct ath6kl *ar,
- const void *buf, size_t len)
-{
-}
-
-static inline void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war)
-{
-}
-
-static inline int ath6kl_debug_init(struct ath6kl *ar)
-{
- return 0;
-}
-
-static inline void ath6kl_debug_cleanup(struct ath6kl *ar)
-{
-}
-
#endif
+
#endif
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/hif-ops.h b/trunk/drivers/net/wireless/ath/ath6kl/hif-ops.h
index d6c898f3d0b3..c923979776a0 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/hif-ops.h
+++ b/trunk/drivers/net/wireless/ath/ath6kl/hif-ops.h
@@ -69,9 +69,4 @@ 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)
-{
- 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 797e2d1d9bf9..5ceff54775a1 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/hif.h
+++ b/trunk/drivers/net/wireless/ath/ath6kl/hif.h
@@ -202,7 +202,6 @@ 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);
};
#endif
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/htc.c b/trunk/drivers/net/wireless/ath/ath6kl/htc.c
index f88a7c9e4148..a8dc5c3ea567 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/trunk/drivers/net/wireless/ath/ath6kl/htc.c
@@ -22,19 +22,8 @@
#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
-static void ath6kl_htc_tx_buf_align(u8 **buf, unsigned long len)
-{
- u8 *align_addr;
-
- if (!IS_ALIGNED((unsigned long) *buf, 4)) {
- align_addr = PTR_ALIGN(*buf - 4, 4);
- memmove(align_addr, *buf, len);
- *buf = align_addr;
- }
-}
-
-static void ath6kl_htc_tx_prep_pkt(struct htc_packet *packet, u8 flags,
- int ctrl0, int ctrl1)
+static void htc_prep_send_pkt(struct htc_packet *packet, u8 flags, int ctrl0,
+ int ctrl1)
{
struct htc_frame_hdr *hdr;
@@ -178,8 +167,7 @@ static void htc_async_tx_scat_complete(struct htc_target *target,
htc_tx_complete(endpoint, &tx_compq);
}
-static int ath6kl_htc_tx_issue(struct htc_target *target,
- struct htc_packet *packet)
+static int htc_issue_send(struct htc_target *target, struct htc_packet *packet)
{
int status;
bool sync = false;
@@ -208,7 +196,7 @@ static int ath6kl_htc_tx_issue(struct htc_target *target,
HIF_WR_SYNC_BLOCK_INC);
packet->status = status;
- packet->buf += HTC_HDR_LENGTH;
+ packet->buf += HTC_HDR_LENGTH;
} else
status = hif_write_async(target->dev->ar,
target->dev->ar->mbox_info.htc_addr,
@@ -277,9 +265,9 @@ static int htc_check_credits(struct htc_target *target,
return 0;
}
-static void ath6kl_htc_tx_pkts_get(struct htc_target *target,
- struct htc_endpoint *endpoint,
- struct list_head *queue)
+static void htc_tx_pkts_get(struct htc_target *target,
+ struct htc_endpoint *endpoint,
+ struct list_head *queue)
{
int req_cred;
u8 flags;
@@ -358,11 +346,11 @@ static int htc_get_credit_padding(unsigned int cred_sz, int *len,
return cred_pad;
}
-static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target,
- struct htc_endpoint *endpoint,
- struct hif_scatter_req *scat_req,
- int n_scat,
- struct list_head *queue)
+static int htc_setup_send_scat_list(struct htc_target *target,
+ struct htc_endpoint *endpoint,
+ struct hif_scatter_req *scat_req,
+ int n_scat,
+ struct list_head *queue)
{
struct htc_packet *packet;
int i, len, rem_scat, cred_pad;
@@ -382,23 +370,27 @@ static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target,
cred_pad = htc_get_credit_padding(target->tgt_cred_sz,
&len, endpoint);
- if (cred_pad < 0 || rem_scat < len) {
+ if (cred_pad < 0) {
+ status = -EINVAL;
+ break;
+ }
+
+ if (rem_scat < len) {
+ /* exceeds what we can transfer */
status = -ENOSPC;
break;
}
rem_scat -= len;
/* now remove it from the queue */
+ packet = list_first_entry(queue, struct htc_packet, list);
list_del(&packet->list);
scat_req->scat_list[i].packet = packet;
/* prepare packet and flag message as part of a send bundle */
- ath6kl_htc_tx_prep_pkt(packet,
+ htc_prep_send_pkt(packet,
packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE,
cred_pad, packet->info.tx.seqno);
- /* Make sure the buffer is 4-byte aligned */
- ath6kl_htc_tx_buf_align(&packet->buf,
- packet->act_len + HTC_HDR_LENGTH);
scat_req->scat_list[i].buf = packet->buf;
scat_req->scat_list[i].len = len;
@@ -410,7 +402,7 @@ static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target,
}
/* Roll back scatter setup in case of any failure */
- if (scat_req->scat_entries < HTC_MIN_HTC_MSGS_TO_BUNDLE) {
+ if (status || (scat_req->scat_entries < HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
for (i = scat_req->scat_entries - 1; i >= 0; i--) {
packet = scat_req->scat_list[i].packet;
if (packet) {
@@ -418,32 +410,31 @@ static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target,
list_add(&packet->list, queue);
}
}
- return -EAGAIN;
+ return -EINVAL;
}
- return status;
+ return 0;
}
/*
- * Drain a queue and send as bundles this function may return without fully
- * draining the queue when
+ * htc_issue_send_bundle: drain a queue and send as bundles
+ * this function may return without fully draining the queue
+ * when
*
* 1. scatter resources are exhausted
* 2. a message that will consume a partial credit will stop the
* bundling process early
* 3. we drop below the minimum number of messages for a bundle
*/
-static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
- struct list_head *queue,
- int *sent_bundle, int *n_bundle_pkts)
+static void htc_issue_send_bundle(struct htc_endpoint *endpoint,
+ struct list_head *queue,
+ int *sent_bundle, int *n_bundle_pkts)
{
struct htc_target *target = endpoint->target;
struct hif_scatter_req *scat_req = NULL;
int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0;
- int status;
while (true) {
- status = 0;
n_scat = get_queue_depth(queue);
n_scat = min(n_scat, target->msg_per_bndl_max);
@@ -466,10 +457,8 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
scat_req->len = 0;
scat_req->scat_entries = 0;
- status = ath6kl_htc_tx_setup_scat_list(target, endpoint,
- scat_req, n_scat,
- queue);
- if (status == -EAGAIN) {
+ if (htc_setup_send_scat_list(target, endpoint, scat_req,
+ n_scat, queue)) {
hif_scatter_req_add(target->dev->ar, scat_req);
break;
}
@@ -483,21 +472,18 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
"send scatter total bytes: %d , entries: %d\n",
scat_req->len, scat_req->scat_entries);
ath6kldev_submit_scat_req(target->dev, scat_req, false);
-
- if (status)
- break;
}
*sent_bundle = n_sent_bundle;
*n_bundle_pkts = tot_pkts_bundle;
- ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "%s (sent:%d)\n",
- __func__, n_sent_bundle);
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "htc_issue_send_bundle (sent:%d)\n",
+ n_sent_bundle);
return;
}
-static void ath6kl_htc_tx_from_queue(struct htc_target *target,
- struct htc_endpoint *endpoint)
+static void htc_tx_from_ep_txq(struct htc_target *target,
+ struct htc_endpoint *endpoint)
{
struct list_head txq;
struct htc_packet *packet;
@@ -525,7 +511,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
if (list_empty(&endpoint->txq))
break;
- ath6kl_htc_tx_pkts_get(target, endpoint, &txq);
+ htc_tx_pkts_get(target, endpoint, &txq);
if (list_empty(&txq))
break;
@@ -542,8 +528,8 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
int temp1 = 0, temp2 = 0;
- ath6kl_htc_tx_bundle(endpoint, &txq,
- &temp1, &temp2);
+ htc_issue_send_bundle(endpoint, &txq,
+ &temp1, &temp2);
bundle_sent += temp1;
n_pkts_bundle += temp2;
}
@@ -555,9 +541,9 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
list);
list_del(&packet->list);
- ath6kl_htc_tx_prep_pkt(packet, packet->info.tx.flags,
- 0, packet->info.tx.seqno);
- ath6kl_htc_tx_issue(target, packet);
+ htc_prep_send_pkt(packet, packet->info.tx.flags,
+ 0, packet->info.tx.seqno);
+ htc_issue_send(target, packet);
}
spin_lock_bh(&target->tx_lock);
@@ -570,9 +556,9 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
spin_unlock_bh(&target->tx_lock);
}
-static bool ath6kl_htc_tx_try(struct htc_target *target,
- struct htc_endpoint *endpoint,
- struct htc_packet *tx_pkt)
+static bool htc_try_send(struct htc_target *target,
+ struct htc_endpoint *endpoint,
+ struct htc_packet *tx_pkt)
{
struct htc_ep_callbacks ep_cb;
int txq_depth;
@@ -608,7 +594,7 @@ static bool ath6kl_htc_tx_try(struct htc_target *target,
list_add_tail(&tx_pkt->list, &endpoint->txq);
spin_unlock_bh(&target->tx_lock);
- ath6kl_htc_tx_from_queue(target, endpoint);
+ htc_tx_from_ep_txq(target, endpoint);
return true;
}
@@ -642,7 +628,7 @@ static void htc_chk_ep_txq(struct htc_target *target)
* chance to reclaim credits from lower priority
* ones.
*/
- ath6kl_htc_tx_from_queue(target, endpoint);
+ htc_tx_from_ep_txq(target, endpoint);
spin_lock_bh(&target->tx_lock);
}
spin_unlock_bh(&target->tx_lock);
@@ -694,8 +680,8 @@ static int htc_setup_tx_complete(struct htc_target *target)
/* we want synchronous operation */
send_pkt->completion = NULL;
- ath6kl_htc_tx_prep_pkt(send_pkt, 0, 0, 0);
- status = ath6kl_htc_tx_issue(target, send_pkt);
+ htc_prep_send_pkt(send_pkt, 0, 0, 0);
+ status = htc_issue_send(target, send_pkt);
if (send_pkt != NULL)
htc_reclaim_txctrl_buf(target, send_pkt);
@@ -747,7 +733,7 @@ int ath6kl_htc_tx(struct htc_target *target, struct htc_packet *packet)
endpoint = &target->endpoint[packet->endpoint];
- if (!ath6kl_htc_tx_try(target, endpoint, packet)) {
+ if (!htc_try_send(target, endpoint, packet)) {
packet->status = (target->htc_flags & HTC_OP_STATE_STOPPING) ?
-ECANCELED : -ENOSPC;
INIT_LIST_HEAD(&queue);
@@ -860,8 +846,8 @@ void ath6kl_htc_indicate_activity_change(struct htc_target *target,
/* HTC Rx */
-static inline void ath6kl_htc_rx_update_stats(struct htc_endpoint *endpoint,
- int n_look_ahds)
+static inline void htc_update_rx_stats(struct htc_endpoint *endpoint,
+ int n_look_ahds)
{
endpoint->ep_st.rx_pkts++;
if (n_look_ahds == 1)
@@ -908,9 +894,8 @@ static void reclaim_rx_ctrl_buf(struct htc_target *target,
spin_unlock_bh(&target->htc_lock);
}
-static int ath6kl_htc_rx_packet(struct htc_target *target,
- struct htc_packet *packet,
- u32 rx_len)
+static int dev_rx_pkt(struct htc_target *target, struct htc_packet *packet,
+ u32 rx_len)
{
struct ath6kl_device *dev = target->dev;
u32 padded_len;
@@ -944,9 +929,9 @@ static int ath6kl_htc_rx_packet(struct htc_target *target,
* "hint" that there are more single-packets to fetch
* on this endpoint.
*/
-static void ath6kl_htc_rx_set_indicate(u32 lk_ahd,
- struct htc_endpoint *endpoint,
- struct htc_packet *packet)
+static void set_rxpkt_indication_flag(u32 lk_ahd,
+ struct htc_endpoint *endpoint,
+ struct htc_packet *packet)
{
struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)&lk_ahd;
@@ -957,7 +942,7 @@ static void ath6kl_htc_rx_set_indicate(u32 lk_ahd,
}
}
-static void ath6kl_htc_rx_chk_water_mark(struct htc_endpoint *endpoint)
+static void chk_rx_water_mark(struct htc_endpoint *endpoint)
{
struct htc_ep_callbacks ep_cb = endpoint->ep_cb;
@@ -974,9 +959,8 @@ static void ath6kl_htc_rx_chk_water_mark(struct htc_endpoint *endpoint)
}
/* This function is called with rx_lock held */
-static int ath6kl_htc_rx_setup(struct htc_target *target,
- struct htc_endpoint *ep,
- u32 *lk_ahds, struct list_head *queue, int n_msg)
+static int htc_setup_rxpkts(struct htc_target *target, struct htc_endpoint *ep,
+ u32 *lk_ahds, struct list_head *queue, int n_msg)
{
struct htc_packet *packet;
/* FIXME: type of lk_ahds can't be right */
@@ -1076,10 +1060,10 @@ static int ath6kl_htc_rx_setup(struct htc_target *target,
return status;
}
-static int ath6kl_htc_rx_alloc(struct htc_target *target,
- u32 lk_ahds[], int msg,
- struct htc_endpoint *endpoint,
- struct list_head *queue)
+static int alloc_and_prep_rxpkts(struct htc_target *target,
+ u32 lk_ahds[], int msg,
+ struct htc_endpoint *endpoint,
+ struct list_head *queue)
{
int status = 0;
struct htc_packet *packet, *tmp_pkt;
@@ -1145,8 +1129,8 @@ static int ath6kl_htc_rx_alloc(struct htc_target *target,
n_msg = 1;
/* Setup packet buffers for each message */
- status = ath6kl_htc_rx_setup(target, endpoint, &lk_ahds[i],
- queue, n_msg);
+ status = htc_setup_rxpkts(target, endpoint, &lk_ahds[i], queue,
+ n_msg);
/*
* This is due to unavailabilty of buffers to rx entire data.
@@ -1192,9 +1176,9 @@ static void htc_ctrl_rx(struct htc_target *context, struct htc_packet *packets)
packets->act_len + HTC_HDR_LENGTH);
ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES,
- "Unexpected ENDPOINT 0 Message", "",
- packets->buf - HTC_HDR_LENGTH,
- packets->act_len + HTC_HDR_LENGTH);
+ "Unexpected ENDPOINT 0 Message",
+ packets->buf - HTC_HDR_LENGTH,
+ packets->act_len + HTC_HDR_LENGTH);
}
htc_reclaim_rxbuf(context, packets, &context->endpoint[0]);
@@ -1328,7 +1312,7 @@ static int htc_parse_trailer(struct htc_target *target,
memcpy((u8 *)&next_lk_ahds[0], lk_ahd->lk_ahd, 4);
ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Next Look Ahead",
- "", next_lk_ahds, 4);
+ next_lk_ahds, 4);
*n_lk_ahds = 1;
}
@@ -1347,7 +1331,7 @@ static int htc_parse_trailer(struct htc_target *target,
(struct htc_bundle_lkahd_rpt *) record_buf;
ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Bundle lk_ahd",
- "", record_buf, record->len);
+ record_buf, record->len);
for (i = 0; i < len; i++) {
memcpy((u8 *)&next_lk_ahds[i],
@@ -1380,8 +1364,7 @@ static int htc_proc_trailer(struct htc_target *target,
ath6kl_dbg(ATH6KL_DBG_HTC_RECV, "+htc_proc_trailer (len:%d)\n", len);
- ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Recv Trailer", "",
- buf, len);
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Recv Trailer", buf, len);
orig_buf = buf;
orig_len = len;
@@ -1419,14 +1402,14 @@ static int htc_proc_trailer(struct htc_target *target,
if (status)
ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "BAD Recv Trailer",
- "", orig_buf, orig_len);
+ orig_buf, orig_len);
return status;
}
-static int ath6kl_htc_rx_process_hdr(struct htc_target *target,
- struct htc_packet *packet,
- u32 *next_lkahds, int *n_lkahds)
+static int htc_proc_rxhdr(struct htc_target *target,
+ struct htc_packet *packet,
+ u32 *next_lkahds, int *n_lkahds)
{
int status = 0;
u16 payload_len;
@@ -1436,8 +1419,8 @@ 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);
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "HTC Recv PKT", packet->buf,
+ packet->act_len);
/*
* NOTE: we cannot assume the alignment of buf, so we use the safe
@@ -1478,12 +1461,12 @@ 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_err("htc_proc_rxhdr, lk_ahd mismatch! (pPkt:0x%p flags:0x%X)\n",
+ packet, packet->info.rx.rx_flags);
ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Expected Message lk_ahd",
- "", &packet->info.rx.exp_hdr, 4);
+ &packet->info.rx.exp_hdr, 4);
ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Current Frame Header",
- "", (u8 *)&lk_ahd, sizeof(lk_ahd));
+ (u8 *)&lk_ahd, sizeof(lk_ahd));
status = -ENOMEM;
goto fail_rx;
}
@@ -1491,8 +1474,8 @@ static int ath6kl_htc_rx_process_hdr(struct htc_target *target,
if (htc_hdr->flags & HTC_FLG_RX_TRAILER) {
if (htc_hdr->ctrl[0] < sizeof(struct htc_record_hdr) ||
htc_hdr->ctrl[0] > payload_len) {
- ath6kl_err("%s(): invalid hdr (payload len should be :%d, CB[0] is:%d)\n",
- __func__, payload_len, htc_hdr->ctrl[0]);
+ ath6kl_err("htc_proc_rxhdr, invalid hdr (payload len should be :%d, CB[0] is:%d)\n",
+ payload_len, htc_hdr->ctrl[0]);
status = -ENOMEM;
goto fail_rx;
}
@@ -1519,20 +1502,20 @@ static int ath6kl_htc_rx_process_hdr(struct htc_target *target,
fail_rx:
if (status)
ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "BAD HTC Recv PKT",
- "", packet->buf,
+ 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", "",
+ "HTC - Application Msg",
packet->buf, packet->act_len);
}
return status;
}
-static void ath6kl_htc_rx_complete(struct htc_endpoint *endpoint,
- struct htc_packet *packet)
+static void do_rx_completion(struct htc_endpoint *endpoint,
+ struct htc_packet *packet)
{
ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
"htc calling ep %d recv callback on packet 0x%p\n",
@@ -1540,10 +1523,10 @@ static void ath6kl_htc_rx_complete(struct htc_endpoint *endpoint,
endpoint->ep_cb.rx(endpoint->target, packet);
}
-static int ath6kl_htc_rx_bundle(struct htc_target *target,
- struct list_head *rxq,
- struct list_head *sync_compq,
- int *n_pkt_fetched, bool part_bundle)
+static int htc_issue_rxpkt_bundle(struct htc_target *target,
+ struct list_head *rxq,
+ struct list_head *sync_compq,
+ int *n_pkt_fetched, bool part_bundle)
{
struct hif_scatter_req *scat_req;
struct htc_packet *packet;
@@ -1565,15 +1548,15 @@ static int ath6kl_htc_rx_bundle(struct htc_target *target,
* This would only happen if the target ignored our max
* bundle limit.
*/
- ath6kl_warn("%s(): partial bundle detected num:%d , %d\n",
- __func__, get_queue_depth(rxq), n_scat_pkt);
+ ath6kl_warn("htc_issue_rxpkt_bundle : partial bundle detected num:%d , %d\n",
+ get_queue_depth(rxq), n_scat_pkt);
}
len = 0;
ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
- "%s(): (numpackets: %d , actual : %d)\n",
- __func__, get_queue_depth(rxq), n_scat_pkt);
+ "htc_issue_rxpkt_bundle (numpackets: %d , actual : %d)\n",
+ get_queue_depth(rxq), n_scat_pkt);
scat_req = hif_scatter_req_get(target->dev->ar);
@@ -1633,10 +1616,9 @@ static int ath6kl_htc_rx_bundle(struct htc_target *target,
return status;
}
-static int ath6kl_htc_rx_process_packets(struct htc_target *target,
- struct list_head *comp_pktq,
- u32 lk_ahds[],
- int *n_lk_ahd)
+static int htc_proc_fetched_rxpkts(struct htc_target *target,
+ struct list_head *comp_pktq, u32 lk_ahds[],
+ int *n_lk_ahd)
{
struct htc_packet *packet, *tmp_pkt;
struct htc_endpoint *ep;
@@ -1647,8 +1629,7 @@ static int ath6kl_htc_rx_process_packets(struct htc_target *target,
ep = &target->endpoint[packet->endpoint];
/* process header for each of the recv packet */
- status = ath6kl_htc_rx_process_hdr(target, packet, lk_ahds,
- n_lk_ahd);
+ status = htc_proc_rxhdr(target, packet, lk_ahds, n_lk_ahd);
if (status)
return status;
@@ -1658,8 +1639,8 @@ static int ath6kl_htc_rx_process_packets(struct htc_target *target,
* based on the lookahead.
*/
if (*n_lk_ahd > 0)
- ath6kl_htc_rx_set_indicate(lk_ahds[0],
- ep, packet);
+ set_rxpkt_indication_flag(lk_ahds[0],
+ ep, packet);
} else
/*
* Packets in a bundle automatically have
@@ -1668,20 +1649,20 @@ static int ath6kl_htc_rx_process_packets(struct htc_target *target,
packet->info.rx.indicat_flags |=
HTC_RX_FLAGS_INDICATE_MORE_PKTS;
- ath6kl_htc_rx_update_stats(ep, *n_lk_ahd);
+ htc_update_rx_stats(ep, *n_lk_ahd);
if (packet->info.rx.rx_flags & HTC_RX_PKT_PART_OF_BUNDLE)
ep->ep_st.rx_bundl += 1;
- ath6kl_htc_rx_complete(ep, packet);
+ do_rx_completion(ep, packet);
}
return status;
}
-static int ath6kl_htc_rx_fetch(struct htc_target *target,
- struct list_head *rx_pktq,
- struct list_head *comp_pktq)
+static int htc_fetch_rxpkts(struct htc_target *target,
+ struct list_head *rx_pktq,
+ struct list_head *comp_pktq)
{
int fetched_pkts;
bool part_bundle = false;
@@ -1697,10 +1678,10 @@ static int ath6kl_htc_rx_fetch(struct htc_target *target,
* bundle transfer and recv bundling is
* allowed.
*/
- status = ath6kl_htc_rx_bundle(target, rx_pktq,
- comp_pktq,
- &fetched_pkts,
- part_bundle);
+ status = htc_issue_rxpkt_bundle(target, rx_pktq,
+ comp_pktq,
+ &fetched_pkts,
+ part_bundle);
if (status)
return status;
@@ -1729,8 +1710,7 @@ static int ath6kl_htc_rx_fetch(struct htc_target *target,
HTC_RX_PKT_IGNORE_LOOKAHEAD;
/* go fetch the packet */
- status = ath6kl_htc_rx_packet(target, packet,
- packet->act_len);
+ status = dev_rx_pkt(target, packet, packet->act_len);
if (status)
return status;
@@ -1784,9 +1764,9 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
* Try to allocate as many HTC RX packets indicated by the
* look_aheads.
*/
- status = ath6kl_htc_rx_alloc(target, look_aheads,
- num_look_ahead, endpoint,
- &rx_pktq);
+ status = alloc_and_prep_rxpkts(target, look_aheads,
+ num_look_ahead, endpoint,
+ &rx_pktq);
if (status)
break;
@@ -1801,15 +1781,14 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
num_look_ahead = 0;
- status = ath6kl_htc_rx_fetch(target, &rx_pktq, &comp_pktq);
+ status = htc_fetch_rxpkts(target, &rx_pktq, &comp_pktq);
if (!status)
- ath6kl_htc_rx_chk_water_mark(endpoint);
+ chk_rx_water_mark(endpoint);
/* Process fetched packets */
- status = ath6kl_htc_rx_process_packets(target, &comp_pktq,
- look_aheads,
- &num_look_ahead);
+ status = htc_proc_fetched_rxpkts(target, &comp_pktq,
+ look_aheads, &num_look_ahead);
if (!num_look_ahead || status)
break;
@@ -1902,14 +1881,14 @@ static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target)
packet->completion = NULL;
/* get the message from the device, this will block */
- if (ath6kl_htc_rx_packet(target, packet, packet->act_len))
+ if (dev_rx_pkt(target, packet, packet->act_len))
goto fail_ctrl_rx;
/* process receive header */
- packet->status = ath6kl_htc_rx_process_hdr(target, packet, NULL, NULL);
+ packet->status = htc_proc_rxhdr(target, packet, NULL, NULL);
if (packet->status) {
- ath6kl_err("htc_wait_for_ctrl_msg, ath6kl_htc_rx_process_hdr failed (status = %d)\n",
+ ath6kl_err("htc_wait_for_ctrl_msg, htc_proc_rxhdr failed (status = %d)\n",
packet->status);
goto fail_ctrl_rx;
}
@@ -1956,7 +1935,7 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
list_for_each_entry_safe(packet, tmp_pkt, pkt_queue, list) {
packet->status = -ECANCELED;
list_del(&packet->list);
- ath6kl_htc_rx_complete(endpoint, packet);
+ do_rx_completion(endpoint, packet);
}
return status;
@@ -2055,8 +2034,8 @@ int ath6kl_htc_conn_service(struct htc_target *target,
/* we want synchronous operation */
tx_pkt->completion = NULL;
- ath6kl_htc_tx_prep_pkt(tx_pkt, 0, 0, 0);
- status = ath6kl_htc_tx_issue(target, tx_pkt);
+ htc_prep_send_pkt(tx_pkt, 0, 0, 0);
+ status = htc_issue_send(target, tx_pkt);
if (status)
goto fail_tx;
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/init.c b/trunk/drivers/net/wireless/ath/ath6kl/init.c
index c1d2366704b5..9d10322eac41 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/init.c
+++ b/trunk/drivers/net/wireless/ath/ath6kl/init.c
@@ -15,8 +15,6 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include
-#include
#include
#include "core.h"
#include "cfg80211.h"
@@ -25,10 +23,8 @@
#include "hif-ops.h"
unsigned int debug_mask;
-static unsigned int testmode;
module_param(debug_mask, uint, 0644);
-module_param(testmode, uint, 0644);
/*
* Include definitions here that can be used to tune the WLAN module
@@ -57,6 +53,12 @@ module_param(testmode, uint, 0644);
#define CONFIG_AR600x_DEBUG_UART_TX_PIN 8
+enum addr_type {
+ DATASET_PATCH_ADDR,
+ APP_LOAD_ADDR,
+ APP_START_OVERRIDE_ADDR,
+};
+
#define ATH6KL_DATA_OFFSET 64
struct sk_buff *ath6kl_buf_alloc(int size)
{
@@ -65,7 +67,7 @@ struct sk_buff *ath6kl_buf_alloc(int size)
/* Add chacheline space at front and back of buffer */
reserved = (2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
- sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES;
+ sizeof(struct htc_packet);
skb = dev_alloc_skb(size + reserved);
if (skb)
@@ -83,7 +85,7 @@ void ath6kl_init_profile_info(struct ath6kl *ar)
ar->prwise_crypto = NONE_CRYPT;
ar->prwise_crypto_len = 0;
ar->grp_crypto = NONE_CRYPT;
- ar->grp_crypto_len = 0;
+ ar->grp_crpto_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));
@@ -106,6 +108,17 @@ static u8 ath6kl_get_fw_iftype(struct ath6kl *ar)
}
}
+static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
+ u32 item_offset)
+{
+ u32 addr = 0;
+
+ if (ar->target_type == TARGET_TYPE_AR6003)
+ addr = ATH6KL_HI_START_ADDR + item_offset;
+
+ return addr;
+}
+
static int ath6kl_set_host_app_area(struct ath6kl *ar)
{
u32 address, data;
@@ -114,15 +127,16 @@ static int ath6kl_set_host_app_area(struct ath6kl *ar)
/* Fetch the address of the host_app_area_s
* instance in the host interest area */
address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_app_host_interest));
- address = TARG_VTOP(ar->target_type, address);
+ address = TARG_VTOP(address);
- if (ath6kl_diag_read32(ar, address, &data))
+ if (ath6kl_read_reg_diag(ar, &address, &data))
return -EIO;
- address = TARG_VTOP(ar->target_type, data);
+ address = TARG_VTOP(data);
host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION;
- if (ath6kl_diag_write(ar, address, (u8 *) &host_app_area,
- sizeof(struct host_app_area)))
+ if (ath6kl_access_datadiag(ar, address,
+ (u8 *)&host_app_area,
+ sizeof(struct host_app_area), false))
return -EIO;
return 0;
@@ -276,7 +290,6 @@ static void ath6kl_init_control_info(struct ath6kl *ar)
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));
@@ -357,10 +370,10 @@ static void ath6kl_dump_target_assert_info(struct ath6kl *ar)
/* 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);
+ address = TARG_VTOP(address);
/* read RAM location through diagnostic window */
- status = ath6kl_diag_read32(ar, address, ®dump_loc);
+ status = ath6kl_read_reg_diag(ar, &address, ®dump_loc);
if (status || !regdump_loc) {
ath6kl_err("failed to get ptr to register dump area\n");
@@ -369,11 +382,15 @@ static void ath6kl_dump_target_assert_info(struct ath6kl *ar)
ath6kl_dbg(ATH6KL_DBG_TRC, "location of register dump data: 0x%X\n",
regdump_loc);
- regdump_loc = TARG_VTOP(ar->target_type, regdump_loc);
+
+ regdump_loc = TARG_VTOP(regdump_loc);
/* fetch register dump data */
- status = ath6kl_diag_read(ar, regdump_loc, (u8 *)®dump_val[0],
- REG_DUMP_COUNT_AR6003 * (sizeof(u32)));
+ status = ath6kl_access_datadiag(ar,
+ regdump_loc,
+ (u8 *)®dump_val[0],
+ REG_DUMP_COUNT_AR6003 * (sizeof(u32)),
+ true);
if (status) {
ath6kl_err("failed to get register dump\n");
@@ -399,7 +416,6 @@ void ath6kl_target_failure(struct ath6kl *ar)
static int ath6kl_target_config_wlan_params(struct ath6kl *ar)
{
int status = 0;
- int ret;
/*
* Configure the device for rx dot11 header rules. "0,0" are the
@@ -444,28 +460,6 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar)
status = -EIO;
}
- if (ar->p2p) {
- ret = ath6kl_wmi_info_req_cmd(ar->wmi,
- P2P_FLAG_CAPABILITIES_REQ |
- P2P_FLAG_MACADDR_REQ |
- P2P_FLAG_HMODEL_REQ);
- if (ret) {
- ath6kl_dbg(ATH6KL_DBG_TRC, "failed to request P2P "
- "capabilities (%d) - assuming P2P not "
- "supported\n", ret);
- ar->p2p = 0;
- }
- }
-
- if (ar->p2p) {
- /* Enable Probe Request reporting for P2P */
- 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);
- }
- }
-
return status;
}
@@ -501,10 +495,6 @@ int ath6kl_configure_target(struct ath6kl *ar)
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);
@@ -528,21 +518,29 @@ int ath6kl_configure_target(struct ath6kl *ar)
* but possible in theory.
*/
- param = ar->hw.board_ext_data_addr;
- ram_reserved_size = ar->hw.reserved_ram_size;
-
- if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_board_ext_data)),
- (u8 *)¶m, 4) != 0) {
- ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n");
- return -EIO;
- }
+ if (ar->target_type == TARGET_TYPE_AR6003) {
+ if (ar->version.target_ver == AR6003_REV2_VERSION) {
+ param = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
+ ram_reserved_size = AR6003_REV2_RAM_RESERVE_SIZE;
+ } else {
+ param = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
+ ram_reserved_size = AR6003_REV3_RAM_RESERVE_SIZE;
+ }
- if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_end_ram_reserve_sz)),
- (u8 *)&ram_reserved_size, 4) != 0) {
- ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n");
- return -EIO;
+ if (ath6kl_bmi_write(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_board_ext_data)),
+ (u8 *)¶m, 4) != 0) {
+ ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n");
+ return -EIO;
+ }
+ if (ath6kl_bmi_write(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_end_ram_reserve_sz)),
+ (u8 *)&ram_reserved_size, 4) != 0) {
+ ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n");
+ return -EIO;
+ }
}
/* set the block size for the target */
@@ -570,12 +568,6 @@ struct ath6kl *ath6kl_core_alloc(struct device *sdev)
ar->wdev = wdev;
wdev->iftype = NL80211_IFTYPE_STATION;
- if (ath6kl_debug_init(ar)) {
- ath6kl_err("Failed to initialize debugfs\n");
- ath6kl_cfg80211_deinit(ar);
- return NULL;
- }
-
dev = alloc_netdev(0, "wlan%d", ether_setup);
if (!dev) {
ath6kl_err("no memory for network device instance\n");
@@ -587,6 +579,7 @@ struct ath6kl *ath6kl_core_alloc(struct device *sdev)
SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
wdev->netdev = dev;
ar->sme_state = SME_DISCONNECTED;
+ ar->auto_auth_stage = AUTH_IDLE;
init_netdev(dev);
@@ -618,6 +611,29 @@ int ath6kl_unavail_ev(struct ath6kl *ar)
}
/* firmware upload */
+static u32 ath6kl_get_load_address(u32 target_ver, enum addr_type type)
+{
+ WARN_ON(target_ver != AR6003_REV2_VERSION &&
+ target_ver != AR6003_REV3_VERSION);
+
+ switch (type) {
+ case DATASET_PATCH_ADDR:
+ return (target_ver == AR6003_REV2_VERSION) ?
+ AR6003_REV2_DATASET_PATCH_ADDRESS :
+ AR6003_REV3_DATASET_PATCH_ADDRESS;
+ case APP_LOAD_ADDR:
+ return (target_ver == AR6003_REV2_VERSION) ?
+ AR6003_REV2_APP_LOAD_ADDRESS :
+ 0x1234;
+ case APP_START_OVERRIDE_ADDR:
+ return (target_ver == AR6003_REV2_VERSION) ?
+ AR6003_REV2_APP_START_OVERRIDE :
+ AR6003_REV3_APP_START_OVERRIDE;
+ default:
+ return 0;
+ }
+}
+
static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
u8 **fw, size_t *fw_len)
{
@@ -639,79 +655,15 @@ static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
return ret;
}
-#ifdef CONFIG_OF
-static const char *get_target_ver_dir(const struct ath6kl *ar)
-{
- switch (ar->version.target_ver) {
- case AR6003_REV1_VERSION:
- return "ath6k/AR6003/hw1.0";
- case AR6003_REV2_VERSION:
- return "ath6k/AR6003/hw2.0";
- case AR6003_REV3_VERSION:
- return "ath6k/AR6003/hw2.1.1";
- }
- ath6kl_warn("%s: unsupported target version 0x%x.\n", __func__,
- ar->version.target_ver);
- return NULL;
-}
-
-/*
- * Check the device tree for a board-id and use it to construct
- * the pathname to the firmware file. Used (for now) to find a
- * fallback to the "bdata.bin" file--typically a symlink to the
- * appropriate board-specific file.
- */
-static bool check_device_tree(struct ath6kl *ar)
-{
- static const char *board_id_prop = "atheros,board-id";
- struct device_node *node;
- char board_filename[64];
- const char *board_id;
- int ret;
-
- for_each_compatible_node(node, NULL, "atheros,ath6kl") {
- board_id = of_get_property(node, board_id_prop, NULL);
- if (board_id == NULL) {
- ath6kl_warn("No \"%s\" property on %s node.\n",
- board_id_prop, node->name);
- continue;
- }
- snprintf(board_filename, sizeof(board_filename),
- "%s/bdata.%s.bin", get_target_ver_dir(ar), board_id);
-
- ret = ath6kl_get_fw(ar, board_filename, &ar->fw_board,
- &ar->fw_board_len);
- if (ret) {
- ath6kl_err("Failed to get DT board file %s: %d\n",
- board_filename, ret);
- continue;
- }
- return true;
- }
- return false;
-}
-#else
-static bool check_device_tree(struct ath6kl *ar)
-{
- return false;
-}
-#endif /* CONFIG_OF */
-
static int ath6kl_fetch_board_file(struct ath6kl *ar)
{
const char *filename;
int ret;
- if (ar->fw_board != NULL)
- return 0;
-
switch (ar->version.target_ver) {
case AR6003_REV2_VERSION:
filename = AR6003_REV2_BOARD_DATA_FILE;
break;
- case AR6004_REV1_VERSION:
- filename = AR6004_REV1_BOARD_DATA_FILE;
- break;
default:
filename = AR6003_REV3_BOARD_DATA_FILE;
break;
@@ -724,11 +676,6 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar)
return 0;
}
- if (check_device_tree(ar)) {
- /* got board file from device tree */
- return 0;
- }
-
/* there was no proper board file, try to use default instead */
ath6kl_warn("Failed to get board file %s (%d), trying to find default board file.\n",
filename, ret);
@@ -737,9 +684,6 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar)
case AR6003_REV2_VERSION:
filename = AR6003_REV2_DEFAULT_BOARD_DATA_FILE;
break;
- case AR6004_REV1_VERSION:
- filename = AR6004_REV1_DEFAULT_BOARD_DATA_FILE;
- break;
default:
filename = AR6003_REV3_DEFAULT_BOARD_DATA_FILE;
break;
@@ -759,384 +703,47 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar)
return 0;
}
-static int ath6kl_fetch_otp_file(struct ath6kl *ar)
-{
- const char *filename;
- int ret;
-
- if (ar->fw_otp != NULL)
- return 0;
-
- switch (ar->version.target_ver) {
- case AR6003_REV2_VERSION:
- filename = AR6003_REV2_OTP_FILE;
- break;
- case AR6004_REV1_VERSION:
- ath6kl_dbg(ATH6KL_DBG_TRC, "AR6004 doesn't need OTP file\n");
- return 0;
- break;
- default:
- filename = AR6003_REV3_OTP_FILE;
- break;
- }
-
- ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
- &ar->fw_otp_len);
- if (ret) {
- ath6kl_err("Failed to get OTP file %s: %d\n",
- filename, ret);
- return ret;
- }
-
- return 0;
-}
-
-static int ath6kl_fetch_fw_file(struct ath6kl *ar)
-{
- const char *filename;
- int ret;
-
- if (ar->fw != NULL)
- return 0;
-
- if (testmode) {
- switch (ar->version.target_ver) {
- case AR6003_REV2_VERSION:
- filename = AR6003_REV2_TCMD_FIRMWARE_FILE;
- break;
- case AR6003_REV3_VERSION:
- filename = AR6003_REV3_TCMD_FIRMWARE_FILE;
- break;
- case AR6004_REV1_VERSION:
- ath6kl_warn("testmode not supported with ar6004\n");
- return -EOPNOTSUPP;
- default:
- ath6kl_warn("unknown target version: 0x%x\n",
- ar->version.target_ver);
- return -EINVAL;
- }
-
- set_bit(TESTMODE, &ar->flag);
-
- goto get_fw;
- }
-
- switch (ar->version.target_ver) {
- case AR6003_REV2_VERSION:
- filename = AR6003_REV2_FIRMWARE_FILE;
- break;
- case AR6004_REV1_VERSION:
- filename = AR6004_REV1_FIRMWARE_FILE;
- break;
- default:
- filename = AR6003_REV3_FIRMWARE_FILE;
- break;
- }
-
-get_fw:
- ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
- if (ret) {
- ath6kl_err("Failed to get firmware file %s: %d\n",
- filename, ret);
- return ret;
- }
-
- return 0;
-}
-
-static int ath6kl_fetch_patch_file(struct ath6kl *ar)
-{
- const char *filename;
- int ret;
-
- switch (ar->version.target_ver) {
- case AR6003_REV2_VERSION:
- filename = AR6003_REV2_PATCH_FILE;
- break;
- case AR6004_REV1_VERSION:
- /* FIXME: implement for AR6004 */
- return 0;
- break;
- default:
- filename = AR6003_REV3_PATCH_FILE;
- break;
- }
-
- if (ar->fw_patch == NULL) {
- ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
- &ar->fw_patch_len);
- if (ret) {
- ath6kl_err("Failed to get patch file %s: %d\n",
- filename, ret);
- return ret;
- }
- }
-
- return 0;
-}
-
-static int ath6kl_fetch_fw_api1(struct ath6kl *ar)
-{
- int ret;
-
- ret = ath6kl_fetch_otp_file(ar);
- if (ret)
- return ret;
-
- ret = ath6kl_fetch_fw_file(ar);
- if (ret)
- return ret;
-
- ret = ath6kl_fetch_patch_file(ar);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static int ath6kl_fetch_fw_api2(struct ath6kl *ar)
-{
- size_t magic_len, len, ie_len;
- const struct firmware *fw;
- struct ath6kl_fw_ie *hdr;
- const char *filename;
- const u8 *data;
- int ret, ie_id, i, index, bit;
- __le32 *val;
-
- switch (ar->version.target_ver) {
- case AR6003_REV2_VERSION:
- filename = AR6003_REV2_FIRMWARE_2_FILE;
- break;
- case AR6003_REV3_VERSION:
- filename = AR6003_REV3_FIRMWARE_2_FILE;
- break;
- case AR6004_REV1_VERSION:
- filename = AR6004_REV1_FIRMWARE_2_FILE;
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- ret = request_firmware(&fw, filename, ar->dev);
- if (ret)
- return ret;
-
- data = fw->data;
- len = fw->size;
-
- /* magic also includes the null byte, check that as well */
- magic_len = strlen(ATH6KL_FIRMWARE_MAGIC) + 1;
-
- if (len < magic_len) {
- ret = -EINVAL;
- goto out;
- }
-
- if (memcmp(data, ATH6KL_FIRMWARE_MAGIC, magic_len) != 0) {
- ret = -EINVAL;
- goto out;
- }
-
- len -= magic_len;
- data += magic_len;
-
- /* loop elements */
- while (len > sizeof(struct ath6kl_fw_ie)) {
- /* hdr is unaligned! */
- hdr = (struct ath6kl_fw_ie *) data;
-
- ie_id = le32_to_cpup(&hdr->id);
- ie_len = le32_to_cpup(&hdr->len);
-
- len -= sizeof(*hdr);
- data += sizeof(*hdr);
-
- if (len < ie_len) {
- ret = -EINVAL;
- goto out;
- }
-
- switch (ie_id) {
- case ATH6KL_FW_IE_OTP_IMAGE:
- ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n",
- ie_len);
-
- ar->fw_otp = kmemdup(data, ie_len, GFP_KERNEL);
-
- if (ar->fw_otp == NULL) {
- ret = -ENOMEM;
- goto out;
- }
-
- ar->fw_otp_len = ie_len;
- break;
- case ATH6KL_FW_IE_FW_IMAGE:
- ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n",
- ie_len);
-
- ar->fw = kmemdup(data, ie_len, GFP_KERNEL);
-
- if (ar->fw == NULL) {
- ret = -ENOMEM;
- goto out;
- }
-
- ar->fw_len = ie_len;
- break;
- case ATH6KL_FW_IE_PATCH_IMAGE:
- ath6kl_dbg(ATH6KL_DBG_BOOT, "found patch image ie (%zd B)\n",
- ie_len);
-
- ar->fw_patch = kmemdup(data, ie_len, GFP_KERNEL);
-
- if (ar->fw_patch == NULL) {
- ret = -ENOMEM;
- goto out;
- }
-
- ar->fw_patch_len = ie_len;
- break;
- case ATH6KL_FW_IE_RESERVED_RAM_SIZE:
- val = (__le32 *) data;
- ar->hw.reserved_ram_size = le32_to_cpup(val);
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "found reserved ram size ie 0x%d\n",
- ar->hw.reserved_ram_size);
- break;
- case ATH6KL_FW_IE_CAPABILITIES:
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "found firmware capabilities ie (%zd B)\n",
- ie_len);
-
- for (i = 0; i < ATH6KL_FW_CAPABILITY_MAX; i++) {
- index = ALIGN(i, 8) / 8;
- bit = i % 8;
-
- if (data[index] & (1 << bit))
- __set_bit(i, ar->fw_capabilities);
- }
-
- ath6kl_dbg_dump(ATH6KL_DBG_BOOT, "capabilities", "",
- ar->fw_capabilities,
- sizeof(ar->fw_capabilities));
- break;
- case ATH6KL_FW_IE_PATCH_ADDR:
- if (ie_len != sizeof(*val))
- break;
-
- val = (__le32 *) data;
- ar->hw.dataset_patch_addr = le32_to_cpup(val);
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "found patch address ie 0x%d\n",
- ar->hw.dataset_patch_addr);
- break;
- default:
- ath6kl_dbg(ATH6KL_DBG_BOOT, "Unknown fw ie: %u\n",
- le32_to_cpup(&hdr->id));
- break;
- }
-
- len -= ie_len;
- data += ie_len;
- };
-
- ret = 0;
-out:
- release_firmware(fw);
-
- return ret;
-}
-
-static int ath6kl_fetch_firmwares(struct ath6kl *ar)
-{
- int ret;
-
- ret = ath6kl_fetch_board_file(ar);
- if (ret)
- return ret;
-
- ret = ath6kl_fetch_fw_api2(ar);
- if (ret == 0) {
- ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 2\n");
- return 0;
- }
-
- ret = ath6kl_fetch_fw_api1(ar);
- if (ret)
- return ret;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 1\n");
-
- return 0;
-}
static int ath6kl_upload_board_file(struct ath6kl *ar)
{
u32 board_address, board_ext_address, param;
- u32 board_data_size, board_ext_data_size;
int ret;
- if (WARN_ON(ar->fw_board == NULL))
- return -ENOENT;
-
- /*
- * Determine where in Target RAM to write Board Data.
- * For AR6004, host determine Target RAM address for
- * writing board data.
- */
- if (ar->target_type == TARGET_TYPE_AR6004) {
- board_address = AR6004_REV1_BOARD_DATA_ADDRESS;
- ath6kl_bmi_write(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_board_data)),
- (u8 *) &board_address, 4);
- } else {
- ath6kl_bmi_read(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_board_data)),
- (u8 *) &board_address, 4);
+ if (ar->fw_board == NULL) {
+ ret = ath6kl_fetch_board_file(ar);
+ if (ret)
+ return ret;
}
+ /* Determine where in Target RAM to write Board Data */
+ ath6kl_bmi_read(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_board_data)),
+ (u8 *) &board_address, 4);
+ ath6kl_dbg(ATH6KL_DBG_TRC, "board data download addr: 0x%x\n",
+ board_address);
+
/* determine where in target ram to write extended board data */
ath6kl_bmi_read(ar,
ath6kl_get_hi_item_addr(ar,
HI_ITEM(hi_board_ext_data)),
(u8 *) &board_ext_address, 4);
+ ath6kl_dbg(ATH6KL_DBG_TRC, "board file download addr: 0x%x\n",
+ board_ext_address);
+
if (board_ext_address == 0) {
ath6kl_err("Failed to get board file target address.\n");
return -EINVAL;
}
- switch (ar->target_type) {
- case TARGET_TYPE_AR6003:
- board_data_size = AR6003_BOARD_DATA_SZ;
- board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ;
- break;
- case TARGET_TYPE_AR6004:
- board_data_size = AR6004_BOARD_DATA_SZ;
- board_ext_data_size = AR6004_BOARD_EXT_DATA_SZ;
- break;
- default:
- WARN_ON(1);
- return -EINVAL;
- break;
- }
-
- if (ar->fw_board_len == (board_data_size +
- board_ext_data_size)) {
-
+ if (ar->fw_board_len == (AR6003_BOARD_DATA_SZ +
+ AR6003_BOARD_EXT_DATA_SZ)) {
/* write extended board data */
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "writing extended board data to 0x%x (%d B)\n",
- board_ext_address, board_ext_data_size);
-
ret = ath6kl_bmi_write(ar, board_ext_address,
- ar->fw_board + board_data_size,
- board_ext_data_size);
+ ar->fw_board + AR6003_BOARD_DATA_SZ,
+ AR6003_BOARD_EXT_DATA_SZ);
+
if (ret) {
ath6kl_err("Failed to write extended board data: %d\n",
ret);
@@ -1144,25 +751,21 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
}
/* record that extended board data is initialized */
- param = (board_ext_data_size << 16) | 1;
-
+ param = (AR6003_BOARD_EXT_DATA_SZ << 16) | 1;
ath6kl_bmi_write(ar,
ath6kl_get_hi_item_addr(ar,
HI_ITEM(hi_board_ext_data_config)),
(unsigned char *) ¶m, 4);
}
- if (ar->fw_board_len < board_data_size) {
+ if (ar->fw_board_len < AR6003_BOARD_DATA_SZ) {
ath6kl_err("Too small board file: %zu\n", ar->fw_board_len);
ret = -EINVAL;
return ret;
}
- ath6kl_dbg(ATH6KL_DBG_BOOT, "writing board file to 0x%x (%d B)\n",
- board_address, board_data_size);
-
ret = ath6kl_bmi_write(ar, board_address, ar->fw_board,
- board_data_size);
+ AR6003_BOARD_DATA_SZ);
if (ret) {
ath6kl_err("Board file bmi write failed: %d\n", ret);
@@ -1181,16 +784,31 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
static int ath6kl_upload_otp(struct ath6kl *ar)
{
+ const char *filename;
u32 address, param;
int ret;
- if (WARN_ON(ar->fw_otp == NULL))
- return -ENOENT;
+ switch (ar->version.target_ver) {
+ case AR6003_REV2_VERSION:
+ filename = AR6003_REV2_OTP_FILE;
+ break;
+ default:
+ filename = AR6003_REV3_OTP_FILE;
+ break;
+ }
- address = ar->hw.app_load_addr;
+ if (ar->fw_otp == NULL) {
+ ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
+ &ar->fw_otp_len);
+ if (ret) {
+ ath6kl_err("Failed to get OTP file %s: %d\n",
+ filename, ret);
+ return ret;
+ }
+ }
- ath6kl_dbg(ATH6KL_DBG_BOOT, "writing otp to 0x%x (%zd B)\n", address,
- ar->fw_otp_len);
+ address = ath6kl_get_load_address(ar->version.target_ver,
+ APP_LOAD_ADDR);
ret = ath6kl_bmi_fast_download(ar, address, ar->fw_otp,
ar->fw_otp_len);
@@ -1199,25 +817,10 @@ static int ath6kl_upload_otp(struct ath6kl *ar)
return ret;
}
- /* read firmware start address */
- ret = ath6kl_bmi_read(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_app_start)),
- (u8 *) &address, sizeof(address));
-
- if (ret) {
- ath6kl_err("Failed to read hi_app_start: %d\n", ret);
- return ret;
- }
-
- ar->hw.app_start_override_addr = address;
-
- 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", address);
param = 0;
+ address = ath6kl_get_load_address(ar->version.target_ver,
+ APP_START_OVERRIDE_ADDR);
ath6kl_bmi_execute(ar, address, ¶m);
return ret;
@@ -1225,16 +828,30 @@ static int ath6kl_upload_otp(struct ath6kl *ar)
static int ath6kl_upload_firmware(struct ath6kl *ar)
{
+ const char *filename;
u32 address;
int ret;
- if (WARN_ON(ar->fw == NULL))
- return -ENOENT;
+ switch (ar->version.target_ver) {
+ case AR6003_REV2_VERSION:
+ filename = AR6003_REV2_FIRMWARE_FILE;
+ break;
+ default:
+ filename = AR6003_REV3_FIRMWARE_FILE;
+ break;
+ }
- address = ar->hw.app_load_addr;
+ if (ar->fw == NULL) {
+ ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
+ if (ret) {
+ ath6kl_err("Failed to get firmware file %s: %d\n",
+ filename, ret);
+ return ret;
+ }
+ }
- ath6kl_dbg(ATH6KL_DBG_BOOT, "writing firmware to 0x%x (%zd B)\n",
- address, ar->fw_len);
+ address = ath6kl_get_load_address(ar->version.target_ver,
+ APP_LOAD_ADDR);
ret = ath6kl_bmi_fast_download(ar, address, ar->fw, ar->fw_len);
@@ -1243,29 +860,41 @@ static int ath6kl_upload_firmware(struct ath6kl *ar)
return ret;
}
- /*
- * Set starting address for firmware
- * Don't need to setup app_start override addr on AR6004
- */
- if (ar->target_type != TARGET_TYPE_AR6004) {
- address = ar->hw.app_start_override_addr;
- ath6kl_bmi_set_app_start(ar, address);
- }
+ /* Set starting address for firmware */
+ address = ath6kl_get_load_address(ar->version.target_ver,
+ APP_START_OVERRIDE_ADDR);
+ ath6kl_bmi_set_app_start(ar, address);
+
return ret;
}
static int ath6kl_upload_patch(struct ath6kl *ar)
{
+ const char *filename;
u32 address, param;
int ret;
- if (WARN_ON(ar->fw_patch == NULL))
- return -ENOENT;
+ switch (ar->version.target_ver) {
+ case AR6003_REV2_VERSION:
+ filename = AR6003_REV2_PATCH_FILE;
+ break;
+ default:
+ filename = AR6003_REV3_PATCH_FILE;
+ break;
+ }
- address = ar->hw.dataset_patch_addr;
+ if (ar->fw_patch == NULL) {
+ ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
+ &ar->fw_patch_len);
+ if (ret) {
+ ath6kl_err("Failed to get patch file %s: %d\n",
+ filename, ret);
+ return ret;
+ }
+ }
- ath6kl_dbg(ATH6KL_DBG_BOOT, "writing patch to 0x%x (%zd B)\n",
- address, ar->fw_patch_len);
+ address = ath6kl_get_load_address(ar->version.target_ver,
+ DATASET_PATCH_ADDR);
ret = ath6kl_bmi_write(ar, address, ar->fw_patch, ar->fw_patch_len);
if (ret) {
@@ -1287,8 +916,7 @@ static int ath6kl_init_upload(struct ath6kl *ar)
u32 param, options, sleep, address;
int status = 0;
- if (ar->target_type != TARGET_TYPE_AR6003 &&
- ar->target_type != TARGET_TYPE_AR6004)
+ if (ar->target_type != TARGET_TYPE_AR6003)
return -EINVAL;
/* temporarily disable system sleep */
@@ -1320,22 +948,18 @@ static int ath6kl_init_upload(struct ath6kl *ar)
options, sleep);
/* program analog PLL register */
- /* no need to control 40/44MHz clock on AR6004 */
- if (ar->target_type != TARGET_TYPE_AR6004) {
- status = ath6kl_bmi_reg_write(ar, ATH6KL_ANALOG_PLL_REGISTER,
- 0xF9104001);
-
- if (status)
- return status;
+ status = ath6kl_bmi_reg_write(ar, ATH6KL_ANALOG_PLL_REGISTER,
+ 0xF9104001);
+ if (status)
+ return status;
- /* Run at 80/88MHz by default */
- param = SM(CPU_CLOCK_STANDARD, 1);
+ /* Run at 80/88MHz by default */
+ param = SM(CPU_CLOCK_STANDARD, 1);
- address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
- status = ath6kl_bmi_reg_write(ar, address, param);
- if (status)
- return status;
- }
+ address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
+ status = ath6kl_bmi_reg_write(ar, address, param);
+ if (status)
+ return status;
param = 0;
address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
@@ -1412,45 +1036,6 @@ static int ath6kl_init_upload(struct ath6kl *ar)
return status;
}
-static int ath6kl_init_hw_params(struct ath6kl *ar)
-{
- switch (ar->version.target_ver) {
- case AR6003_REV2_VERSION:
- ar->hw.dataset_patch_addr = AR6003_REV2_DATASET_PATCH_ADDRESS;
- 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;
- break;
- case AR6003_REV3_VERSION:
- ar->hw.dataset_patch_addr = AR6003_REV3_DATASET_PATCH_ADDRESS;
- ar->hw.app_load_addr = 0x1234;
- ar->hw.board_ext_data_addr = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
- ar->hw.reserved_ram_size = AR6003_REV3_RAM_RESERVE_SIZE;
- break;
- case AR6004_REV1_VERSION:
- ar->hw.dataset_patch_addr = AR6003_REV2_DATASET_PATCH_ADDRESS;
- ar->hw.app_load_addr = AR6003_REV3_APP_LOAD_ADDRESS;
- ar->hw.board_ext_data_addr = AR6004_REV1_BOARD_EXT_DATA_ADDRESS;
- ar->hw.reserved_ram_size = AR6004_REV1_RAM_RESERVE_SIZE;
- break;
- default:
- ath6kl_err("Unsupported hardware version: 0x%x\n",
- ar->version.target_ver);
- return -EINVAL;
- }
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "target_ver 0x%x target_type 0x%x dataset_patch 0x%x app_load_addr 0x%x\n",
- ar->version.target_ver, ar->target_type,
- ar->hw.dataset_patch_addr, ar->hw.app_load_addr);
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "app_start_override_addr 0x%x board_ext_data_addr 0x%x reserved_ram_size 0x%x",
- ar->hw.app_start_override_addr, ar->hw.board_ext_data_addr,
- ar->hw.reserved_ram_size);
-
- return 0;
-}
-
static int ath6kl_init(struct net_device *dev)
{
struct ath6kl *ar = ath6kl_priv(dev);
@@ -1477,6 +1062,8 @@ static int ath6kl_init(struct net_device *dev)
ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
+ wlan_node_table_init(&ar->scan_table);
+
/*
* 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
@@ -1524,8 +1111,6 @@ static int ath6kl_init(struct net_device *dev)
&ar->flag),
WMI_TIMEOUT);
- ath6kl_dbg(ATH6KL_DBG_BOOT, "firmware booted\n");
-
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);
@@ -1548,8 +1133,6 @@ static int ath6kl_init(struct net_device *dev)
ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
- ar->wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
-
status = ath6kl_target_config_wlan_params(ar);
if (!status)
goto ath6kl_init_done;
@@ -1562,6 +1145,7 @@ static int ath6kl_init(struct net_device *dev)
err_cleanup_scatter:
ath6kl_hif_cleanup_scatter(ar);
err_node_cleanup:
+ wlan_node_table_cleanup(&ar->scan_table);
ath6kl_wmi_shutdown(ar->wmi);
clear_bit(WMI_ENABLED, &ar->flag);
ar->wmi = NULL;
@@ -1591,10 +1175,6 @@ int ath6kl_core_init(struct ath6kl *ar)
ar->target_type = le32_to_cpu(targ_info.type);
ar->wdev->wiphy->hw_version = le32_to_cpu(targ_info.version);
- ret = ath6kl_init_hw_params(ar);
- if (ret)
- goto err_bmi_cleanup;
-
ret = ath6kl_configure_target(ar);
if (ret)
goto err_bmi_cleanup;
@@ -1613,10 +1193,6 @@ int ath6kl_core_init(struct ath6kl *ar)
goto err_htc_cleanup;
}
- ret = ath6kl_fetch_firmwares(ar);
- if (ret)
- goto err_htc_cleanup;
-
ret = ath6kl_init_upload(ar);
if (ret)
goto err_htc_cleanup;
@@ -1709,8 +1285,6 @@ void ath6kl_destroy(struct net_device *dev, unsigned int unregister)
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);
@@ -1718,6 +1292,8 @@ void ath6kl_destroy(struct net_device *dev, unsigned int unregister)
free_netdev(dev);
+ wlan_node_table_cleanup(&ar->scan_table);
+
kfree(ar->fw_board);
kfree(ar->fw_otp);
kfree(ar->fw);
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/main.c b/trunk/drivers/net/wireless/ath/ath6kl/main.c
index 30b5a53db9ed..c336eae0cf48 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/main.c
+++ b/trunk/drivers/net/wireless/ath/ath6kl/main.c
@@ -61,8 +61,7 @@ static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie,
sta = &ar->sta_list[free_slot];
memcpy(sta->mac, mac, ETH_ALEN);
- if (ielen <= ATH6KL_MAX_IE)
- memcpy(sta->wpa_ie, wpaie, ielen);
+ memcpy(sta->wpa_ie, wpaie, ielen);
sta->aid = aid;
sta->keymgmt = keymgmt;
sta->ucipher = ucipher;
@@ -178,8 +177,8 @@ void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie)
static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
{
int status;
+ u8 addr_val[4];
s32 i;
- __le32 addr_val;
/*
* Write bytes 1,2,3 of the register to set the upper address bytes,
@@ -189,18 +188,16 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
for (i = 1; i <= 3; i++) {
/*
* Fill the buffer with the address byte value we want to
- * hit 4 times. No need to worry about endianness as the
- * same byte is copied to all four bytes of addr_val at
- * any time.
+ * hit 4 times.
*/
- memset((u8 *)&addr_val, ((u8 *)&addr)[i], 4);
+ memset(addr_val, ((u8 *)&addr)[i], 4);
/*
* Hit each byte of the register address with a 4-byte
* write operation to the same address, this is a harmless
* operation.
*/
- status = hif_read_write_sync(ar, reg_addr + i, (u8 *)&addr_val,
+ status = hif_read_write_sync(ar, reg_addr + i, addr_val,
4, HIF_WR_SYNC_BYTE_FIX);
if (status)
break;
@@ -218,9 +215,7 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
* cycle to start, the extra 3 byte write to bytes 1,2,3 has no
* effect since we are writing the same values again
*/
- addr_val = cpu_to_le32(addr);
- status = hif_read_write_sync(ar, reg_addr,
- (u8 *)&(addr_val),
+ status = hif_read_write_sync(ar, reg_addr, (u8 *)(&addr),
4, HIF_WR_SYNC_BYTE_INC);
if (status) {
@@ -233,193 +228,90 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
}
/*
- * Read from the hardware through its diagnostic window. No cooperation
- * from the firmware is required for this.
+ * Read from the ATH6KL through its diagnostic window. No cooperation from
+ * the Target is required for this.
*/
-int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value)
+int ath6kl_read_reg_diag(struct ath6kl *ar, u32 *address, u32 *data)
{
- int ret;
+ int status;
/* set window register to start read cycle */
- ret = ath6kl_set_addrwin_reg(ar, WINDOW_READ_ADDR_ADDRESS, address);
- if (ret)
- return ret;
+ status = ath6kl_set_addrwin_reg(ar, WINDOW_READ_ADDR_ADDRESS,
+ *address);
+
+ if (status)
+ return status;
/* read the data */
- ret = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *) value,
- sizeof(*value), HIF_RD_SYNC_BYTE_INC);
- if (ret) {
- ath6kl_warn("failed to read32 through diagnose window: %d\n",
- ret);
- return ret;
+ status = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *)data,
+ sizeof(u32), HIF_RD_SYNC_BYTE_INC);
+ if (status) {
+ ath6kl_err("failed to read from window data addr\n");
+ return status;
}
- return 0;
+ return status;
}
+
/*
* Write to the ATH6KL through its diagnostic window. No cooperation from
* the Target is required for this.
*/
-int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value)
+static int ath6kl_write_reg_diag(struct ath6kl *ar, u32 *address, u32 *data)
{
- int ret;
+ int status;
/* set write data */
- ret = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *) &value,
- sizeof(value), HIF_WR_SYNC_BYTE_INC);
- if (ret) {
- ath6kl_err("failed to write 0x%x during diagnose window to 0x%d\n",
- address, value);
- return ret;
+ status = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *)data,
+ sizeof(u32), HIF_WR_SYNC_BYTE_INC);
+ if (status) {
+ ath6kl_err("failed to write 0x%x to window data addr\n", *data);
+ return status;
}
/* set window register, which starts the write cycle */
return ath6kl_set_addrwin_reg(ar, WINDOW_WRITE_ADDR_ADDRESS,
- address);
+ *address);
}
-int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length)
-{
- u32 count, *buf = data;
- int ret;
-
- if (WARN_ON(length % 4))
- return -EINVAL;
-
- for (count = 0; count < length / 4; count++, address += 4) {
- ret = ath6kl_diag_read32(ar, address, &buf[count]);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length)
+int ath6kl_access_datadiag(struct ath6kl *ar, u32 address,
+ u8 *data, u32 length, bool read)
{
u32 count;
- __le32 *buf = data;
- int ret;
-
- if (WARN_ON(length % 4))
- return -EINVAL;
-
- for (count = 0; count < length / 4; count++, address += 4) {
- ret = ath6kl_diag_write32(ar, address, buf[count]);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-int ath6kl_read_fwlogs(struct ath6kl *ar)
-{
- struct ath6kl_dbglog_hdr debug_hdr;
- struct ath6kl_dbglog_buf debug_buf;
- u32 address, length, dropped, firstbuf, debug_hdr_addr;
- int ret = 0, loop;
- u8 *buf;
-
- buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- address = TARG_VTOP(ar->target_type,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_dbglog_hdr)));
-
- ret = ath6kl_diag_read32(ar, address, &debug_hdr_addr);
- if (ret)
- goto out;
-
- /* Get the contents of the ring buffer */
- if (debug_hdr_addr == 0) {
- ath6kl_warn("Invalid address for debug_hdr_addr\n");
- ret = -EINVAL;
- goto out;
- }
-
- address = TARG_VTOP(ar->target_type, debug_hdr_addr);
- ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr));
-
- address = TARG_VTOP(ar->target_type,
- le32_to_cpu(debug_hdr.dbuf_addr));
- firstbuf = address;
- dropped = le32_to_cpu(debug_hdr.dropped);
- ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
-
- loop = 100;
-
- do {
- address = TARG_VTOP(ar->target_type,
- le32_to_cpu(debug_buf.buffer_addr));
- length = le32_to_cpu(debug_buf.length);
-
- if (length != 0 && (le32_to_cpu(debug_buf.length) <=
- le32_to_cpu(debug_buf.bufsize))) {
- length = ALIGN(length, 4);
-
- ret = ath6kl_diag_read(ar, address,
- buf, length);
- if (ret)
- goto out;
-
- ath6kl_debug_fwlog_event(ar, buf, length);
- }
-
- address = TARG_VTOP(ar->target_type,
- le32_to_cpu(debug_buf.next));
- ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
- if (ret)
- goto out;
-
- loop--;
+ int status = 0;
- if (WARN_ON(loop == 0)) {
- ret = -ETIMEDOUT;
- goto out;
+ for (count = 0; count < length; count += 4, address += 4) {
+ if (read) {
+ status = ath6kl_read_reg_diag(ar, &address,
+ (u32 *) &data[count]);
+ if (status)
+ break;
+ } else {
+ status = ath6kl_write_reg_diag(ar, &address,
+ (u32 *) &data[count]);
+ if (status)
+ break;
}
- } while (address != firstbuf);
-
-out:
- kfree(buf);
+ }
- return ret;
+ return status;
}
-/* FIXME: move to a better place, target.h? */
-#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
-#define AR6004_RESET_CONTROL_ADDRESS 0x00004000
-
static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
bool wait_fot_compltn, bool cold_reset)
{
int status = 0;
u32 address;
- __le32 data;
+ u32 data;
- if (target_type != TARGET_TYPE_AR6003 &&
- target_type != TARGET_TYPE_AR6004)
+ if (target_type != TARGET_TYPE_AR6003)
return;
- data = cold_reset ? cpu_to_le32(RESET_CONTROL_COLD_RST) :
- cpu_to_le32(RESET_CONTROL_MBOX_RST);
+ data = cold_reset ? RESET_CONTROL_COLD_RST : RESET_CONTROL_MBOX_RST;
- switch (target_type) {
- case TARGET_TYPE_AR6003:
- address = AR6003_RESET_CONTROL_ADDRESS;
- break;
- case TARGET_TYPE_AR6004:
- address = AR6004_RESET_CONTROL_ADDRESS;
- break;
- default:
- address = AR6003_RESET_CONTROL_ADDRESS;
- break;
- }
-
- status = ath6kl_diag_write32(ar, address, data);
+ address = RTC_BASE_ADDRESS;
+ status = ath6kl_write_reg_diag(ar, &address, &data);
if (status)
ath6kl_err("failed to reset target\n");
@@ -519,107 +411,68 @@ static void ath6kl_install_static_wep_keys(struct ath6kl *ar)
}
}
-void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel)
-{
- struct ath6kl_req_key *ik;
- int res;
- u8 key_rsc[ATH6KL_KEY_SEQ_LEN];
-
- ik = &ar->ap_mode_bkey;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "AP mode started on %u MHz\n", channel);
-
- switch (ar->auth_mode) {
- case NONE_AUTH:
- if (ar->prwise_crypto == WEP_CRYPT)
- ath6kl_install_static_wep_keys(ar);
- break;
- case WPA_PSK_AUTH:
- case WPA2_PSK_AUTH:
- case (WPA_PSK_AUTH | WPA2_PSK_AUTH):
- if (!ik->valid)
- break;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed addkey for "
- "the initial group key for AP mode\n");
- memset(key_rsc, 0, sizeof(key_rsc));
- res = ath6kl_wmi_addkey_cmd(
- ar->wmi, ik->key_index, ik->key_type,
- 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 "
- "addkey failed: %d\n", res);
- }
- break;
- }
-
- 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 *ar, u16 aid, u8 *mac_addr,
- u8 keymgmt, u8 ucipher, u8 auth,
- u8 assoc_req_len, u8 *assoc_info)
+static void ath6kl_connect_ap_mode(struct ath6kl *ar, u16 channel, u8 *bssid,
+ u16 listen_int, u16 beacon_int,
+ u8 assoc_resp_len, u8 *assoc_info)
{
- u8 *ies = NULL, *wpa_ie = NULL, *pos;
- size_t ies_len = 0;
+ struct net_device *dev = ar->net_dev;
struct station_info sinfo;
+ struct ath6kl_req_key *ik;
+ enum crypto_type keyType = NONE_CRYPT;
- ath6kl_dbg(ATH6KL_DBG_TRC, "new station %pM aid=%d\n", mac_addr, aid);
-
- if (assoc_req_len > sizeof(struct ieee80211_hdr_3addr)) {
- struct ieee80211_mgmt *mgmt =
- (struct ieee80211_mgmt *) assoc_info;
- if (ieee80211_is_assoc_req(mgmt->frame_control) &&
- assoc_req_len >= sizeof(struct ieee80211_hdr_3addr) +
- sizeof(mgmt->u.assoc_req)) {
- ies = mgmt->u.assoc_req.variable;
- ies_len = assoc_info + assoc_req_len - ies;
- } else if (ieee80211_is_reassoc_req(mgmt->frame_control) &&
- assoc_req_len >= sizeof(struct ieee80211_hdr_3addr)
- + sizeof(mgmt->u.reassoc_req)) {
- ies = mgmt->u.reassoc_req.variable;
- ies_len = assoc_info + assoc_req_len - ies;
- }
- }
+ if (memcmp(dev->dev_addr, bssid, ETH_ALEN) == 0) {
+ ik = &ar->ap_mode_bkey;
- pos = ies;
- while (pos && pos + 1 < ies + ies_len) {
- if (pos + 2 + pos[1] > ies + ies_len)
+ switch (ar->auth_mode) {
+ case NONE_AUTH:
+ if (ar->prwise_crypto == WEP_CRYPT)
+ ath6kl_install_static_wep_keys(ar);
break;
- if (pos[0] == WLAN_EID_RSN)
- wpa_ie = pos; /* RSN IE */
- else if (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
- pos[1] >= 4 &&
- pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2) {
- if (pos[5] == 0x01)
- wpa_ie = pos; /* WPA IE */
- else if (pos[5] == 0x04) {
- wpa_ie = pos; /* WPS IE */
- break; /* overrides WPA/RSN IE */
+ case WPA_PSK_AUTH:
+ case WPA2_PSK_AUTH:
+ case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
+ switch (ik->ik_type) {
+ case ATH6KL_CIPHER_TKIP:
+ keyType = TKIP_CRYPT;
+ break;
+ case ATH6KL_CIPHER_AES_CCM:
+ keyType = AES_CRYPT;
+ break;
+ default:
+ goto skip_key;
}
+ ath6kl_wmi_addkey_cmd(ar->wmi, ik->ik_keyix, keyType,
+ GROUP_USAGE, ik->ik_keylen,
+ (u8 *)&ik->ik_keyrsc,
+ ik->ik_keydata,
+ KEY_OP_INIT_VAL, ik->ik_macaddr,
+ SYNC_BOTH_WMIFLAG);
+ break;
}
- pos += 2 + pos[1];
+skip_key:
+ set_bit(CONNECTED, &ar->flag);
+ return;
}
- ath6kl_add_new_sta(ar, mac_addr, aid, wpa_ie,
- wpa_ie ? 2 + wpa_ie[1] : 0,
- keymgmt, ucipher, auth);
+ ath6kl_dbg(ATH6KL_DBG_TRC, "new station %pM aid=%d\n",
+ bssid, channel);
+
+ ath6kl_add_new_sta(ar, bssid, channel, assoc_info, assoc_resp_len,
+ listen_int & 0xFF, beacon_int,
+ (listen_int >> 8) & 0xFF);
/* send event to application */
memset(&sinfo, 0, sizeof(sinfo));
/* TODO: sinfo.generation */
-
- sinfo.assoc_req_ies = ies;
- sinfo.assoc_req_ies_len = ies_len;
- sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
-
- cfg80211_new_sta(ar->net_dev, mac_addr, &sinfo, GFP_KERNEL);
+ /* TODO: need to deliver (Re)AssocReq IEs somehow.. change in
+ * cfg80211 needed, e.g., by adding those into sinfo
+ */
+ cfg80211_new_sta(ar->net_dev, bssid, &sinfo, GFP_KERNEL);
netif_wake_queue(ar->net_dev);
+
+ return;
}
/* Functions for Tx credit handling */
@@ -926,41 +779,6 @@ void ath6kl_disconnect(struct ath6kl *ar)
}
}
-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 */
static const char *get_hw_id_string(u32 id)
@@ -1001,20 +819,17 @@ 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);
- ath6kl_info("hw %s fw %s%s\n",
+ ath6kl_info("hw %s fw %s\n",
get_hw_id_string(ar->wdev->wiphy->hw_version),
- ar->wdev->wiphy->fw_version,
- test_bit(TESTMODE, &ar->flag) ? " testmode" : "");
+ ar->wdev->wiphy->fw_version);
}
void ath6kl_scan_complete_evt(struct ath6kl *ar, int status)
{
ath6kl_cfg80211_scan_complete_event(ar, status);
- if (!ar->usr_bss_filter) {
- clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
+ if (!ar->usr_bss_filter)
ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
- }
ath6kl_dbg(ATH6KL_DBG_WLAN_SCAN, "scan complete: %d\n", status);
}
@@ -1027,6 +842,13 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
{
unsigned long flags;
+ if (ar->nw_type == AP_NETWORK) {
+ ath6kl_connect_ap_mode(ar, channel, bssid, listen_int,
+ beacon_int, assoc_resp_len,
+ assoc_info);
+ return;
+ }
+
ath6kl_cfg80211_connect_event(ar, channel, bssid,
listen_int, beacon_int,
net_type, beacon_ie_len,
@@ -1058,10 +880,8 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
ar->next_ep_id = ENDPOINT_2;
}
- if (!ar->usr_bss_filter) {
- set_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
- ath6kl_wmi_bssfilter_cmd(ar->wmi, CURRENT_BSS_FILTER, 0);
- }
+ if (!ar->usr_bss_filter)
+ ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
}
void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast)
@@ -1095,11 +915,26 @@ static void ath6kl_update_target_stats(struct ath6kl *ar, u8 *ptr, u32 len)
(struct wmi_target_stats *) ptr;
struct target_stats *stats = &ar->target_stats;
struct tkip_ccmp_stats *ccmp_stats;
+ struct bss *conn_bss = NULL;
+ struct cserv_stats *c_stats;
u8 ac;
if (len < sizeof(*tgt_stats))
return;
+ /* update the RSSI of the connected bss */
+ if (test_bit(CONNECTED, &ar->flag)) {
+ conn_bss = ath6kl_wmi_find_node(ar->wmi, ar->bssid);
+ if (conn_bss) {
+ c_stats = &tgt_stats->cserv_stats;
+ conn_bss->ni_rssi =
+ a_sle16_to_cpu(c_stats->cs_ave_beacon_rssi);
+ conn_bss->ni_snr =
+ tgt_stats->cserv_stats.cs_ave_beacon_snr;
+ ath6kl_wmi_node_return(ar->wmi, conn_bss);
+ }
+ }
+
ath6kl_dbg(ATH6KL_DBG_TRC, "updating target stats\n");
stats->tx_pkt += le32_to_cpu(tgt_stats->stats.tx.pkt);
@@ -1330,6 +1165,7 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
u8 assoc_resp_len, u8 *assoc_info,
u16 prot_reason_status)
{
+ struct bss *wmi_ssid_node = NULL;
unsigned long flags;
if (ar->nw_type == AP_NETWORK) {
@@ -1352,10 +1188,7 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
cfg80211_del_sta(ar->net_dev, bssid, GFP_KERNEL);
}
- if (memcmp(ar->net_dev->dev_addr, bssid, ETH_ALEN) == 0) {
- memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
- clear_bit(CONNECTED, &ar->flag);
- }
+ clear_bit(CONNECTED, &ar->flag);
return;
}
@@ -1389,6 +1222,33 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
}
}
+ if ((reason == NO_NETWORK_AVAIL) && test_bit(WMI_READY, &ar->flag)) {
+ ath6kl_wmi_node_free(ar->wmi, bssid);
+
+ /*
+ * In case any other same SSID nodes are present remove it,
+ * since those nodes also not available now.
+ */
+ do {
+ /*
+ * Find the nodes based on SSID and remove it
+ *
+ * Note: This case will not work out for
+ * Hidden-SSID
+ */
+ wmi_ssid_node = ath6kl_wmi_find_ssid_node(ar->wmi,
+ ar->ssid,
+ ar->ssid_len,
+ false,
+ true);
+
+ if (wmi_ssid_node)
+ ath6kl_wmi_node_free(ar->wmi,
+ wmi_ssid_node->ni_macaddr);
+
+ } while (wmi_ssid_node);
+ }
+
/* update connect & link status atomically */
spin_lock_irqsave(&ar->lock, flags);
clear_bit(CONNECTED, &ar->flag);
@@ -1471,7 +1331,7 @@ void init_netdev(struct net_device *dev)
dev->needed_headroom = ETH_HLEN;
dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) +
sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH
- + WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES;
+ + WMI_MAX_TX_META_SZ;
return;
}
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/node.c b/trunk/drivers/net/wireless/ath/ath6kl/node.c
new file mode 100644
index 000000000000..131205c610b9
--- /dev/null
+++ b/trunk/drivers/net/wireless/ath/ath6kl/node.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2004-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.
+ */
+
+#include "htc.h"
+#include "wmi.h"
+#include "debug.h"
+
+struct bss *wlan_node_alloc(int wh_size)
+{
+ struct bss *ni;
+
+ ni = kzalloc(sizeof(struct bss), GFP_ATOMIC);
+
+ if ((ni != NULL) && wh_size) {
+ ni->ni_buf = kmalloc(wh_size, GFP_ATOMIC);
+ if (ni->ni_buf == NULL) {
+ kfree(ni);
+ return NULL;
+ }
+ }
+
+ return ni;
+}
+
+void wlan_node_free(struct bss *ni)
+{
+ kfree(ni->ni_buf);
+ kfree(ni);
+}
+
+void wlan_setup_node(struct ath6kl_node_table *nt, struct bss *ni,
+ const u8 *mac_addr)
+{
+ int hash;
+
+ memcpy(ni->ni_macaddr, mac_addr, ETH_ALEN);
+ hash = ATH6KL_NODE_HASH(mac_addr);
+ ni->ni_refcnt = 1;
+
+ ni->ni_tstamp = jiffies_to_msecs(jiffies);
+ ni->ni_actcnt = WLAN_NODE_INACT_CNT;
+
+ spin_lock_bh(&nt->nt_nodelock);
+
+ /* insert at the end of the node list */
+ ni->ni_list_next = NULL;
+ ni->ni_list_prev = nt->nt_node_last;
+ if (nt->nt_node_last != NULL)
+ nt->nt_node_last->ni_list_next = ni;
+
+ nt->nt_node_last = ni;
+ if (nt->nt_node_first == NULL)
+ nt->nt_node_first = ni;
+
+ /* insert into the hash list */
+ ni->ni_hash_next = nt->nt_hash[hash];
+ if (ni->ni_hash_next != NULL)
+ nt->nt_hash[hash]->ni_hash_prev = ni;
+
+ ni->ni_hash_prev = NULL;
+ nt->nt_hash[hash] = ni;
+
+ spin_unlock_bh(&nt->nt_nodelock);
+}
+
+struct bss *wlan_find_node(struct ath6kl_node_table *nt,
+ const u8 *mac_addr)
+{
+ struct bss *ni, *found_ni = NULL;
+ int hash;
+
+ spin_lock_bh(&nt->nt_nodelock);
+
+ hash = ATH6KL_NODE_HASH(mac_addr);
+ for (ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) {
+ if (memcmp(ni->ni_macaddr, mac_addr, ETH_ALEN) == 0) {
+ ni->ni_refcnt++;
+ found_ni = ni;
+ break;
+ }
+ }
+
+ spin_unlock_bh(&nt->nt_nodelock);
+
+ return found_ni;
+}
+
+void wlan_node_reclaim(struct ath6kl_node_table *nt, struct bss *ni)
+{
+ int hash;
+
+ spin_lock_bh(&nt->nt_nodelock);
+
+ if (ni->ni_list_prev == NULL)
+ /* fix list head */
+ nt->nt_node_first = ni->ni_list_next;
+ else
+ ni->ni_list_prev->ni_list_next = ni->ni_list_next;
+
+ if (ni->ni_list_next == NULL)
+ /* fix list tail */
+ nt->nt_node_last = ni->ni_list_prev;
+ else
+ ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
+
+ if (ni->ni_hash_prev == NULL) {
+ /* first in list so fix the list head */
+ hash = ATH6KL_NODE_HASH(ni->ni_macaddr);
+ nt->nt_hash[hash] = ni->ni_hash_next;
+ } else {
+ ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
+ }
+
+ if (ni->ni_hash_next != NULL)
+ ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
+
+ wlan_node_free(ni);
+
+ spin_unlock_bh(&nt->nt_nodelock);
+}
+
+static void wlan_node_dec_free(struct bss *ni)
+{
+ if ((ni->ni_refcnt--) == 1)
+ wlan_node_free(ni);
+}
+
+void wlan_free_allnodes(struct ath6kl_node_table *nt)
+{
+ struct bss *ni;
+
+ while ((ni = nt->nt_node_first) != NULL)
+ wlan_node_reclaim(nt, ni);
+}
+
+void wlan_iterate_nodes(struct ath6kl_node_table *nt, void *arg)
+{
+ struct bss *ni;
+
+ spin_lock_bh(&nt->nt_nodelock);
+ for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
+ ni->ni_refcnt++;
+ ath6kl_cfg80211_scan_node(arg, ni);
+ wlan_node_dec_free(ni);
+ }
+ spin_unlock_bh(&nt->nt_nodelock);
+}
+
+void wlan_node_table_init(struct ath6kl_node_table *nt)
+{
+ ath6kl_dbg(ATH6KL_DBG_WLAN_NODE, "node table = 0x%lx\n",
+ (unsigned long)nt);
+
+ memset(nt, 0, sizeof(struct ath6kl_node_table));
+
+ spin_lock_init(&nt->nt_nodelock);
+
+ nt->nt_node_age = WLAN_NODE_INACT_TIMEOUT_MSEC;
+}
+
+void wlan_refresh_inactive_nodes(struct ath6kl *ar)
+{
+ struct ath6kl_node_table *nt = &ar->scan_table;
+ struct bss *bss;
+ u32 now;
+
+ now = jiffies_to_msecs(jiffies);
+ bss = nt->nt_node_first;
+ while (bss != NULL) {
+ /* refresh all nodes except the current bss */
+ if (memcmp(ar->bssid, bss->ni_macaddr, ETH_ALEN) != 0) {
+ if (((now - bss->ni_tstamp) > nt->nt_node_age)
+ || --bss->ni_actcnt == 0) {
+ wlan_node_reclaim(nt, bss);
+ }
+ }
+ bss = bss->ni_list_next;
+ }
+}
+
+void wlan_node_table_cleanup(struct ath6kl_node_table *nt)
+{
+ wlan_free_allnodes(nt);
+}
+
+struct bss *wlan_find_ssid_node(struct ath6kl_node_table *nt, u8 * ssid,
+ u32 ssid_len, bool is_wpa2, bool match_ssid)
+{
+ struct bss *ni, *found_ni = NULL;
+ u8 *ie_ssid;
+
+ spin_lock_bh(&nt->nt_nodelock);
+
+ for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
+
+ ie_ssid = ni->ni_cie.ie_ssid;
+
+ if ((ie_ssid[1] <= IEEE80211_MAX_SSID_LEN) &&
+ (memcmp(ssid, &ie_ssid[2], ssid_len) == 0)) {
+
+ if (match_ssid ||
+ (is_wpa2 && ni->ni_cie.ie_rsn != NULL) ||
+ (!is_wpa2 && ni->ni_cie.ie_wpa != NULL)) {
+ ni->ni_refcnt++;
+ found_ni = ni;
+ break;
+ }
+ }
+ }
+
+ spin_unlock_bh(&nt->nt_nodelock);
+
+ return found_ni;
+}
+
+void wlan_node_return(struct ath6kl_node_table *nt, struct bss *ni)
+{
+ spin_lock_bh(&nt->nt_nodelock);
+ wlan_node_dec_free(ni);
+ spin_unlock_bh(&nt->nt_nodelock);
+}
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/sdio.c b/trunk/drivers/net/wireless/ath/ath6kl/sdio.c
index f1dc311ee0c7..34171604cbe4 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/trunk/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -25,7 +25,6 @@
#include "hif-ops.h"
#include "target.h"
#include "debug.h"
-#include "cfg80211.h"
struct ath6kl_sdio {
struct sdio_func *func;
@@ -135,12 +134,10 @@ static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr,
int ret = 0;
if (request & HIF_WRITE) {
- /* FIXME: looks like ugly workaround for something */
if (addr >= HIF_MBOX_BASE_ADDR &&
addr <= HIF_MBOX_END_ADDR)
addr += (HIF_MBOX_WIDTH - len);
- /* FIXME: this also looks like ugly workaround */
if (addr == HIF_MBOX0_EXT_BASE_ADDR)
addr += HIF_MBOX0_EXT_WIDTH - len;
@@ -155,11 +152,6 @@ static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr,
ret = sdio_memcpy_fromio(func, buf, addr, len);
}
- 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);
- ath6kl_dbg_dump(ATH6KL_DBG_SDIO_DUMP, NULL, "sdio ", buf, len);
-
return ret;
}
@@ -180,8 +172,7 @@ static struct bus_request *ath6kl_sdio_alloc_busreq(struct ath6kl_sdio *ar_sdio)
list_del(&bus_req->list);
spin_unlock_irqrestore(&ar_sdio->lock, flag);
- ath6kl_dbg(ATH6KL_DBG_SCATTER, "%s: bus request 0x%p\n",
- __func__, bus_req);
+ ath6kl_dbg(ATH6KL_DBG_TRC, "%s: bus request 0x%p\n", __func__, bus_req);
return bus_req;
}
@@ -191,8 +182,7 @@ static void ath6kl_sdio_free_bus_req(struct ath6kl_sdio *ar_sdio,
{
unsigned long flag;
- ath6kl_dbg(ATH6KL_DBG_SCATTER, "%s: bus request 0x%p\n",
- __func__, bus_req);
+ ath6kl_dbg(ATH6KL_DBG_TRC, "%s: bus request 0x%p\n", __func__, bus_req);
spin_lock_irqsave(&ar_sdio->lock, flag);
list_add_tail(&bus_req->list, &ar_sdio->bus_req_freeq);
@@ -223,6 +213,16 @@ static void ath6kl_sdio_setup_scat_data(struct hif_scatter_req *scat_req,
/* assemble SG list */
for (i = 0; i < scat_req->scat_entries; i++, sg++) {
+ if ((unsigned long)scat_req->scat_list[i].buf & 0x3)
+ /*
+ * Some scatter engines can handle unaligned
+ * buffers, print this as informational only.
+ */
+ ath6kl_dbg(ATH6KL_DBG_SCATTER,
+ "(%s) scatter buffer is unaligned 0x%p\n",
+ scat_req->req & HIF_WRITE ? "WR" : "RD",
+ scat_req->scat_list[i].buf);
+
ath6kl_dbg(ATH6KL_DBG_SCATTER, "%d: addr:0x%p, len:%d\n",
i, scat_req->scat_list[i].buf,
scat_req->scat_list[i].len);
@@ -447,8 +447,6 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)
int status;
struct ath6kl_sdio *ar_sdio;
- ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n");
-
ar_sdio = sdio_get_drvdata(func);
atomic_set(&ar_sdio->irq_handling, 1);
@@ -686,7 +684,7 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
MAX_SCATTER_REQUESTS, virt_scat);
if (!ret) {
- ath6kl_dbg(ATH6KL_DBG_SCATTER,
+ ath6kl_dbg(ATH6KL_DBG_ANY,
"hif-scatter enabled: max scatter req : %d entries: %d\n",
MAX_SCATTER_REQUESTS,
MAX_SCATTER_ENTRIES_PER_REQ);
@@ -711,7 +709,7 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
return ret;
}
- ath6kl_dbg(ATH6KL_DBG_SCATTER,
+ ath6kl_dbg(ATH6KL_DBG_ANY,
"Vitual scatter enabled, max_scat_req:%d, entries:%d\n",
ATH6KL_SCATTER_REQS, ATH6KL_SCATTER_ENTRIES_PER_REQ);
@@ -723,34 +721,6 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
return 0;
}
-static int ath6kl_sdio_suspend(struct ath6kl *ar)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- struct sdio_func *func = ar_sdio->func;
- mmc_pm_flag_t flags;
- int ret;
-
- flags = sdio_get_host_pm_caps(func);
-
- 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) {
- printk(KERN_ERR "ath6kl: set sdio pm flags failed: %d\n",
- ret);
- return ret;
- }
-
- ath6kl_deep_sleep_enable(ar);
-
- return 0;
-}
-
static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
.read_write_sync = ath6kl_sdio_read_write_sync,
.write_async = ath6kl_sdio_write_async,
@@ -761,7 +731,6 @@ static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
.enable_scatter = ath6kl_sdio_enable_scatter,
.scat_req_rw = ath6kl_sdio_async_rw_scatter,
.cleanup_scatter = ath6kl_sdio_cleanup_scatter,
- .suspend = ath6kl_sdio_suspend,
};
static int ath6kl_sdio_probe(struct sdio_func *func,
@@ -772,10 +741,10 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
struct ath6kl *ar;
int count;
- 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);
+ ath6kl_dbg(ATH6KL_DBG_TRC,
+ "%s: func: 0x%X, vendor id: 0x%X, dev id: 0x%X, block size: 0x%X/0x%X\n",
+ __func__, func->num, func->vendor,
+ func->device, func->max_blksize, func->cur_blksize);
ar_sdio = kzalloc(sizeof(struct ath6kl_sdio), GFP_KERNEL);
if (!ar_sdio)
@@ -831,10 +800,10 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
ath6kl_err("Failed to enable 4-bit async irq mode %d\n",
ret);
sdio_release_host(func);
- goto err_cfg80211;
+ goto err_dma;
}
- ath6kl_dbg(ATH6KL_DBG_SDIO, "4-bit async irq mode enabled\n");
+ ath6kl_dbg(ATH6KL_DBG_TRC, "4-bit async irq mode enabled\n");
}
/* give us some time to enable, in ms */
@@ -844,7 +813,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
ret = ath6kl_sdio_power_on(ar_sdio);
if (ret)
- goto err_cfg80211;
+ goto err_dma;
sdio_claim_host(func);
@@ -868,8 +837,6 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
err_off:
ath6kl_sdio_power_off(ar_sdio);
-err_cfg80211:
- ath6kl_cfg80211_deinit(ar_sdio->ar);
err_dma:
kfree(ar_sdio->dma_buffer);
err_hif:
@@ -882,10 +849,6 @@ static void ath6kl_sdio_remove(struct sdio_func *func)
{
struct ath6kl_sdio *ar_sdio;
- 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);
ath6kl_stop_txrx(ar_sdio->ar);
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/target.h b/trunk/drivers/net/wireless/ath/ath6kl/target.h
index c9a76051f042..519a013c9991 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/target.h
+++ b/trunk/drivers/net/wireless/ath/ath6kl/target.h
@@ -20,9 +20,6 @@
#define AR6003_BOARD_DATA_SZ 1024
#define AR6003_BOARD_EXT_DATA_SZ 768
-#define AR6004_BOARD_DATA_SZ 7168
-#define AR6004_BOARD_EXT_DATA_SZ 0
-
#define RESET_CONTROL_ADDRESS 0x00000000
#define RESET_CONTROL_COLD_RST 0x00000100
#define RESET_CONTROL_MBOX_RST 0x00000004
@@ -138,8 +135,7 @@
* between the two, and is intended to remain constant (with additions only
* at the end).
*/
-#define ATH6KL_AR6003_HI_START_ADDR 0x00540600
-#define ATH6KL_AR6004_HI_START_ADDR 0x00400800
+#define ATH6KL_HI_START_ADDR 0x00540600
/*
* These are items that the Host may need to access
@@ -304,11 +300,6 @@ struct host_interest {
#define HI_OPTION_FW_MODE_BSS_STA 0x1
#define HI_OPTION_FW_MODE_AP 0x2
-#define HI_OPTION_FW_SUBMODE_NONE 0x0
-#define HI_OPTION_FW_SUBMODE_P2PDEV 0x1
-#define HI_OPTION_FW_SUBMODE_P2PCLIENT 0x2
-#define HI_OPTION_FW_SUBMODE_P2PGO 0x3
-
#define HI_OPTION_NUM_DEV_SHIFT 0x9
#define HI_OPTION_FW_BRIDGE_SHIFT 0x04
@@ -321,44 +312,20 @@ struct host_interest {
|------------------------------------------------------------------------------|
*/
#define HI_OPTION_FW_MODE_SHIFT 0xC
-#define HI_OPTION_FW_SUBMODE_SHIFT 0x14
/* Convert a Target virtual address into a Target physical address */
-#define AR6003_VTOP(vaddr) ((vaddr) & 0x001fffff)
-#define AR6004_VTOP(vaddr) (vaddr)
-
-#define TARG_VTOP(target_type, vaddr) \
- (((target_type) == TARGET_TYPE_AR6003) ? AR6003_VTOP(vaddr) : \
- (((target_type) == TARGET_TYPE_AR6004) ? AR6004_VTOP(vaddr) : 0))
+#define TARG_VTOP(vaddr) (vaddr & 0x001fffff)
+#define AR6003_REV2_APP_START_OVERRIDE 0x944C00
#define AR6003_REV2_APP_LOAD_ADDRESS 0x543180
#define AR6003_REV2_BOARD_EXT_DATA_ADDRESS 0x57E500
#define AR6003_REV2_DATASET_PATCH_ADDRESS 0x57e884
#define AR6003_REV2_RAM_RESERVE_SIZE 6912
+#define AR6003_REV3_APP_START_OVERRIDE 0x945d00
#define AR6003_REV3_APP_LOAD_ADDRESS 0x545000
#define AR6003_REV3_BOARD_EXT_DATA_ADDRESS 0x542330
#define AR6003_REV3_DATASET_PATCH_ADDRESS 0x57FF74
#define AR6003_REV3_RAM_RESERVE_SIZE 512
-#define AR6004_REV1_BOARD_DATA_ADDRESS 0x435400
-#define AR6004_REV1_BOARD_EXT_DATA_ADDRESS 0x437000
-#define AR6004_REV1_RAM_RESERVE_SIZE 11264
-
-#define ATH6KL_FWLOG_PAYLOAD_SIZE 1500
-
-struct ath6kl_dbglog_buf {
- __le32 next;
- __le32 buffer_addr;
- __le32 bufsize;
- __le32 length;
- __le32 count;
- __le32 free;
-} __packed;
-
-struct ath6kl_dbglog_hdr {
- __le32 dbuf_addr;
- __le32 dropped;
-} __packed;
-
#endif
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/testmode.c b/trunk/drivers/net/wireless/ath/ath6kl/testmode.c
deleted file mode 100644
index 381eb66a605f..000000000000
--- a/trunk/drivers/net/wireless/ath/ath6kl/testmode.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2010-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.
- */
-
-#include "testmode.h"
-
-#include
-
-enum ath6kl_tm_attr {
- __ATH6KL_TM_ATTR_INVALID = 0,
- ATH6KL_TM_ATTR_CMD = 1,
- ATH6KL_TM_ATTR_DATA = 2,
-
- /* keep last */
- __ATH6KL_TM_ATTR_AFTER_LAST,
- ATH6KL_TM_ATTR_MAX = __ATH6KL_TM_ATTR_AFTER_LAST - 1,
-};
-
-enum ath6kl_tm_cmd {
- ATH6KL_TM_CMD_TCMD = 0,
- ATH6KL_TM_CMD_RX_REPORT = 1,
-};
-
-#define ATH6KL_TM_DATA_MAX_LEN 5000
-
-static const struct nla_policy ath6kl_tm_policy[ATH6KL_TM_ATTR_MAX + 1] = {
- [ATH6KL_TM_ATTR_CMD] = { .type = NLA_U32 },
- [ATH6KL_TM_ATTR_DATA] = { .type = NLA_BINARY,
- .len = ATH6KL_TM_DATA_MAX_LEN },
-};
-
-void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len)
-{
- if (down_interruptible(&ar->sem))
- return;
-
- kfree(ar->tm.rx_report);
-
- ar->tm.rx_report = kmemdup(buf, buf_len, GFP_KERNEL);
- ar->tm.rx_report_len = buf_len;
-
- up(&ar->sem);
-
- wake_up(&ar->event_wq);
-}
-
-static int ath6kl_tm_rx_report(struct ath6kl *ar, void *buf, size_t buf_len,
- struct sk_buff *skb)
-{
- int ret = 0;
- long left;
-
- if (down_interruptible(&ar->sem))
- return -ERESTARTSYS;
-
- if (!test_bit(WMI_READY, &ar->flag)) {
- ret = -EIO;
- goto out;
- }
-
- if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
- ret = -EBUSY;
- goto out;
- }
-
- if (ath6kl_wmi_test_cmd(ar->wmi, buf, buf_len) < 0) {
- up(&ar->sem);
- return -EIO;
- }
-
- left = wait_event_interruptible_timeout(ar->event_wq,
- ar->tm.rx_report != NULL,
- WMI_TIMEOUT);
-
- if (left == 0) {
- ret = -ETIMEDOUT;
- goto out;
- } else if (left < 0) {
- ret = left;
- goto out;
- }
-
- if (ar->tm.rx_report == NULL || ar->tm.rx_report_len == 0) {
- ret = -EINVAL;
- goto out;
- }
-
- NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, ar->tm.rx_report_len,
- ar->tm.rx_report);
-
- kfree(ar->tm.rx_report);
- ar->tm.rx_report = NULL;
-
-out:
- up(&ar->sem);
-
- return ret;
-
-nla_put_failure:
- ret = -ENOBUFS;
- goto out;
-}
-
-int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
-{
- struct ath6kl *ar = wiphy_priv(wiphy);
- struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1];
- int err, buf_len, reply_len;
- struct sk_buff *skb;
- void *buf;
-
- err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len,
- ath6kl_tm_policy);
- if (err)
- return err;
-
- if (!tb[ATH6KL_TM_ATTR_CMD])
- return -EINVAL;
-
- switch (nla_get_u32(tb[ATH6KL_TM_ATTR_CMD])) {
- case ATH6KL_TM_CMD_TCMD:
- if (!tb[ATH6KL_TM_ATTR_DATA])
- return -EINVAL;
-
- buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]);
- buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]);
-
- ath6kl_wmi_test_cmd(ar->wmi, buf, buf_len);
-
- return 0;
-
- break;
- case ATH6KL_TM_CMD_RX_REPORT:
- if (!tb[ATH6KL_TM_ATTR_DATA])
- return -EINVAL;
-
- buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]);
- buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]);
-
- reply_len = nla_total_size(ATH6KL_TM_DATA_MAX_LEN);
- skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len);
- if (!skb)
- return -ENOMEM;
-
- err = ath6kl_tm_rx_report(ar, buf, buf_len, skb);
- if (err < 0) {
- kfree_skb(skb);
- return err;
- }
-
- return cfg80211_testmode_reply(skb);
- default:
- return -EOPNOTSUPP;
- }
-}
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/testmode.h b/trunk/drivers/net/wireless/ath/ath6kl/testmode.h
deleted file mode 100644
index 43dffcc11fb1..000000000000
--- a/trunk/drivers/net/wireless/ath/ath6kl/testmode.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2010-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.
- */
-
-#include "core.h"
-
-#ifdef CONFIG_NL80211_TESTMODE
-
-void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len);
-int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len);
-
-#else
-
-static inline void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf,
- size_t buf_len)
-{
-}
-
-static inline int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
-{
- return 0;
-}
-
-#endif
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/txrx.c b/trunk/drivers/net/wireless/ath/ath6kl/txrx.c
index a7117074f81c..167bdb9cf68d 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/trunk/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -239,6 +239,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
u16 htc_tag = ATH6KL_DATA_PKT_TAG;
u8 ac = 99 ; /* initialize to unmapped ac */
bool chk_adhoc_ps_mapping = false, more_data = false;
+ struct wmi_tx_meta_v2 meta_v2;
int ret;
ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
@@ -261,6 +262,8 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
}
if (test_bit(WMI_ENABLED, &ar->flag)) {
+ memset(&meta_v2, 0, sizeof(meta_v2));
+
if (skb_headroom(skb) < dev->needed_headroom) {
WARN_ON(1);
goto fail_tx;
@@ -317,31 +320,12 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
spin_unlock_bh(&ar->lock);
- if (!IS_ALIGNED((unsigned long) skb->data - HTC_HDR_LENGTH, 4) &&
- skb_cloned(skb)) {
- /*
- * We will touch (move the buffer data to align it. Since the
- * skb buffer is cloned and not only the header is changed, we
- * have to copy it to allow the changes. Since we are copying
- * the data here, we may as well align it by reserving suitable
- * headroom to avoid the memmove in ath6kl_htc_tx_buf_align().
- */
- struct sk_buff *nskb;
-
- nskb = skb_copy_expand(skb, HTC_HDR_LENGTH, 0, GFP_ATOMIC);
- if (nskb == NULL)
- goto fail_tx;
- kfree_skb(skb);
- skb = nskb;
- }
-
cookie->skb = skb;
cookie->map_no = map_no;
set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len,
eid, htc_tag);
- ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "tx ",
- skb->data, skb->len);
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, skb->data, skb->len);
/*
* HTC interface is asynchronous, if this fails, cleanup will
@@ -705,8 +689,6 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint)
break;
packet = (struct htc_packet *) skb->head;
- if (!IS_ALIGNED((unsigned long) skb->data, 4))
- skb->data = PTR_ALIGN(skb->data - 4, 4);
set_htc_rxpkt_info(packet, skb, skb->data,
ATH6KL_BUFFER_SIZE, endpoint);
list_add_tail(&packet->list, &queue);
@@ -727,8 +709,6 @@ void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count)
return;
packet = (struct htc_packet *) skb->head;
- if (!IS_ALIGNED((unsigned long) skb->data, 4))
- skb->data = PTR_ALIGN(skb->data - 4, 4);
set_htc_rxpkt_info(packet, skb, skb->data,
ATH6KL_AMSDU_BUFFER_SIZE, 0);
spin_lock_bh(&ar->lock);
@@ -832,7 +812,7 @@ static void aggr_slice_amsdu(struct aggr_info *p_aggr,
/* Add the length of A-MSDU subframe padding bytes -
* Round to nearest word.
*/
- frame_8023_len = ALIGN(frame_8023_len, 4);
+ frame_8023_len = ALIGN(frame_8023_len + 3, 3);
framep += frame_8023_len;
amsdu_len -= frame_8023_len;
@@ -1064,13 +1044,12 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
ar->net_stats.rx_packets++;
ar->net_stats.rx_bytes += packet->act_len;
- 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);
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, skb->data, skb->len);
+
+ spin_unlock_bh(&ar->lock);
skb->dev = ar->net_dev;
@@ -1086,8 +1065,9 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
return;
}
- min_hdr_len = sizeof(struct ethhdr) + sizeof(struct wmi_data_hdr) +
- sizeof(struct ath6kl_llc_snap_hdr);
+ min_hdr_len = sizeof(struct ethhdr);
+ min_hdr_len += sizeof(struct wmi_data_hdr) +
+ sizeof(struct ath6kl_llc_snap_hdr);
dhdr = (struct wmi_data_hdr *) skb->data;
@@ -1183,7 +1163,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
seq_no = wmi_data_hdr_get_seqno(dhdr);
meta_type = wmi_data_hdr_get_meta(dhdr);
dot11_hdr = wmi_data_hdr_get_dot11(dhdr);
- skb_pull(skb, sizeof(struct wmi_data_hdr));
+
+ ath6kl_wmi_data_hdr_remove(ar->wmi, skb);
switch (meta_type) {
case WMI_META_VERSION_1:
@@ -1250,15 +1231,9 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
ath6kl_data_tx(skb1, ar->net_dev);
}
- datap = (struct ethhdr *) skb->data;
-
- if (is_unicast_ether_addr(datap->h_dest) &&
- 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(ar->net_dev, skb);
+ if (!aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no,
+ is_amsdu, skb))
+ ath6kl_deliver_frames_to_nw_stack(ar->net_dev, skb);
}
static void aggr_timeout(unsigned long arg)
@@ -1275,6 +1250,10 @@ static void aggr_timeout(unsigned long arg)
if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress)
continue;
+ /*
+ * FIXME: these timeouts happen quite fruently, something
+ * line once within 60 seconds. Investigate why.
+ */
stats->num_timeouts++;
ath6kl_dbg(ATH6KL_DBG_AGGR,
"aggr timeout (st %d end %d)\n",
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/wmi.c b/trunk/drivers/net/wireless/ath/ath6kl/wmi.c
index a7de23cbd2c7..f5aa33dd4c42 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/trunk/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -17,9 +17,6 @@
#include
#include "core.h"
#include "debug.h"
-#include "testmode.h"
-#include "../regd.h"
-#include "../regd_common.h"
static int ath6kl_wmi_sync_point(struct wmi *wmi);
@@ -170,11 +167,9 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
if (WARN_ON(skb == NULL))
return -EINVAL;
- if (tx_meta_info) {
- ret = ath6kl_wmi_meta_add(wmi, skb, &meta_ver, tx_meta_info);
- if (ret)
- return ret;
- }
+ ret = ath6kl_wmi_meta_add(wmi, skb, &meta_ver, tx_meta_info);
+ if (ret)
+ return ret;
skb_push(skb, sizeof(struct wmi_data_hdr));
@@ -381,6 +376,35 @@ int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb)
return 0;
}
+int ath6kl_wmi_data_hdr_remove(struct wmi *wmi, struct sk_buff *skb)
+{
+ if (WARN_ON(skb == NULL))
+ return -EINVAL;
+
+ skb_pull(skb, sizeof(struct wmi_data_hdr));
+
+ return 0;
+}
+
+static void ath6kl_wmi_convert_bssinfo_hdr2_to_hdr(struct sk_buff *skb,
+ u8 *datap)
+{
+ struct wmi_bss_info_hdr2 bih2;
+ struct wmi_bss_info_hdr *bih;
+
+ memcpy(&bih2, datap, sizeof(struct wmi_bss_info_hdr2));
+
+ skb_push(skb, 4);
+ bih = (struct wmi_bss_info_hdr *) skb->data;
+
+ bih->ch = bih2.ch;
+ bih->frame_type = bih2.frame_type;
+ bih->snr = bih2.snr;
+ bih->rssi = a_cpu_to_sle16(bih2.snr - 95);
+ bih->ie_mask = cpu_to_le32(le16_to_cpu(bih2.ie_mask));
+ memcpy(bih->bssid, bih2.bssid, ETH_ALEN);
+}
+
static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len)
{
struct tx_complete_msg_v1 *msg_v1;
@@ -409,201 +433,6 @@ static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len)
return 0;
}
-static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap,
- int len)
-{
- struct wmi_remain_on_chnl_event *ev;
- u32 freq;
- u32 dur;
- struct ieee80211_channel *chan;
- struct ath6kl *ar = wmi->parent_dev;
-
- if (len < sizeof(*ev))
- return -EINVAL;
-
- ev = (struct wmi_remain_on_chnl_event *) datap;
- freq = le32_to_cpu(ev->freq);
- dur = le32_to_cpu(ev->duration);
- ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl: freq=%u dur=%u\n",
- freq, dur);
- chan = ieee80211_get_channel(ar->wdev->wiphy, freq);
- if (!chan) {
- ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl: Unknown channel "
- "(freq=%u)\n", freq);
- return -EINVAL;
- }
- 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 wmi_cancel_remain_on_chnl_event *ev;
- u32 freq;
- u32 dur;
- struct ieee80211_channel *chan;
- struct ath6kl *ar = wmi->parent_dev;
-
- if (len < sizeof(*ev))
- return -EINVAL;
-
- ev = (struct wmi_cancel_remain_on_chnl_event *) datap;
- freq = le32_to_cpu(ev->freq);
- dur = le32_to_cpu(ev->duration);
- ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: freq=%u dur=%u "
- "status=%u\n", freq, dur, ev->status);
- chan = ieee80211_get_channel(ar->wdev->wiphy, freq);
- if (!chan) {
- ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: Unknown "
- "channel (freq=%u)\n", freq);
- return -EINVAL;
- }
- 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 wmi_tx_status_event *ev;
- u32 id;
- struct ath6kl *ar = wmi->parent_dev;
-
- if (len < sizeof(*ev))
- return -EINVAL;
-
- ev = (struct wmi_tx_status_event *) datap;
- id = le32_to_cpu(ev->id);
- ath6kl_dbg(ATH6KL_DBG_WMI, "tx_status: id=%x ack_status=%u\n",
- id, ev->ack_status);
- if (wmi->last_mgmt_tx_frame) {
- cfg80211_mgmt_tx_status(ar->net_dev, id,
- wmi->last_mgmt_tx_frame,
- wmi->last_mgmt_tx_frame_len,
- !!ev->ack_status, GFP_ATOMIC);
- kfree(wmi->last_mgmt_tx_frame);
- wmi->last_mgmt_tx_frame = NULL;
- wmi->last_mgmt_tx_frame_len = 0;
- }
-
- return 0;
-}
-
-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;
-
- ev = (struct wmi_p2p_rx_probe_req_event *) datap;
- freq = le32_to_cpu(ev->freq);
- dlen = le16_to_cpu(ev->len);
- if (datap + len < ev->data + dlen) {
- ath6kl_err("invalid wmi_p2p_rx_probe_req_event: "
- "len=%d dlen=%u\n", len, dlen);
- return -EINVAL;
- }
- ath6kl_dbg(ATH6KL_DBG_WMI, "rx_probe_req: len=%u freq=%u "
- "probe_req_report=%d\n",
- dlen, freq, ar->probe_req_report);
-
- if (ar->probe_req_report || ar->nw_type == AP_NETWORK)
- cfg80211_rx_mgmt(ar->net_dev, freq, ev->data, dlen, GFP_ATOMIC);
-
- return 0;
-}
-
-static int ath6kl_wmi_p2p_capabilities_event_rx(u8 *datap, int len)
-{
- struct wmi_p2p_capabilities_event *ev;
- u16 dlen;
-
- if (len < sizeof(*ev))
- return -EINVAL;
-
- ev = (struct wmi_p2p_capabilities_event *) datap;
- dlen = le16_to_cpu(ev->len);
- ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_capab: len=%u\n", dlen);
-
- return 0;
-}
-
-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;
-
- ev = (struct wmi_rx_action_event *) datap;
- freq = le32_to_cpu(ev->freq);
- dlen = le16_to_cpu(ev->len);
- if (datap + len < ev->data + dlen) {
- ath6kl_err("invalid wmi_rx_action_event: "
- "len=%d dlen=%u\n", len, dlen);
- return -EINVAL;
- }
- ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq);
- cfg80211_rx_mgmt(ar->net_dev, freq, ev->data, dlen, GFP_ATOMIC);
-
- return 0;
-}
-
-static int ath6kl_wmi_p2p_info_event_rx(u8 *datap, int len)
-{
- struct wmi_p2p_info_event *ev;
- u32 flags;
- u16 dlen;
-
- if (len < sizeof(*ev))
- return -EINVAL;
-
- ev = (struct wmi_p2p_info_event *) datap;
- flags = le32_to_cpu(ev->info_req_flags);
- dlen = le16_to_cpu(ev->len);
- ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_info: flags=%x len=%d\n", flags, dlen);
-
- if (flags & P2P_FLAG_CAPABILITIES_REQ) {
- struct wmi_p2p_capabilities *cap;
- if (dlen < sizeof(*cap))
- return -EINVAL;
- cap = (struct wmi_p2p_capabilities *) ev->data;
- ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_info: GO Power Save = %d\n",
- cap->go_power_save);
- }
-
- if (flags & P2P_FLAG_MACADDR_REQ) {
- struct wmi_p2p_macaddr *mac;
- if (dlen < sizeof(*mac))
- return -EINVAL;
- mac = (struct wmi_p2p_macaddr *) ev->data;
- ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_info: MAC Address = %pM\n",
- mac->mac_addr);
- }
-
- if (flags & P2P_FLAG_HMODEL_REQ) {
- struct wmi_p2p_hmodel *mod;
- if (dlen < sizeof(*mod))
- return -EINVAL;
- mod = (struct wmi_p2p_hmodel *) ev->data;
- ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_info: P2P Model = %d (%s)\n",
- mod->p2p_model,
- mod->p2p_model ? "host" : "firmware");
- }
- return 0;
-}
-
static inline struct sk_buff *ath6kl_wmi_get_new_buf(u32 size)
{
struct sk_buff *skb;
@@ -649,84 +478,18 @@ static int ath6kl_wmi_ready_event_rx(struct wmi *wmi, u8 *datap, int len)
return 0;
}
-/*
- * Mechanism to modify the roaming behavior in the firmware. The lower rssi
- * at which the station has to roam can be passed with
- * WMI_SET_LRSSI_SCAN_PARAMS. Subtract 96 from RSSI to get the signal level
- * in dBm.
- */
-int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi)
-{
- 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;
-
- cmd->info.params.lrssi_scan_period = cpu_to_le16(DEF_LRSSI_SCAN_PERIOD);
- cmd->info.params.lrssi_scan_threshold = a_cpu_to_sle16(lrssi +
- DEF_SCAN_FOR_ROAM_INTVL);
- cmd->info.params.lrssi_roam_threshold = a_cpu_to_sle16(lrssi);
- cmd->info.params.roam_rssi_floor = DEF_LRSSI_ROAM_FLOOR;
- cmd->roam_ctrl = WMI_SET_LRSSI_SCAN_PARAMS;
-
- ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_ROAM_CTRL_CMDID, NO_SYNC_WMIFLAG);
-
- return 0;
-}
-
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 (ar->nw_type == AP_NETWORK) {
- /* AP mode start/STA connected event */
- struct net_device *dev = ar->net_dev;
- if (memcmp(dev->dev_addr, ev->u.ap_bss.bssid, ETH_ALEN) == 0) {
- ath6kl_dbg(ATH6KL_DBG_WMI, "%s: freq %d bssid %pM "
- "(AP started)\n",
- __func__, le16_to_cpu(ev->u.ap_bss.ch),
- ev->u.ap_bss.bssid);
- ath6kl_connect_ap_mode_bss(
- ar, le16_to_cpu(ev->u.ap_bss.ch));
- } else {
- ath6kl_dbg(ATH6KL_DBG_WMI, "%s: aid %u mac_addr %pM "
- "auth=%u keymgmt=%u cipher=%u apsd_info=%u "
- "(STA connected)\n",
- __func__, ev->u.ap_sta.aid,
- ev->u.ap_sta.mac_addr,
- ev->u.ap_sta.auth,
- ev->u.ap_sta.keymgmt,
- le16_to_cpu(ev->u.ap_sta.cipher),
- ev->u.ap_sta.apsd_info);
- ath6kl_connect_ap_mode_sta(
- ar, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr,
- ev->u.ap_sta.keymgmt,
- le16_to_cpu(ev->u.ap_sta.cipher),
- ev->u.ap_sta.auth, ev->assoc_req_len,
- ev->assoc_info + ev->beacon_ie_len);
- }
- return 0;
- }
-
- /* STA/IBSS mode connection event */
-
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "wmi event connect freq %d bssid %pM listen_intvl %d beacon_intvl %d type %d\n",
- 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),
- le32_to_cpu(ev->u.sta.nw_type));
+ ath6kl_dbg(ATH6KL_DBG_WMI, "%s: freq %d bssid %pM\n",
+ __func__, ev->ch, ev->bssid);
/* Start of assoc rsp IEs */
pie = ev->assoc_info + ev->beacon_ie_len +
@@ -755,92 +518,16 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len)
pie += pie[1] + 2;
}
- ath6kl_connect_event(wmi->parent_dev, le16_to_cpu(ev->u.sta.ch),
- ev->u.sta.bssid,
- le16_to_cpu(ev->u.sta.listen_intvl),
- le16_to_cpu(ev->u.sta.beacon_intvl),
- le32_to_cpu(ev->u.sta.nw_type),
+ ath6kl_connect_event(wmi->parent_dev, le16_to_cpu(ev->ch), ev->bssid,
+ le16_to_cpu(ev->listen_intvl),
+ le16_to_cpu(ev->beacon_intvl),
+ le32_to_cpu(ev->nw_type),
ev->beacon_ie_len, ev->assoc_req_len,
ev->assoc_resp_len, ev->assoc_info);
return 0;
}
-static struct country_code_to_enum_rd *
-ath6kl_regd_find_country(u16 countryCode)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
- if (allCountries[i].countryCode == countryCode)
- return &allCountries[i];
- }
-
- return NULL;
-}
-
-static struct reg_dmn_pair_mapping *
-ath6kl_get_regpair(u16 regdmn)
-{
- int i;
-
- if (regdmn == NO_ENUMRD)
- return NULL;
-
- for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
- if (regDomainPairs[i].regDmnEnum == regdmn)
- return ®DomainPairs[i];
- }
-
- return NULL;
-}
-
-static struct country_code_to_enum_rd *
-ath6kl_regd_find_country_by_rd(u16 regdmn)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
- if (allCountries[i].regDmnEnum == regdmn)
- return &allCountries[i];
- }
-
- return NULL;
-}
-
-static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
-{
-
- struct ath6kl_wmi_regdomain *ev;
- struct country_code_to_enum_rd *country = NULL;
- struct reg_dmn_pair_mapping *regpair = NULL;
- char alpha2[2];
- u32 reg_code;
-
- ev = (struct ath6kl_wmi_regdomain *) datap;
- reg_code = le32_to_cpu(ev->reg_code);
-
- if ((reg_code >> ATH6KL_COUNTRY_RD_SHIFT) & COUNTRY_ERD_FLAG)
- country = ath6kl_regd_find_country((u16) reg_code);
- else if (!(((u16) reg_code & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)) {
-
- regpair = ath6kl_get_regpair((u16) reg_code);
- country = ath6kl_regd_find_country_by_rd((u16) reg_code);
- ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n",
- regpair->regDmnEnum);
- }
-
- if (country) {
- alpha2[0] = country->isoName[0];
- alpha2[1] = country->isoName[1];
-
- 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 wmi_disconnect_event *ev;
@@ -851,11 +538,6 @@ static int ath6kl_wmi_disconnect_event_rx(struct wmi *wmi, u8 *datap, int len)
ev = (struct wmi_disconnect_event *) datap;
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "wmi event disconnect proto_reason %d bssid %pM wmi_reason %d assoc_resp_len %d\n",
- le16_to_cpu(ev->proto_reason_status), ev->bssid,
- ev->disconn_reason, ev->assoc_resp_len);
-
wmi->is_wmm_enabled = false;
wmi->pair_crypto_type = NONE_CRYPT;
wmi->grp_crypto_type = NONE_CRYPT;
@@ -900,92 +582,315 @@ static int ath6kl_wmi_tkip_micerr_event_rx(struct wmi *wmi, u8 *datap, int len)
return 0;
}
-static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wlan_parse_beacon(u8 *buf, int frame_len,
+ struct ath6kl_common_ie *cie)
{
- struct wmi_bss_info_hdr2 *bih;
- u8 *buf;
- struct ieee80211_channel *channel;
- struct ath6kl *ar = wmi->parent_dev;
- struct ieee80211_mgmt *mgmt;
- struct cfg80211_bss *bss;
+ u8 *frm, *efrm;
+ u8 elemid_ssid = false;
+
+ frm = buf;
+ efrm = (u8 *) (frm + frame_len);
- if (len <= sizeof(struct wmi_bss_info_hdr2))
+ /*
+ * beacon/probe response frame format
+ * [8] time stamp
+ * [2] beacon interval
+ * [2] capability information
+ * [tlv] ssid
+ * [tlv] supported rates
+ * [tlv] country information
+ * [tlv] parameter set (FH/DS)
+ * [tlv] erp information
+ * [tlv] extended supported rates
+ * [tlv] WMM
+ * [tlv] WPA or RSN
+ * [tlv] Atheros Advanced Capabilities
+ */
+ if ((efrm - frm) < 12)
return -EINVAL;
- bih = (struct wmi_bss_info_hdr2 *) datap;
- buf = datap + sizeof(struct wmi_bss_info_hdr2);
- len -= sizeof(struct wmi_bss_info_hdr2);
+ memset(cie, 0, sizeof(*cie));
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "bss info evt - ch %u, snr %d, rssi %d, bssid \"%pM\" "
- "frame_type=%d\n",
- bih->ch, bih->snr, bih->snr - 95, bih->bssid,
- bih->frame_type);
-
- if (bih->frame_type != BEACON_FTYPE &&
- bih->frame_type != PROBERESP_FTYPE)
- return 0; /* Only update BSS table for now */
-
- if (bih->frame_type == BEACON_FTYPE &&
- test_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag)) {
- clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
- ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
+ cie->ie_tstamp = frm;
+ frm += 8;
+ cie->ie_beaconInt = *(u16 *) frm;
+ frm += 2;
+ cie->ie_capInfo = *(u16 *) frm;
+ frm += 2;
+ cie->ie_chan = 0;
+
+ while (frm < efrm) {
+ switch (*frm) {
+ case WLAN_EID_SSID:
+ if (!elemid_ssid) {
+ cie->ie_ssid = frm;
+ elemid_ssid = true;
+ }
+ break;
+ case WLAN_EID_SUPP_RATES:
+ cie->ie_rates = frm;
+ break;
+ case WLAN_EID_COUNTRY:
+ cie->ie_country = frm;
+ break;
+ case WLAN_EID_FH_PARAMS:
+ break;
+ case WLAN_EID_DS_PARAMS:
+ cie->ie_chan = frm[2];
+ break;
+ case WLAN_EID_TIM:
+ cie->ie_tim = frm;
+ break;
+ case WLAN_EID_IBSS_PARAMS:
+ break;
+ case WLAN_EID_EXT_SUPP_RATES:
+ cie->ie_xrates = frm;
+ break;
+ case WLAN_EID_ERP_INFO:
+ if (frm[1] != 1)
+ return -EINVAL;
+
+ cie->ie_erp = frm[2];
+ break;
+ case WLAN_EID_RSN:
+ cie->ie_rsn = frm;
+ break;
+ case WLAN_EID_HT_CAPABILITY:
+ cie->ie_htcap = frm;
+ break;
+ case WLAN_EID_HT_INFORMATION:
+ cie->ie_htop = frm;
+ break;
+ case WLAN_EID_VENDOR_SPECIFIC:
+ if (frm[1] > 3 && frm[2] == 0x00 && frm[3] == 0x50 &&
+ frm[4] == 0xf2) {
+ /* OUT Type (00:50:F2) */
+
+ if (frm[5] == WPA_OUI_TYPE) {
+ /* WPA OUT */
+ cie->ie_wpa = frm;
+ } else if (frm[5] == WMM_OUI_TYPE) {
+ /* WMM OUT */
+ cie->ie_wmm = frm;
+ } else if (frm[5] == WSC_OUT_TYPE) {
+ /* WSC OUT */
+ cie->ie_wsc = frm;
+ }
+
+ } else if (frm[1] > 3 && frm[2] == 0x00
+ && frm[3] == 0x03 && frm[4] == 0x7f
+ && frm[5] == ATH_OUI_TYPE) {
+ /* Atheros OUI (00:03:7f) */
+ cie->ie_ath = frm;
+ }
+ break;
+ default:
+ break;
+ }
+ frm += frm[1] + 2;
}
- channel = ieee80211_get_channel(ar->wdev->wiphy, le16_to_cpu(bih->ch));
- if (channel == NULL)
+ if ((cie->ie_rates == NULL)
+ || (cie->ie_rates[1] > ATH6KL_RATE_MAXSIZE))
return -EINVAL;
- if (len < 8 + 2 + 2)
+ if ((cie->ie_ssid == NULL)
+ || (cie->ie_ssid[1] > IEEE80211_MAX_SSID_LEN))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct bss *bss = NULL;
+ struct wmi_bss_info_hdr *bih;
+ u8 cached_ssid_len = 0;
+ u8 cached_ssid[IEEE80211_MAX_SSID_LEN] = { 0 };
+ u8 beacon_ssid_len = 0;
+ u8 *buf, *ie_ssid;
+ u8 *ni_buf;
+ int buf_len;
+
+ int ret;
+
+ if (len <= sizeof(struct wmi_bss_info_hdr))
return -EINVAL;
- 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) {
- ar->assoc_bss_dtim_period = tim[3];
- set_bit(DTIM_PERIOD_AVAIL, &ar->flag);
+ bih = (struct wmi_bss_info_hdr *) datap;
+ bss = wlan_find_node(&wmi->parent_dev->scan_table, bih->bssid);
+
+ if (a_sle16_to_cpu(bih->rssi) > 0) {
+ if (bss == NULL)
+ return 0;
+ else
+ bih->rssi = a_cpu_to_sle16(bss->ni_rssi);
+ }
+
+ buf = datap + sizeof(struct wmi_bss_info_hdr);
+ len -= sizeof(struct wmi_bss_info_hdr);
+
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "bss info evt - ch %u, rssi %02x, bssid \"%pM\"\n",
+ bih->ch, a_sle16_to_cpu(bih->rssi), bih->bssid);
+
+ if (bss != NULL) {
+ /*
+ * Free up the node. We are about to allocate a new node.
+ * In case of hidden AP, beacon will not have ssid,
+ * but a directed probe response will have it,
+ * so cache the probe-resp-ssid if already present.
+ */
+ if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE)) {
+ ie_ssid = bss->ni_cie.ie_ssid;
+ if (ie_ssid && (ie_ssid[1] <= IEEE80211_MAX_SSID_LEN) &&
+ (ie_ssid[2] != 0)) {
+ cached_ssid_len = ie_ssid[1];
+ memcpy(cached_ssid, ie_ssid + 2,
+ cached_ssid_len);
+ }
}
+
+ /*
+ * Use the current average rssi of associated AP base on
+ * assumption
+ * 1. Most os with GUI will update RSSI by
+ * ath6kl_wmi_get_stats_cmd() periodically.
+ * 2. ath6kl_wmi_get_stats_cmd(..) will be called when calling
+ * ath6kl_wmi_startscan_cmd(...)
+ * The average value of RSSI give end-user better feeling for
+ * instance value of scan result. It also sync up RSSI info
+ * in GUI between scan result and RSSI signal icon.
+ */
+ if (memcmp(wmi->parent_dev->bssid, bih->bssid, ETH_ALEN) == 0) {
+ bih->rssi = a_cpu_to_sle16(bss->ni_rssi);
+ bih->snr = bss->ni_snr;
+ }
+
+ wlan_node_reclaim(&wmi->parent_dev->scan_table, bss);
}
/*
- * In theory, use of cfg80211_inform_bss() would be more natural here
- * since we do not have the full frame. However, at least for now,
- * cfg80211 can only distinguish Beacon and Probe Response frames from
- * each other when using cfg80211_inform_bss_frame(), so let's build a
- * fake IEEE 802.11 header to be able to take benefit of this.
+ * beacon/probe response frame format
+ * [8] time stamp
+ * [2] beacon interval
+ * [2] capability information
+ * [tlv] ssid
+ */
+ beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
+
+ /*
+ * If ssid is cached for this hidden AP, then change
+ * buffer len accordingly.
*/
- mgmt = kmalloc(24 + len, GFP_ATOMIC);
- if (mgmt == NULL)
+ if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE) &&
+ (cached_ssid_len != 0) &&
+ (beacon_ssid_len == 0 || (cached_ssid_len > beacon_ssid_len &&
+ buf[SSID_IE_LEN_INDEX + 1] == 0))) {
+
+ len += (cached_ssid_len - beacon_ssid_len);
+ }
+
+ bss = wlan_node_alloc(len);
+ if (!bss)
+ return -ENOMEM;
+
+ bss->ni_snr = bih->snr;
+ bss->ni_rssi = a_sle16_to_cpu(bih->rssi);
+
+ if (WARN_ON(!bss->ni_buf))
return -EINVAL;
- if (bih->frame_type == BEACON_FTYPE) {
- mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_BEACON);
- memset(mgmt->da, 0xff, ETH_ALEN);
- } else {
- struct net_device *dev = ar->net_dev;
+ /*
+ * In case of hidden AP, beacon will not have ssid,
+ * but a directed probe response will have it,
+ * so place the cached-ssid(probe-resp) in the bss info.
+ */
+ if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE) &&
+ (cached_ssid_len != 0) &&
+ (beacon_ssid_len == 0 || (beacon_ssid_len &&
+ buf[SSID_IE_LEN_INDEX + 1] == 0))) {
+ ni_buf = bss->ni_buf;
+ buf_len = len;
+
+ /*
+ * Copy the first 14 bytes:
+ * time-stamp(8), beacon-interval(2),
+ * cap-info(2), ssid-id(1), ssid-len(1).
+ */
+ memcpy(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
+
+ ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
+ ni_buf += (SSID_IE_LEN_INDEX + 1);
+
+ buf += (SSID_IE_LEN_INDEX + 1);
+ buf_len -= (SSID_IE_LEN_INDEX + 1);
+
+ memcpy(ni_buf, cached_ssid, cached_ssid_len);
+ ni_buf += cached_ssid_len;
+
+ buf += beacon_ssid_len;
+ buf_len -= beacon_ssid_len;
+
+ if (cached_ssid_len > beacon_ssid_len)
+ buf_len -= (cached_ssid_len - beacon_ssid_len);
+
+ memcpy(ni_buf, buf, buf_len);
+ } else
+ memcpy(bss->ni_buf, buf, len);
+
+ bss->ni_framelen = len;
+
+ ret = ath6kl_wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie);
+ if (ret) {
+ wlan_node_free(bss);
+ return -EINVAL;
+ }
+
+ /*
+ * Update the frequency in ie_chan, overwriting of channel number
+ * which is done in ath6kl_wlan_parse_beacon
+ */
+ bss->ni_cie.ie_chan = le16_to_cpu(bih->ch);
+ wlan_setup_node(&wmi->parent_dev->scan_table, bss, bih->bssid);
+
+ return 0;
+}
- mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_PROBE_RESP);
- memcpy(mgmt->da, dev->dev_addr, ETH_ALEN);
+static int ath6kl_wmi_opt_frame_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct bss *bss;
+ struct wmi_opt_rx_info_hdr *bih;
+ u8 *buf;
+
+ if (len <= sizeof(struct wmi_opt_rx_info_hdr))
+ return -EINVAL;
+
+ bih = (struct wmi_opt_rx_info_hdr *) datap;
+ buf = datap + sizeof(struct wmi_opt_rx_info_hdr);
+ len -= sizeof(struct wmi_opt_rx_info_hdr);
+
+ ath6kl_dbg(ATH6KL_DBG_WMI, "opt frame event %2.2x:%2.2x\n",
+ bih->bssid[4], bih->bssid[5]);
+
+ bss = wlan_find_node(&wmi->parent_dev->scan_table, bih->bssid);
+ if (bss != NULL) {
+ /* Free up the node. We are about to allocate a new node. */
+ wlan_node_reclaim(&wmi->parent_dev->scan_table, bss);
}
- mgmt->duration = cpu_to_le16(0);
- memcpy(mgmt->sa, bih->bssid, ETH_ALEN);
- memcpy(mgmt->bssid, bih->bssid, ETH_ALEN);
- mgmt->seq_ctrl = cpu_to_le16(0);
-
- memcpy(&mgmt->u.beacon, buf, len);
-
- bss = cfg80211_inform_bss_frame(ar->wdev->wiphy, channel, mgmt,
- 24 + len, (bih->snr - 95) * 100,
- GFP_ATOMIC);
- kfree(mgmt);
- if (bss == NULL)
+
+ bss = wlan_node_alloc(len);
+ if (!bss)
return -ENOMEM;
- cfg80211_put_bss(bss);
+
+ bss->ni_snr = bih->snr;
+ bss->ni_cie.ie_chan = le16_to_cpu(bih->ch);
+
+ if (WARN_ON(!bss->ni_buf))
+ return -EINVAL;
+
+ memcpy(bss->ni_buf, buf, len);
+ wlan_setup_node(&wmi->parent_dev->scan_table, bss, bih->bssid);
return 0;
}
@@ -1044,13 +949,6 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len)
return 0;
}
-static int ath6kl_wmi_tcmd_test_report_rx(struct wmi *wmi, u8 *datap, int len)
-{
- ath6kl_tm_rx_report_event(wmi->parent_dev, datap, len);
-
- return 0;
-}
-
static int ath6kl_wmi_ratemask_reply_rx(struct wmi *wmi, u8 *datap, int len)
{
if (len < sizeof(struct wmi_fix_rates_reply))
@@ -1100,41 +998,15 @@ static int ath6kl_wmi_scan_complete_rx(struct wmi *wmi, u8 *datap, int len)
ev = (struct wmi_scan_complete_event *) datap;
+ if (a_sle32_to_cpu(ev->status) == 0)
+ wlan_refresh_inactive_nodes(wmi->parent_dev);
+
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 wmi_neighbor_report_event *ev;
- u8 i;
-
- if (len < sizeof(*ev))
- return -EINVAL;
- ev = (struct wmi_neighbor_report_event *) datap;
- if (sizeof(*ev) + ev->num_neighbors * sizeof(struct wmi_neighbor_info)
- > len) {
- ath6kl_dbg(ATH6KL_DBG_WMI, "truncated neighbor event "
- "(num=%d len=%d)\n", ev->num_neighbors, len);
- return -EINVAL;
- }
- for (i = 0; i < ev->num_neighbors; i++) {
- ath6kl_dbg(ATH6KL_DBG_WMI, "neighbor %d/%d - %pM 0x%x\n",
- i + 1, ev->num_neighbors, ev->neighbor[i].bssid,
- ev->neighbor[i].bss_flags);
- cfg80211_pmksa_candidate_notify(wmi->parent_dev->net_dev, i,
- ev->neighbor[i].bssid,
- !!(ev->neighbor[i].bss_flags &
- WMI_PREAUTH_CAPABLE_BSS),
- GFP_ATOMIC);
- }
-
- return 0;
-}
-
/*
* Target is reporting a programming error. This is for
* developer aid only. Target only checks a few common violations
@@ -1538,11 +1410,6 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,
if (WARN_ON(skb == NULL))
return -EINVAL;
- ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n",
- cmd_id, skb->len, sync_flag);
- ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi tx ",
- skb->data, skb->len);
-
if (sync_flag >= END_WMIFLAG) {
dev_kfree_skb(skb);
return -EINVAL;
@@ -1601,13 +1468,6 @@ int ath6kl_wmi_connect_cmd(struct wmi *wmi, enum network_type nw_type,
struct wmi_connect_cmd *cc;
int ret;
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "wmi connect bssid %pM freq %d flags 0x%x ssid_len %d "
- "type %d dot11_auth %d auth %d pairwise %d group %d\n",
- bssid, channel, ctrl_flags, ssid_len, nw_type,
- dot11_auth_mode, auth_mode, pairwise_crypto, group_crypto);
- ath6kl_dbg_dump(ATH6KL_DBG_WMI, NULL, "ssid ", ssid, ssid_len);
-
wmi->traffic_class = 100;
if ((pairwise_crypto == NONE_CRYPT) && (group_crypto != NONE_CRYPT))
@@ -1653,9 +1513,6 @@ int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 *bssid, u16 channel)
struct wmi_reconnect_cmd *cc;
int ret;
- ath6kl_dbg(ATH6KL_DBG_WMI, "wmi reconnect bssid %pM freq %d\n",
- bssid, channel);
-
wmi->traffic_class = 100;
skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_reconnect_cmd));
@@ -1678,8 +1535,6 @@ int ath6kl_wmi_disconnect_cmd(struct wmi *wmi)
{
int ret;
- ath6kl_dbg(ATH6KL_DBG_WMI, "wmi disconnect\n");
-
wmi->traffic_class = 100;
/* Disconnect command does not need to do a SYNC before. */
@@ -1696,7 +1551,7 @@ int ath6kl_wmi_startscan_cmd(struct wmi *wmi, enum wmi_scan_type scan_type,
struct sk_buff *skb;
struct wmi_start_scan_cmd *sc;
s8 size;
- int i, ret;
+ int ret;
size = sizeof(struct wmi_start_scan_cmd);
@@ -1721,8 +1576,8 @@ int ath6kl_wmi_startscan_cmd(struct wmi *wmi, enum wmi_scan_type scan_type,
sc->force_scan_intvl = cpu_to_le32(force_scan_interval);
sc->num_ch = num_chan;
- for (i = 0; i < num_chan; i++)
- sc->ch_list[i] = cpu_to_le16(ch_list[i]);
+ if (num_chan)
+ memcpy(sc->ch_list, ch_list, num_chan * sizeof(u16));
ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_START_SCAN_CMDID,
NO_SYNC_WMIFLAG);
@@ -1915,10 +1770,6 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,
struct wmi_add_cipher_key_cmd *cmd;
int ret;
- ath6kl_dbg(ATH6KL_DBG_WMI, "addkey cmd: key_index=%u key_type=%d "
- "key_usage=%d key_len=%d key_op_ctrl=%d\n",
- 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))
return -EINVAL;
@@ -2360,25 +2211,6 @@ int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source)
return ret;
}
-int ath6kl_wmi_config_debug_module_cmd(struct wmi *wmi, u32 valid, u32 config)
-{
- struct ath6kl_wmix_dbglog_cfg_module_cmd *cmd;
- struct sk_buff *skb;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct ath6kl_wmix_dbglog_cfg_module_cmd *) skb->data;
- cmd->valid = cpu_to_le32(valid);
- cmd->config = cpu_to_le32(config);
-
- ret = ath6kl_wmi_cmd_send_xtnd(wmi, skb, WMIX_DBGLOG_CFG_MODULE_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
int ath6kl_wmi_get_stats_cmd(struct wmi *wmi)
{
return ath6kl_wmi_simple_cmd(wmi, WMI_GET_STATISTICS_CMDID);
@@ -2484,29 +2316,49 @@ int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl)
return ret;
}
-int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len)
+s32 ath6kl_wmi_get_rate(s8 rate_index)
{
- struct sk_buff *skb;
- int ret;
+ if (rate_index == RATE_AUTO)
+ return 0;
- skb = ath6kl_wmi_get_new_buf(len);
- if (!skb)
- return -ENOMEM;
+ return wmi_rate_tbl[(u32) rate_index][0];
+}
- memcpy(skb->data, buf, len);
+void ath6kl_wmi_node_return(struct wmi *wmi, struct bss *bss)
+{
+ if (bss)
+ wlan_node_return(&wmi->parent_dev->scan_table, bss);
+}
- ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_TEST_CMDID, NO_SYNC_WMIFLAG);
+struct bss *ath6kl_wmi_find_ssid_node(struct wmi *wmi, u8 * ssid,
+ u32 ssid_len, bool is_wpa2,
+ bool match_ssid)
+{
+ struct bss *node = NULL;
- return ret;
+ node = wlan_find_ssid_node(&wmi->parent_dev->scan_table, ssid,
+ ssid_len, is_wpa2, match_ssid);
+ return node;
}
+struct bss *ath6kl_wmi_find_node(struct wmi *wmi, const u8 * mac_addr)
+{
+ struct bss *ni = NULL;
-s32 ath6kl_wmi_get_rate(s8 rate_index)
+ ni = wlan_find_node(&wmi->parent_dev->scan_table, mac_addr);
+
+ return ni;
+}
+
+void ath6kl_wmi_node_free(struct wmi *wmi, const u8 * mac_addr)
{
- if (rate_index == RATE_AUTO)
- return 0;
+ struct bss *ni = NULL;
- return wmi_rate_tbl[(u32) rate_index][0];
+ ni = wlan_find_node(&wmi->parent_dev->scan_table, mac_addr);
+ if (ni != NULL)
+ wlan_node_reclaim(&wmi->parent_dev->scan_table, ni);
+
+ return;
}
static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
@@ -2548,47 +2400,6 @@ static int ath6kl_wmi_delba_req_event_rx(struct wmi *wmi, u8 *datap, int len)
}
/* AP mode functions */
-
-int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, struct wmi_connect_cmd *p)
-{
- struct sk_buff *skb;
- struct wmi_connect_cmd *cm;
- int res;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cm));
- if (!skb)
- return -ENOMEM;
-
- cm = (struct wmi_connect_cmd *) skb->data;
- memcpy(cm, p, sizeof(*cm));
-
- 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",
- __func__, p->nw_type, p->auth_mode, le16_to_cpu(p->ch),
- le32_to_cpu(p->ctrl_flags), res);
- return res;
-}
-
-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;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cm));
- if (!skb)
- return -ENOMEM;
-
- cm = (struct wmi_ap_set_mlme_cmd *) skb->data;
- memcpy(cm->mac, mac, ETH_ALEN);
- cm->reason = cpu_to_le16(reason);
- cm->cmd = cmd;
-
- 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 wmi_pspoll_event *ev;
@@ -2622,7 +2433,6 @@ int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag)
cmd = (struct wmi_ap_set_pvb_cmd *) skb->data;
cmd->aid = cpu_to_le16(aid);
- cmd->rsvd = cpu_to_le16(0);
cmd->flag = cpu_to_le32(flag);
ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_AP_SET_PVB_CMDID,
@@ -2654,160 +2464,6 @@ int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_ver,
return ret;
}
-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;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*p) + ie_len);
- if (!skb)
- return -ENOMEM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "set_appie_cmd: mgmt_frm_type=%u "
- "ie_len=%u\n", mgmt_frm_type, ie_len);
- p = (struct wmi_set_appie_cmd *) skb->data;
- p->mgmt_frm_type = mgmt_frm_type;
- p->ie_len = ie_len;
- memcpy(p->ie_info, ie, ie_len);
- return ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_APPIE_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable)
-{
- struct sk_buff *skb;
- struct wmi_disable_11b_rates_cmd *cmd;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "disable_11b_rates_cmd: disable=%u\n",
- disable);
- cmd = (struct wmi_disable_11b_rates_cmd *) skb->data;
- cmd->disable = disable ? 1 : 0;
-
- return ath6kl_wmi_cmd_send(wmi, skb, WMI_DISABLE_11B_RATES_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-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;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*p));
- if (!skb)
- return -ENOMEM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl_cmd: freq=%u dur=%u\n",
- freq, dur);
- p = (struct wmi_remain_on_chnl_cmd *) skb->data;
- p->freq = cpu_to_le32(freq);
- p->duration = cpu_to_le32(dur);
- return ath6kl_wmi_cmd_send(wmi, skb, WMI_REMAIN_ON_CHNL_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-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;
- u8 *buf;
-
- if (wait)
- return -EINVAL; /* Offload for wait not supported */
-
- buf = kmalloc(data_len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*p) + data_len);
- if (!skb) {
- kfree(buf);
- return -ENOMEM;
- }
-
- kfree(wmi->last_mgmt_tx_frame);
- wmi->last_mgmt_tx_frame = buf;
- wmi->last_mgmt_tx_frame_len = data_len;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "send_action_cmd: id=%u freq=%u wait=%u "
- "len=%u\n", id, freq, wait, data_len);
- p = (struct wmi_send_action_cmd *) skb->data;
- p->id = cpu_to_le32(id);
- p->freq = cpu_to_le32(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, skb, WMI_SEND_ACTION_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u32 freq,
- const u8 *dst,
- const u8 *data, u16 data_len)
-{
- struct sk_buff *skb;
- struct wmi_p2p_probe_response_cmd *p;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*p) + data_len);
- if (!skb)
- return -ENOMEM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "send_probe_response_cmd: freq=%u dst=%pM "
- "len=%u\n", freq, dst, data_len);
- p = (struct wmi_p2p_probe_response_cmd *) skb->data;
- p->freq = cpu_to_le32(freq);
- memcpy(p->destination_addr, dst, ETH_ALEN);
- p->len = cpu_to_le16(data_len);
- memcpy(p->data, data, data_len);
- return ath6kl_wmi_cmd_send(wmi, skb, WMI_SEND_PROBE_RESPONSE_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, bool enable)
-{
- struct sk_buff *skb;
- struct wmi_probe_req_report_cmd *p;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*p));
- if (!skb)
- return -ENOMEM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "probe_report_req_cmd: enable=%u\n",
- enable);
- p = (struct wmi_probe_req_report_cmd *) skb->data;
- p->enable = enable ? 1 : 0;
- return ath6kl_wmi_cmd_send(wmi, skb, WMI_PROBE_REQ_REPORT_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u32 info_req_flags)
-{
- struct sk_buff *skb;
- struct wmi_get_p2p_info *p;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*p));
- if (!skb)
- return -ENOMEM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "info_req_cmd: flags=%x\n",
- info_req_flags);
- p = (struct wmi_get_p2p_info *) skb->data;
- p->info_req_flags = cpu_to_le32(info_req_flags);
- return ath6kl_wmi_cmd_send(wmi, skb, WMI_GET_P2P_INFO_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-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, WMI_CANCEL_REMAIN_ON_CHNL_CMDID);
-}
-
static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
{
struct wmix_cmd_hdr *cmd;
@@ -2832,14 +2488,11 @@ static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
switch (id) {
case WMIX_HB_CHALLENGE_RESP_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event hb challenge resp\n");
break;
case WMIX_DBGLOG_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event dbglog len %d\n", len);
- ath6kl_debug_fwlog_event(wmi->parent_dev, datap, len);
break;
default:
- ath6kl_warn("unknown cmd id 0x%x\n", id);
+ ath6kl_err("unknown cmd id 0x%x\n", id);
wmi->stat.cmd_id_err++;
ret = -EINVAL;
break;
@@ -2875,9 +2528,8 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
datap = skb->data;
len = skb->len;
- ath6kl_dbg(ATH6KL_DBG_WMI, "wmi rx id %d len %d\n", id, len);
- ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi rx ",
- datap, len);
+ ath6kl_dbg(ATH6KL_DBG_WMI, "%s: wmi id: %d\n", __func__, id);
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "msg payload ", datap, len);
switch (id) {
case WMI_GET_BITRATE_CMDID:
@@ -2914,11 +2566,11 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
break;
case WMI_BSSINFO_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n");
- ret = ath6kl_wmi_bssinfo_event_rx(wmi, datap, len);
+ ath6kl_wmi_convert_bssinfo_hdr2_to_hdr(skb, datap);
+ ret = ath6kl_wmi_bssinfo_event_rx(wmi, skb->data, skb->len);
break;
case WMI_REGDOMAIN_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n");
- ath6kl_wmi_regdomain_event(wmi, datap, len);
break;
case WMI_PSTREAM_TIMEOUT_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSTREAM_TIMEOUT_EVENTID\n");
@@ -2926,7 +2578,6 @@ 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);
break;
case WMI_SCAN_COMPLETE_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n");
@@ -2949,7 +2600,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
break;
case WMI_OPT_RX_FRAME_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_OPT_RX_FRAME_EVENTID\n");
- /* this event has been deprecated */
+ ret = ath6kl_wmi_opt_frame_event_rx(wmi, datap, len);
break;
case WMI_REPORT_ROAM_TBL_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_TBL_EVENTID\n");
@@ -2968,10 +2619,6 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
case WMI_REPORT_ROAM_DATA_EVENTID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_DATA_EVENTID\n");
break;
- case WMI_TEST_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TEST_EVENTID\n");
- ret = ath6kl_wmi_tcmd_test_report_rx(wmi, datap, len);
- break;
case WMI_GET_FIXRATES_CMDID:
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n");
ret = ath6kl_wmi_ratemask_reply_rx(wmi, datap, len);
@@ -3036,36 +2683,6 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n");
ret = ath6kl_wmi_tx_complete_event_rx(datap, len);
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);
- 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);
- 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);
- 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);
- break;
- case WMI_P2P_CAPABILITIES_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_CAPABILITIES_EVENTID\n");
- ret = ath6kl_wmi_p2p_capabilities_event_rx(datap, len);
- 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);
- break;
- case WMI_P2P_INFO_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_INFO_EVENTID\n");
- ret = ath6kl_wmi_p2p_info_event_rx(datap, len);
- break;
default:
ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", id);
wmi->stat.cmd_id_err++;
@@ -3122,6 +2739,5 @@ void ath6kl_wmi_shutdown(struct wmi *wmi)
if (!wmi)
return;
- kfree(wmi->last_mgmt_tx_frame);
kfree(wmi);
}
diff --git a/trunk/drivers/net/wireless/ath/ath6kl/wmi.h b/trunk/drivers/net/wireless/ath/ath6kl/wmi.h
index f8e644d54aa7..fe3ddce64087 100644
--- a/trunk/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/trunk/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -129,9 +129,6 @@ struct wmi {
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;
};
struct host_app_area {
@@ -493,61 +490,17 @@ enum wmi_cmd_id {
WMI_SET_PASSPHRASE_CMDID,
WMI_SEND_ASSOC_RES_CMDID,
WMI_SET_ASSOC_REQ_RELAY_CMDID,
+ WMI_GET_RFKILL_MODE_CMDID,
/* ACS command, consists of sub-commands */
WMI_ACS_CTRL_CMDID,
- WMI_SET_EXCESS_TX_RETRY_THRES_CMDID,
- WMI_SET_TBD_TIME_CMDID, /*added for wmiconfig command for TBD */
-
- /* Pktlog cmds */
- WMI_PKTLOG_ENABLE_CMDID,
- WMI_PKTLOG_DISABLE_CMDID,
-
- /* More P2P Cmds */
- WMI_P2P_GO_NEG_REQ_RSP_CMDID,
- WMI_P2P_GRP_INIT_CMDID,
- WMI_P2P_GRP_FORMATION_DONE_CMDID,
- WMI_P2P_INVITE_CMDID,
- WMI_P2P_INVITE_REQ_RSP_CMDID,
- WMI_P2P_PROV_DISC_REQ_CMDID,
- WMI_P2P_SET_CMDID,
-
- WMI_GET_RFKILL_MODE_CMDID,
- WMI_SET_RFKILL_MODE_CMDID,
- WMI_AP_SET_APSD_CMDID,
- WMI_AP_APSD_BUFFERED_TRAFFIC_CMDID,
- WMI_P2P_SDPD_TX_CMDID, /* F05C */
- WMI_P2P_STOP_SDPD_CMDID,
- WMI_P2P_CANCEL_CMDID,
/* Ultra low power store / recall commands */
WMI_STORERECALL_CONFIGURE_CMDID,
WMI_STORERECALL_RECALL_CMDID,
WMI_STORERECALL_HOST_READY_CMDID,
WMI_FORCE_TARGET_ASSERT_CMDID,
-
- WMI_SET_PROBED_SSID_EX_CMDID,
- WMI_SET_NETWORK_LIST_OFFLOAD_CMDID,
- WMI_SET_ARP_NS_OFFLOAD_CMDID,
- WMI_ADD_WOW_EXT_PATTERN_CMDID,
- WMI_GTK_OFFLOAD_OP_CMDID,
- WMI_REMAIN_ON_CHNL_CMDID,
- WMI_CANCEL_REMAIN_ON_CHNL_CMDID,
- WMI_SEND_ACTION_CMDID,
- WMI_PROBE_REQ_REPORT_CMDID,
- WMI_DISABLE_11B_RATES_CMDID,
- WMI_SEND_PROBE_RESPONSE_CMDID,
- WMI_GET_P2P_INFO_CMDID,
- WMI_AP_JOIN_BSS_CMDID,
-};
-
-enum wmi_mgmt_frame_type {
- WMI_FRAME_BEACON = 0,
- WMI_FRAME_PROBE_REQ,
- WMI_FRAME_PROBE_RESP,
- WMI_FRAME_ASSOC_REQ,
- WMI_FRAME_ASSOC_RESP,
- WMI_NUM_MGMT_FRAME
+ WMI_SET_EXCESS_TX_RETRY_THRES_CMDID,
};
/* WMI_CONNECT_CMDID */
@@ -566,6 +519,11 @@ enum dot11_auth_mode {
LEAP_AUTH = 0x04,
};
+enum {
+ AUTH_IDLE,
+ AUTH_OPEN_IN_PROGRESS,
+};
+
enum auth_mode {
NONE_AUTH = 0x01,
WPA_AUTH = 0x02,
@@ -1221,26 +1179,15 @@ enum wmi_event_id {
WMI_WAC_START_WPS_EVENTID,
WMI_WAC_CTRL_REQ_REPLY_EVENTID,
- WMI_REPORT_WMM_PARAMS_EVENTID,
- WMI_WAC_REJECT_WPS_EVENTID,
-
- /* More P2P Events */
- WMI_P2P_GO_NEG_REQ_EVENTID,
- WMI_P2P_INVITE_REQ_EVENTID,
- WMI_P2P_INVITE_RCVD_RESULT_EVENTID,
- WMI_P2P_INVITE_SENT_RESULT_EVENTID,
- WMI_P2P_PROV_DISC_RESP_EVENTID,
- WMI_P2P_PROV_DISC_REQ_EVENTID,
-
/* RFKILL Events */
WMI_RFKILL_STATE_CHANGE_EVENTID,
WMI_RFKILL_GET_MODE_CMD_EVENTID,
-
- WMI_P2P_START_SDPD_EVENTID,
- WMI_P2P_SDPD_RX_EVENTID,
-
WMI_THIN_RESERVED_START_EVENTID = 0x8000,
- /* Events in this range are reserved for thinmode */
+
+ /*
+ * Events in this range are reserved for thinmode
+ * See wmi_thin.h for actual definitions
+ */
WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
WMI_SET_CHANNEL_EVENTID,
@@ -1248,17 +1195,7 @@ enum wmi_event_id {
/* Generic ACS event */
WMI_ACS_EVENTID,
- WMI_STORERECALL_STORE_EVENTID,
- WMI_WOW_EXT_WAKE_EVENTID,
- WMI_GTK_OFFLOAD_STATUS_EVENTID,
- WMI_NETWORK_LIST_OFFLOAD_EVENTID,
- WMI_REMAIN_ON_CHNL_EVENTID,
- WMI_CANCEL_REMAIN_ON_CHNL_EVENTID,
- WMI_TX_STATUS_EVENTID,
- WMI_RX_PROBE_REQ_EVENTID,
- WMI_P2P_CAPABILITIES_EVENTID,
- WMI_RX_ACTION_EVENTID,
- WMI_P2P_INFO_EVENTID,
+ WMI_REPORT_WMM_PARAMS_EVENTID
};
struct wmi_ready_event_2 {
@@ -1270,30 +1207,11 @@ struct wmi_ready_event_2 {
/* Connect Event */
struct wmi_connect_event {
- union {
- struct {
- __le16 ch;
- u8 bssid[ETH_ALEN];
- __le16 listen_intvl;
- __le16 beacon_intvl;
- __le32 nw_type;
- } sta;
- struct {
- u8 phymode;
- u8 aid;
- u8 mac_addr[ETH_ALEN];
- u8 auth;
- u8 keymgmt;
- __le16 cipher;
- u8 apsd_info;
- u8 unused[3];
- } ap_sta;
- struct {
- __le16 ch;
- u8 bssid[ETH_ALEN];
- u8 unused[8];
- } ap_bss;
- } u;
+ __le16 ch;
+ u8 bssid[ETH_ALEN];
+ __le16 listen_intvl;
+ __le16 beacon_intvl;
+ __le32 nw_type;
u8 beacon_ie_len;
u8 assoc_req_len;
u8 assoc_resp_len;
@@ -1320,12 +1238,6 @@ enum wmi_disconnect_reason {
IBSS_MERGE = 0xe,
};
-#define ATH6KL_COUNTRY_RD_SHIFT 16
-
-struct ath6kl_wmi_regdomain {
- __le32 reg_code;
-};
-
struct wmi_disconnect_event {
/* reason code, see 802.11 spec. */
__le16 proto_reason_status;
@@ -1353,54 +1265,33 @@ enum wmi_bi_ftype {
PROBEREQ_FTYPE,
};
-#define DEF_LRSSI_SCAN_PERIOD 5
-#define DEF_LRSSI_ROAM_THRESHOLD 20
-#define DEF_LRSSI_ROAM_FLOOR 60
-#define DEF_SCAN_FOR_ROAM_INTVL 2
+struct wmi_bss_info_hdr {
+ __le16 ch;
-enum wmi_roam_ctrl {
- WMI_FORCE_ROAM = 1,
- WMI_SET_ROAM_MODE,
- WMI_SET_HOST_BIAS,
- WMI_SET_LRSSI_SCAN_PARAMS,
-};
+ /* see, enum wmi_bi_ftype */
+ u8 frame_type;
-struct bss_bias {
+ u8 snr;
+ a_sle16 rssi;
u8 bssid[ETH_ALEN];
- u8 bias;
-} __packed;
-
-struct bss_bias_info {
- u8 num_bss;
- struct bss_bias bss_bias[1];
-} __packed;
-
-struct low_rssi_scan_params {
- __le16 lrssi_scan_period;
- a_sle16 lrssi_scan_threshold;
- a_sle16 lrssi_roam_threshold;
- u8 roam_rssi_floor;
- u8 reserved[1];
-} __packed;
-
-struct roam_ctrl_cmd {
- union {
- u8 bssid[ETH_ALEN];
- u8 roam_mode;
- struct bss_bias_info bss;
- struct low_rssi_scan_params params;
- } __packed info;
- u8 roam_ctrl;
+ __le32 ie_mask;
} __packed;
-/* BSS INFO HDR version 2.0 */
+/*
+ * BSS INFO HDR version 2.0
+ * With 6 bytes HTC header and 6 bytes of WMI header
+ * WMI_BSS_INFO_HDR cannot be accommodated in the removed 802.11 management
+ * header space.
+ * - Reduce the ie_mask to 2 bytes as only two bit flags are used
+ * - Remove rssi and compute it on the host. rssi = snr - 95
+ */
struct wmi_bss_info_hdr2 {
- __le16 ch; /* frequency in MHz */
+ __le16 ch;
/* see, enum wmi_bi_ftype */
u8 frame_type;
- u8 snr; /* note: rssi = snr - 95 dBm */
+ u8 snr;
u8 bssid[ETH_ALEN];
__le16 ie_mask;
} __packed;
@@ -1439,16 +1330,6 @@ enum wmi_bss_flags {
WMI_PMKID_VALID_BSS = 0x02,
};
-struct wmi_neighbor_info {
- u8 bssid[ETH_ALEN];
- u8 bss_flags; /* enum wmi_bss_flags */
-} __packed;
-
-struct wmi_neighbor_report_event {
- u8 num_neighbors;
- struct wmi_neighbor_info neighbor[0];
-} __packed;
-
/* TKIP MIC Error Event */
struct wmi_tkip_micerr_event {
u8 key_id;
@@ -1761,12 +1642,6 @@ struct wmi_get_keepalive_cmd {
u8 keep_alive_intvl;
} __packed;
-struct wmi_set_appie_cmd {
- u8 mgmt_frm_type; /* enum wmi_mgmt_frame_type */
- u8 ie_len;
- u8 ie_info[0];
-} __packed;
-
/* Notify the WSC registration status to the target */
#define WSC_REG_ACTIVE 1
#define WSC_REG_INACTIVE 0
@@ -1914,26 +1789,8 @@ struct wmi_tx_complete_event {
/* Used with WMI_AP_SET_NUM_STA_CMDID */
-/*
- * Used with WMI_AP_SET_MLME_CMDID
- */
-
-/* MLME Commands */
-#define WMI_AP_MLME_ASSOC 1 /* associate station */
-#define WMI_AP_DISASSOC 2 /* disassociate station */
-#define WMI_AP_DEAUTH 3 /* deauthenticate station */
-#define WMI_AP_MLME_AUTHORIZE 4 /* authorize station */
-#define WMI_AP_MLME_UNAUTHORIZE 5 /* unauthorize station */
-
-struct wmi_ap_set_mlme_cmd {
- u8 mac[ETH_ALEN];
- __le16 reason; /* 802.11 reason code */
- u8 cmd; /* operation to perform (WMI_AP_*) */
-} __packed;
-
struct wmi_ap_set_pvb_cmd {
__le32 flag;
- __le16 rsvd;
__le16 aid;
} __packed;
@@ -1983,100 +1840,6 @@ struct wmi_ap_mode_stat {
/* End of AP mode definitions */
-struct wmi_remain_on_chnl_cmd {
- __le32 freq;
- __le32 duration;
-} __packed;
-
-struct wmi_send_action_cmd {
- __le32 id;
- __le32 freq;
- __le32 wait;
- __le16 len;
- u8 data[0];
-} __packed;
-
-struct wmi_tx_status_event {
- __le32 id;
- u8 ack_status;
-} __packed;
-
-struct wmi_probe_req_report_cmd {
- u8 enable;
-} __packed;
-
-struct wmi_disable_11b_rates_cmd {
- u8 disable;
-} __packed;
-
-struct wmi_set_appie_extended_cmd {
- u8 role_id;
- u8 mgmt_frm_type;
- u8 ie_len;
- u8 ie_info[0];
-} __packed;
-
-struct wmi_remain_on_chnl_event {
- __le32 freq;
- __le32 duration;
-} __packed;
-
-struct wmi_cancel_remain_on_chnl_event {
- __le32 freq;
- __le32 duration;
- u8 status;
-} __packed;
-
-struct wmi_rx_action_event {
- __le32 freq;
- __le16 len;
- u8 data[0];
-} __packed;
-
-struct wmi_p2p_capabilities_event {
- __le16 len;
- u8 data[0];
-} __packed;
-
-struct wmi_p2p_rx_probe_req_event {
- __le32 freq;
- __le16 len;
- u8 data[0];
-} __packed;
-
-#define P2P_FLAG_CAPABILITIES_REQ (0x00000001)
-#define P2P_FLAG_MACADDR_REQ (0x00000002)
-#define P2P_FLAG_HMODEL_REQ (0x00000002)
-
-struct wmi_get_p2p_info {
- __le32 info_req_flags;
-} __packed;
-
-struct wmi_p2p_info_event {
- __le32 info_req_flags;
- __le16 len;
- u8 data[0];
-} __packed;
-
-struct wmi_p2p_capabilities {
- u8 go_power_save;
-} __packed;
-
-struct wmi_p2p_macaddr {
- u8 mac_addr[ETH_ALEN];
-} __packed;
-
-struct wmi_p2p_hmodel {
- u8 p2p_model;
-} __packed;
-
-struct wmi_p2p_probe_response_cmd {
- __le32 freq;
- u8 destination_addr[ETH_ALEN];
- __le16 len;
- u8 data[0];
-} __packed;
-
/* Extended WMI (WMIX)
*
* Extended WMIX commands are encapsulated in a WMI message with
@@ -2135,11 +1898,6 @@ struct wmix_hb_challenge_resp_cmd {
__le32 source;
} __packed;
-struct ath6kl_wmix_dbglog_cfg_module_cmd {
- __le32 valid;
- __le32 config;
-} __packed;
-
/* End of Extended WMI (WMIX) */
enum wmi_sync_flag {
@@ -2167,11 +1925,14 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb);
+int ath6kl_wmi_data_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb,
u32 layer2_priority, bool wmm_enabled,
u8 *ac);
int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb);
+struct bss *ath6kl_wmi_find_node(struct wmi *wmi, const u8 *mac_addr);
+void ath6kl_wmi_node_free(struct wmi *wmi, const u8 *mac_addr);
int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,
enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag);
@@ -2217,7 +1978,6 @@ 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);
int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,
@@ -2235,47 +1995,23 @@ int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi);
int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg);
int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl);
-int ath6kl_wmi_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_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
-/* AP mode */
-int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, struct wmi_connect_cmd *p);
+struct bss *ath6kl_wmi_find_ssid_node(struct wmi *wmi, u8 *ssid,
+ u32 ssid_len, bool is_wpa2,
+ bool match_ssid);
-int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 cmd, const u8 *mac, u16 reason);
+void ath6kl_wmi_node_return(struct wmi *wmi, struct bss *bss);
+/* AP mode */
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 rx_meta_version,
bool rx_dot11_hdr, bool defrag_on_host);
-int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 mgmt_frm_type, const u8 *ie,
- u8 ie_len);
-
-/* P2P */
-int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable);
-
-int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u32 freq, u32 dur);
-
-int ath6kl_wmi_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, u32 freq,
- const u8 *dst,
- const u8 *data, u16 data_len);
-
-int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, bool enable);
-
-int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u32 info_req_flags);
-
-int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi);
-
-int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 mgmt_frm_type, const u8 *ie,
- u8 ie_len);
-
void *ath6kl_wmi_init(struct ath6kl *devt);
void ath6kl_wmi_shutdown(struct wmi *wmi);
diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index 08e9341f6368..f2c6f2316a3b 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -1514,7 +1514,7 @@ static const u32 ar9300_2p2_mac_core[][2] = {
{0x00008258, 0x00000000},
{0x0000825c, 0x40000000},
{0x00008260, 0x00080922},
- {0x00008264, 0x9d400010},
+ {0x00008264, 0x9bc00010},
{0x00008268, 0xffffffff},
{0x0000826c, 0x0000ffff},
{0x00008270, 0x00000000},
diff --git a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h
index 1e8614783181..94d887b65e69 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -340,8 +340,7 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an);
-void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
- struct ath_node *an);
+bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an);
/********/
/* VIFs */
diff --git a/trunk/drivers/net/wireless/ath/ath9k/debug.c b/trunk/drivers/net/wireless/ath/ath9k/debug.c
index a5329c98f9ea..179da2099270 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/debug.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/debug.c
@@ -876,15 +876,6 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
TX_SAMP_DBG(rssi) = ts->ts_rssi;
TX_SAMP_DBG(tid) = ts->tid;
TX_SAMP_DBG(qid) = ts->qid;
-
- if (ts->ts_flags & ATH9K_TX_BA) {
- TX_SAMP_DBG(ba_low) = ts->ba_low;
- TX_SAMP_DBG(ba_high) = ts->ba_high;
- } else {
- TX_SAMP_DBG(ba_low) = 0;
- TX_SAMP_DBG(ba_high) = 0;
- }
-
sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES;
spin_unlock(&sc->debug.samp_lock);
@@ -1525,15 +1516,14 @@ static int open_file_bb_mac_samps(struct inode *inode, struct file *file)
len += snprintf(buf + len, size - len, "Tx status Dump :\n");
len += snprintf(buf + len, size - len,
"Sample rssi:- ctl0 ctl1 ctl2 ext0 ext1 ext2 comb "
- "isok rts_fail data_fail rate tid qid "
- "ba_low ba_high tx_before(ms)\n");
+ "isok rts_fail data_fail rate tid qid tx_before(ms)\n");
for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
for (i = 0; i < ATH_DBG_MAX_SAMPLES; i++) {
if (!ATH_SAMP_DBG(ts[i].jiffies))
continue;
- len += snprintf(buf + len, size - len, "%-14d"
- "%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d %-8d "
- "%-9d %-4d %-3d %-3d %08x %08x %-11d\n",
+ len += snprintf(buf + len, size - len, "%4d \t"
+ "%8d %4d %4d %4d %4d %4d %4d %4d %4d "
+ "%4d %4d %2d %2d %d\n",
sampidx,
ATH_SAMP_DBG(ts[i].rssi_ctl0),
ATH_SAMP_DBG(ts[i].rssi_ctl1),
@@ -1548,8 +1538,6 @@ static int open_file_bb_mac_samps(struct inode *inode, struct file *file)
ATH_SAMP_DBG(ts[i].rateindex),
ATH_SAMP_DBG(ts[i].tid),
ATH_SAMP_DBG(ts[i].qid),
- ATH_SAMP_DBG(ts[i].ba_low),
- ATH_SAMP_DBG(ts[i].ba_high),
jiffies_to_msecs(jiffies -
ATH_SAMP_DBG(ts[i].jiffies)));
}
@@ -1562,8 +1550,8 @@ static int open_file_bb_mac_samps(struct inode *inode, struct file *file)
for (i = 0; i < ATH_DBG_MAX_SAMPLES; i++) {
if (!ATH_SAMP_DBG(rs[i].jiffies))
continue;
- len += snprintf(buf + len, size - len, "%-14d"
- "%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-9s %-2d %02x %-13d\n",
+ len += snprintf(buf + len, size - len, "%4d \t"
+ "%8d %4d %4d %4d %4d %4d %4d %s %4d %02x %d\n",
sampidx,
ATH_SAMP_DBG(rs[i].rssi_ctl0),
ATH_SAMP_DBG(rs[i].rssi_ctl1),
diff --git a/trunk/drivers/net/wireless/ath/ath9k/debug.h b/trunk/drivers/net/wireless/ath/ath9k/debug.h
index b93e88bd8c58..39f89bc9abcd 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/debug.h
+++ b/trunk/drivers/net/wireless/ath/ath9k/debug.h
@@ -196,8 +196,6 @@ struct ath_dbg_bb_mac_samp {
u8 rateindex;
u8 qid;
u8 tid;
- u32 ba_low;
- u32 ba_high;
} ts[ATH_DBG_MAX_SAMPLES];
struct {
u64 jiffies;
diff --git a/trunk/drivers/net/wireless/ath/ath9k/eeprom.h b/trunk/drivers/net/wireless/ath/ath9k/eeprom.h
index 5d92f96980e6..a3c7d0c247a3 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/trunk/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -104,11 +104,16 @@
#define OLC_FOR_AR9287_10_LATER (AR_SREV_9287_11_OR_LATER(ah) && \
ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
+#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
+#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2
+#define AR_EEPROM_RFSILENT_POLARITY 0x0002
+#define AR_EEPROM_RFSILENT_POLARITY_S 1
+
#define EEP_RFSILENT_ENABLED 0x0001
#define EEP_RFSILENT_ENABLED_S 0
#define EEP_RFSILENT_POLARITY 0x0002
#define EEP_RFSILENT_POLARITY_S 1
-#define EEP_RFSILENT_GPIO_SEL (AR_SREV_9480(ah) ? 0x00fc : 0x001c)
+#define EEP_RFSILENT_GPIO_SEL 0x001c
#define EEP_RFSILENT_GPIO_SEL_S 2
#define AR5416_OPFLAGS_11A 0x01
diff --git a/trunk/drivers/net/wireless/ath/ath9k/gpio.c b/trunk/drivers/net/wireless/ath/ath9k/gpio.c
index fd0f84ebdb51..afbf5400a52a 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/gpio.c
@@ -84,14 +84,9 @@ void ath_init_leds(struct ath_softc *sc)
static bool ath_is_rfkill_set(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
- bool is_blocked;
- ath9k_ps_wakeup(sc);
- is_blocked = ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
+ return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
ah->rfkill_polarity;
- ath9k_ps_restore(sc);
-
- return is_blocked;
}
void ath9k_rfkill_poll_state(struct ieee80211_hw *hw)
diff --git a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c
index 77c8ded8de57..d3f4a59cd456 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -38,7 +38,6 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
{ USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
{ USB_DEVICE(0x040D, 0x3801) }, /* VIA */
{ USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
- { USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */
{ USB_DEVICE(0x0cf3, 0x7015),
.driver_info = AR9287_USB }, /* Atheros */
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 e3a02eb8e0cc..db2352e5cc0d 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -228,14 +228,8 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv)
static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv)
{
- bool is_blocked;
-
- ath9k_htc_ps_wakeup(priv);
- is_blocked = ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) ==
- priv->ah->rfkill_polarity;
- ath9k_htc_ps_restore(priv);
-
- return is_blocked;
+ return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) ==
+ priv->ah->rfkill_polarity;
}
void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw)
diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 0b9a0e8a4958..495fdf680a6c 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1352,8 +1352,7 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
return ret;
}
-static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct ath9k_htc_priv *priv = hw->priv;
@@ -1564,8 +1563,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
mutex_unlock(&priv->mutex);
}
-static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw)
{
struct ath9k_htc_priv *priv = hw->priv;
u64 tsf;
@@ -1579,8 +1577,7 @@ static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw,
return tsf;
}
-static void ath9k_htc_set_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u64 tsf)
+static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf)
{
struct ath9k_htc_priv *priv = hw->priv;
@@ -1591,8 +1588,7 @@ static void ath9k_htc_set_tsf(struct ieee80211_hw *hw,
mutex_unlock(&priv->mutex);
}
-static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw)
{
struct ath9k_htc_priv *priv = hw->priv;
diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c
index 42ebe8fb053a..f2de7ee047ce 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/hw.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c
@@ -284,12 +284,7 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
ah->hw_version.macVersion =
(val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
-
- if (AR_SREV_9480(ah))
- ah->is_pciexpress = true;
- else
- ah->is_pciexpress = (val &
- AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
+ ah->is_pciexpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
} else {
if (!AR_SREV_9100(ah))
ah->hw_version.macVersion = MS(val, AR_SREV_VERSION);
@@ -2158,10 +2153,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->num_gpio_pins = AR9271_NUM_GPIO;
else if (AR_DEVID_7010(ah))
pCap->num_gpio_pins = AR7010_NUM_GPIO;
- else if (AR_SREV_9300_20_OR_LATER(ah))
- pCap->num_gpio_pins = AR9300_NUM_GPIO;
- else if (AR_SREV_9287_11_OR_LATER(ah))
- pCap->num_gpio_pins = AR9287_NUM_GPIO;
else if (AR_SREV_9285_12_OR_LATER(ah))
pCap->num_gpio_pins = AR9285_NUM_GPIO;
else if (AR_SREV_9280_20_OR_LATER(ah))
diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c
index 988318665758..ee39702da5d8 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/main.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/main.c
@@ -133,7 +133,7 @@ void ath9k_ps_restore(struct ath_softc *sc)
ath_hw_cycle_counters_update(common);
spin_unlock(&common->cc_lock);
- ath9k_hw_setpower(sc->sc_ah, mode);
+ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
unlock:
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
@@ -1833,7 +1833,8 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw,
switch (cmd) {
case STA_NOTIFY_SLEEP:
an->sleeping = true;
- ath_tx_aggr_sleep(sta, sc, an);
+ if (ath_tx_aggr_sleep(sc, an))
+ ieee80211_sta_set_tim(sta);
break;
case STA_NOTIFY_AWAKE:
an->sleeping = false;
@@ -1842,8 +1843,7 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw,
}
}
-static int ath9k_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct ath_softc *sc = hw->priv;
@@ -2143,7 +2143,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
ath9k_ps_restore(sc);
}
-static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
{
struct ath_softc *sc = hw->priv;
u64 tsf;
@@ -2157,9 +2157,7 @@ static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
return tsf;
}
-static void ath9k_set_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- u64 tsf)
+static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
{
struct ath_softc *sc = hw->priv;
@@ -2170,7 +2168,7 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw,
mutex_unlock(&sc->mutex);
}
-static void ath9k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+static void ath9k_reset_tsf(struct ieee80211_hw *hw)
{
struct ath_softc *sc = hw->priv;
diff --git a/trunk/drivers/net/wireless/ath/ath9k/rc.c b/trunk/drivers/net/wireless/ath/ath9k/rc.c
index 8448281dd069..4f1301881137 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/rc.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/rc.c
@@ -1362,6 +1362,12 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED)
return;
+ if (!(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) {
+ tx_info->status.ampdu_ack_len =
+ (tx_info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
+ tx_info->status.ampdu_len = 1;
+ }
+
if (!(tx_info->flags & IEEE80211_TX_STAT_ACK))
tx_status = 1;
diff --git a/trunk/drivers/net/wireless/ath/ath9k/recv.c b/trunk/drivers/net/wireless/ath/ath9k/recv.c
index f658ec60b510..bcc0b222ec18 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/recv.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/recv.c
@@ -205,22 +205,14 @@ static void ath_rx_remove_buffer(struct ath_softc *sc,
static void ath_rx_edma_cleanup(struct ath_softc *sc)
{
- struct ath_hw *ah = sc->sc_ah;
- struct ath_common *common = ath9k_hw_common(ah);
struct ath_buf *bf;
ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP);
ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP);
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
- if (bf->bf_mpdu) {
- dma_unmap_single(sc->dev, bf->bf_buf_addr,
- common->rx_bufsize,
- DMA_BIDIRECTIONAL);
+ if (bf->bf_mpdu)
dev_kfree_skb_any(bf->bf_mpdu);
- bf->bf_buf_addr = 0;
- bf->bf_mpdu = NULL;
- }
}
INIT_LIST_HEAD(&sc->rx.rxbuf);
@@ -586,11 +578,22 @@ static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
{
+ struct ieee80211_mgmt *mgmt;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
if (skb->len < 24 + 8 + 2 + 2)
return;
+ mgmt = (struct ieee80211_mgmt *)skb->data;
+ if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0) {
+ /* TODO: This doesn't work well if you have stations
+ * associated to two different APs because curbssid
+ * is just the last AP that any of the stations associated
+ * with.
+ */
+ return; /* not from our current AP */
+ }
+
sc->ps_flags &= ~PS_WAIT_FOR_BEACON;
if (sc->ps_flags & PS_BEACON_SYNC) {
@@ -626,7 +629,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
}
}
-static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon)
+static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -635,7 +638,7 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon)
/* Process Beacon and CAB receive in PS state */
if (((sc->ps_flags & PS_WAIT_FOR_BEACON) || ath9k_check_auto_sleep(sc))
- && mybeacon)
+ && ieee80211_is_beacon(hdr->frame_control))
ath_rx_ps_beacon(sc, skb);
else if ((sc->ps_flags & PS_WAIT_FOR_CAB) &&
(ieee80211_is_data(hdr->frame_control) ||
@@ -1941,10 +1944,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
spin_lock_irqsave(&sc->sc_pm_lock, flags);
if ((sc->ps_flags & (PS_WAIT_FOR_BEACON |
- PS_WAIT_FOR_CAB |
- PS_WAIT_FOR_PSPOLL_DATA)) ||
- ath9k_check_auto_sleep(sc))
- ath_rx_ps(sc, skb, rs.is_mybeacon);
+ PS_WAIT_FOR_CAB |
+ PS_WAIT_FOR_PSPOLL_DATA)) ||
+ ath9k_check_auto_sleep(sc))
+ ath_rx_ps(sc, skb);
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx == 3)
diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c
index c2bfc57958d8..fa3dcfdf7174 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c
@@ -542,7 +542,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
/* prepend un-acked frames to the beginning of the pending frame queue */
if (!skb_queue_empty(&bf_pending)) {
if (an->sleeping)
- ieee80211_sta_set_buffered(sta, tid->tidno, true);
+ ieee80211_sta_set_tim(sta);
spin_lock_bh(&txq->axq_lock);
if (clear_filter)
@@ -1153,13 +1153,12 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
ath_tx_flush_tid(sc, txtid);
}
-void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
- struct ath_node *an)
+bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an)
{
struct ath_atx_tid *tid;
struct ath_atx_ac *ac;
struct ath_txq *txq;
- bool buffered;
+ bool buffered = false;
int tidno;
for (tidno = 0, tid = &an->tid[tidno];
@@ -1173,7 +1172,8 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
spin_lock_bh(&txq->axq_lock);
- buffered = !skb_queue_empty(&tid->buf_q);
+ if (!skb_queue_empty(&tid->buf_q))
+ buffered = true;
tid->sched = false;
list_del(&tid->list);
@@ -1184,9 +1184,9 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
}
spin_unlock_bh(&txq->axq_lock);
-
- ieee80211_sta_set_buffered(sta, tidno, buffered);
}
+
+ return buffered;
}
void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
@@ -2043,9 +2043,10 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
BUG_ON(nbad > nframes);
+
+ tx_info->status.ampdu_len = nframes;
+ tx_info->status.ampdu_ack_len = nframes - nbad;
}
- tx_info->status.ampdu_len = nframes;
- tx_info->status.ampdu_ack_len = nframes - nbad;
if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) == 0) {
diff --git a/trunk/drivers/net/wireless/ath/carl9170/main.c b/trunk/drivers/net/wireless/ath/carl9170/main.c
index beca71073e9b..af351ecd87c4 100644
--- a/trunk/drivers/net/wireless/ath/carl9170/main.c
+++ b/trunk/drivers/net/wireless/ath/carl9170/main.c
@@ -1078,8 +1078,7 @@ static void carl9170_op_bss_info_changed(struct ieee80211_hw *hw,
mutex_unlock(&ar->mutex);
}
-static u64 carl9170_op_get_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static u64 carl9170_op_get_tsf(struct ieee80211_hw *hw)
{
struct ar9170 *ar = hw->priv;
struct carl9170_tsf_rsp tsf;
@@ -1305,8 +1304,7 @@ static int carl9170_op_sta_remove(struct ieee80211_hw *hw,
return 0;
}
-static int carl9170_op_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+static int carl9170_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *param)
{
struct ar9170 *ar = hw->priv;
diff --git a/trunk/drivers/net/wireless/b43/b43.h b/trunk/drivers/net/wireless/b43/b43.h
index 447a2307c9d9..f8615cdf1075 100644
--- a/trunk/drivers/net/wireless/b43/b43.h
+++ b/trunk/drivers/net/wireless/b43/b43.h
@@ -107,40 +107,6 @@
#define B43_MMIO_RADIO_HWENABLED_LO 0x49A
#define B43_MMIO_GPIO_CONTROL 0x49C
#define B43_MMIO_GPIO_MASK 0x49E
-#define B43_MMIO_TXE0_CTL 0x500
-#define B43_MMIO_TXE0_AUX 0x502
-#define B43_MMIO_TXE0_TS_LOC 0x504
-#define B43_MMIO_TXE0_TIME_OUT 0x506
-#define B43_MMIO_TXE0_WM_0 0x508
-#define B43_MMIO_TXE0_WM_1 0x50A
-#define B43_MMIO_TXE0_PHYCTL 0x50C
-#define B43_MMIO_TXE0_STATUS 0x50E
-#define B43_MMIO_TXE0_MMPLCP0 0x510
-#define B43_MMIO_TXE0_MMPLCP1 0x512
-#define B43_MMIO_TXE0_PHYCTL1 0x514
-#define B43_MMIO_XMTFIFODEF 0x520
-#define B43_MMIO_XMTFIFO_FRAME_CNT 0x522 /* core rev>= 16 only */
-#define B43_MMIO_XMTFIFO_BYTE_CNT 0x524 /* core rev>= 16 only */
-#define B43_MMIO_XMTFIFO_HEAD 0x526 /* core rev>= 16 only */
-#define B43_MMIO_XMTFIFO_RD_PTR 0x528 /* core rev>= 16 only */
-#define B43_MMIO_XMTFIFO_WR_PTR 0x52A /* core rev>= 16 only */
-#define B43_MMIO_XMTFIFODEF1 0x52C /* core rev>= 16 only */
-#define B43_MMIO_XMTFIFOCMD 0x540
-#define B43_MMIO_XMTFIFOFLUSH 0x542
-#define B43_MMIO_XMTFIFOTHRESH 0x544
-#define B43_MMIO_XMTFIFORDY 0x546
-#define B43_MMIO_XMTFIFOPRIRDY 0x548
-#define B43_MMIO_XMTFIFORQPRI 0x54A
-#define B43_MMIO_XMTTPLATETXPTR 0x54C
-#define B43_MMIO_XMTTPLATEPTR 0x550
-#define B43_MMIO_SMPL_CLCT_STRPTR 0x552 /* core rev>= 22 only */
-#define B43_MMIO_SMPL_CLCT_STPPTR 0x554 /* core rev>= 22 only */
-#define B43_MMIO_SMPL_CLCT_CURPTR 0x556 /* core rev>= 22 only */
-#define B43_MMIO_XMTTPLATEDATALO 0x560
-#define B43_MMIO_XMTTPLATEDATAHI 0x562
-#define B43_MMIO_XMTSEL 0x568
-#define B43_MMIO_XMTTXCNT 0x56A
-#define B43_MMIO_XMTTXSHMADDR 0x56C
#define B43_MMIO_TSF_CFP_START_LOW 0x604
#define B43_MMIO_TSF_CFP_START_HIGH 0x606
#define B43_MMIO_TSF_CFP_PRETBTT 0x612
@@ -152,16 +118,12 @@
#define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */
#define B43_MMIO_RNG 0x65A
#define B43_MMIO_IFSSLOT 0x684 /* Interframe slot time */
-#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */
-#define B43_MMIO_IFSSTAT 0x690
-#define B43_MMIO_IFSMEDBUSYCTL 0x692
-#define B43_MMIO_IFTXDUR 0x694
+#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */
#define B43_MMIO_IFSCTL_USE_EDCF 0x0004
#define B43_MMIO_POWERUP_DELAY 0x6A8
#define B43_MMIO_BTCOEX_CTL 0x6B4 /* Bluetooth Coexistence Control */
#define B43_MMIO_BTCOEX_STAT 0x6B6 /* Bluetooth Coexistence Status */
#define B43_MMIO_BTCOEX_TXCTL 0x6B8 /* Bluetooth Coexistence Transmit Control */
-#define B43_MMIO_WEPCTL 0x7C0
/* SPROM boardflags_lo values */
#define B43_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */
diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c
index 7cf4125a1624..56fa3a3648c4 100644
--- a/trunk/drivers/net/wireless/b43/main.c
+++ b/trunk/drivers/net/wireless/b43/main.c
@@ -729,59 +729,52 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)
for (i = 0; i < 5; i++)
b43_ram_write(dev, i * 4, buffer[i]);
- b43_write16(dev, B43_MMIO_XMTSEL, 0x0000);
-
+ b43_write16(dev, 0x0568, 0x0000);
if (dev->dev->core_rev < 11)
- b43_write16(dev, B43_MMIO_WEPCTL, 0x0000);
+ b43_write16(dev, 0x07C0, 0x0000);
else
- b43_write16(dev, B43_MMIO_WEPCTL, 0x0100);
-
+ b43_write16(dev, 0x07C0, 0x0100);
value = (ofdm ? 0x41 : 0x40);
- b43_write16(dev, B43_MMIO_TXE0_PHYCTL, value);
- if (phy->type == B43_PHYTYPE_N || phy->type == B43_PHYTYPE_LP ||
- phy->type == B43_PHYTYPE_LCN)
- b43_write16(dev, B43_MMIO_TXE0_PHYCTL1, 0x1A02);
-
- b43_write16(dev, B43_MMIO_TXE0_WM_0, 0x0000);
- b43_write16(dev, B43_MMIO_TXE0_WM_1, 0x0000);
-
- b43_write16(dev, B43_MMIO_XMTTPLATETXPTR, 0x0000);
- b43_write16(dev, B43_MMIO_XMTTXCNT, 0x0014);
- b43_write16(dev, B43_MMIO_XMTSEL, 0x0826);
- b43_write16(dev, B43_MMIO_TXE0_CTL, 0x0000);
-
- if (!pa_on && phy->type == B43_PHYTYPE_N)
- ; /*b43_nphy_pa_override(dev, false) */
+ b43_write16(dev, 0x050C, value);
+ if ((phy->type == B43_PHYTYPE_N) || (phy->type == B43_PHYTYPE_LP))
+ b43_write16(dev, 0x0514, 0x1A02);
+ b43_write16(dev, 0x0508, 0x0000);
+ b43_write16(dev, 0x050A, 0x0000);
+ b43_write16(dev, 0x054C, 0x0000);
+ b43_write16(dev, 0x056A, 0x0014);
+ b43_write16(dev, 0x0568, 0x0826);
+ b43_write16(dev, 0x0500, 0x0000);
+ if (!pa_on && (phy->type == B43_PHYTYPE_N)) {
+ //SPEC TODO
+ }
switch (phy->type) {
case B43_PHYTYPE_N:
- case B43_PHYTYPE_LCN:
- b43_write16(dev, B43_MMIO_TXE0_AUX, 0x00D0);
+ b43_write16(dev, 0x0502, 0x00D0);
break;
case B43_PHYTYPE_LP:
- b43_write16(dev, B43_MMIO_TXE0_AUX, 0x0050);
+ b43_write16(dev, 0x0502, 0x0050);
break;
default:
- b43_write16(dev, B43_MMIO_TXE0_AUX, 0x0030);
+ b43_write16(dev, 0x0502, 0x0030);
}
- b43_read16(dev, B43_MMIO_TXE0_AUX);
if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5)
b43_radio_write16(dev, 0x0051, 0x0017);
for (i = 0x00; i < max_loop; i++) {
- value = b43_read16(dev, B43_MMIO_TXE0_STATUS);
+ value = b43_read16(dev, 0x050E);
if (value & 0x0080)
break;
udelay(10);
}
for (i = 0x00; i < 0x0A; i++) {
- value = b43_read16(dev, B43_MMIO_TXE0_STATUS);
+ value = b43_read16(dev, 0x050E);
if (value & 0x0400)
break;
udelay(10);
}
for (i = 0x00; i < 0x19; i++) {
- value = b43_read16(dev, B43_MMIO_IFSSTAT);
+ value = b43_read16(dev, 0x0690);
if (!(value & 0x0100))
break;
udelay(10);
@@ -3559,8 +3552,7 @@ static void b43_qos_init(struct b43_wldev *dev)
b43dbg(dev->wl, "QoS enabled\n");
}
-static int b43_op_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 _queue,
+static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue,
const struct ieee80211_tx_queue_params *params)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
@@ -3607,7 +3599,7 @@ static int b43_op_get_stats(struct ieee80211_hw *hw,
return 0;
}
-static u64 b43_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+static u64 b43_op_get_tsf(struct ieee80211_hw *hw)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
@@ -3626,8 +3618,7 @@ static u64 b43_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
return tsf;
}
-static void b43_op_set_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u64 tsf)
+static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
diff --git a/trunk/drivers/net/wireless/b43/phy_lcn.c b/trunk/drivers/net/wireless/b43/phy_lcn.c
index a13e28ef6246..bffeb44b4a40 100644
--- a/trunk/drivers/net/wireless/b43/phy_lcn.c
+++ b/trunk/drivers/net/wireless/b43/phy_lcn.c
@@ -433,7 +433,7 @@ static void b43_phy_lcn_sense_setup(struct b43_wldev *dev,
b43_phy_set(dev, 0x4d0, 0x20);
b43_radio_write(dev, 0x112, 0x6);
- b43_dummy_transmission(dev, true, false);
+ /* TODO: dummy transmission? */
/* Wait if not done */
if (!(b43_phy_read(dev, 0x476) & 0x8000))
udelay(10);
diff --git a/trunk/drivers/net/wireless/b43/tables_phy_lcn.c b/trunk/drivers/net/wireless/b43/tables_phy_lcn.c
index 5176363cadf2..9d484e2f79bf 100644
--- a/trunk/drivers/net/wireless/b43/tables_phy_lcn.c
+++ b/trunk/drivers/net/wireless/b43/tables_phy_lcn.c
@@ -657,25 +657,8 @@ void b43_phy_lcn_load_tx_gain_tab(struct b43_wldev *dev,
}
}
-/* wlc_lcnphy_load_rfpower */
-static void b43_phy_lcn_load_rfpower(struct b43_wldev *dev)
-{
- u32 bbmult, rfgain;
- u8 i;
-
- for (i = 0; i < 128; i++) {
- bbmult = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x140 + i));
- bbmult >>= 20;
- rfgain = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0xc0 + i));
-
- /* TODO: calculate value for 0x240 + i table offset
- * b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x240 + i), val);
- */
- }
-}
-
/* Not implemented in brcmsmac, noticed in wl in MMIO dump */
-static void b43_phy_lcn_rewrite_rfpower_table(struct b43_wldev *dev)
+static void b43_phy_lcn_rewrite_tables(struct b43_wldev *dev)
{
int i;
u32 tmp;
@@ -702,7 +685,7 @@ void b43_phy_lcn_tables_init(struct b43_wldev *dev)
b43_phy_lcn_upload_static_tables(dev);
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
- if (sprom->boardflags_lo & B43_BFL_FEM)
+ if (sprom->boardflags_lo & B43_BFL_EXTLNA)
b43_phy_lcn_load_tx_gain_tab(dev,
b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0);
else
@@ -718,7 +701,7 @@ void b43_phy_lcn_tables_init(struct b43_wldev *dev)
else
b43err(dev->wl, "SW ctl table is unknown for this card\n");
- b43_phy_lcn_load_rfpower(dev);
- b43_phy_lcn_rewrite_rfpower_table(dev);
+ /* TODO: various tables ops here */
+ b43_phy_lcn_rewrite_tables(dev);
b43_phy_lcn_clean_papd_comp_table(dev);
}
diff --git a/trunk/drivers/net/wireless/b43legacy/main.c b/trunk/drivers/net/wireless/b43legacy/main.c
index a3b72cd72c66..468d1836548e 100644
--- a/trunk/drivers/net/wireless/b43legacy/main.c
+++ b/trunk/drivers/net/wireless/b43legacy/main.c
@@ -2466,8 +2466,7 @@ static void b43legacy_op_tx(struct ieee80211_hw *hw,
}
}
-static int b43legacy_op_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
return 0;
diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-4965-tx.c b/trunk/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
index 7f12e3638bae..ac4f64de1363 100644
--- a/trunk/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
+++ b/trunk/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
@@ -335,7 +335,7 @@ int iwl4965_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
sta_priv = (void *)sta->drv_priv;
if (sta_priv && sta_priv->asleep &&
- (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)) {
+ (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)) {
/*
* This sends an asynchronous command to the device,
* but we can rely on it being processed before the
diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-core.c b/trunk/drivers/net/wireless/iwlegacy/iwl-core.c
index 2bd5659310d7..35cd2537e7fd 100644
--- a/trunk/drivers/net/wireless/iwlegacy/iwl-core.c
+++ b/trunk/drivers/net/wireless/iwlegacy/iwl-core.c
@@ -937,7 +937,7 @@ void iwl_legacy_irq_handle_error(struct iwl_priv *priv)
&priv->contexts[IWL_RXON_CTX_BSS]);
#endif
- wake_up(&priv->wait_command_queue);
+ wake_up_interruptible(&priv->wait_command_queue);
/* Keep the restart process from trying to send host
* commands by clearing the INIT status bit */
@@ -1250,8 +1250,7 @@ void iwl_legacy_clear_isr_stats(struct iwl_priv *priv)
memset(&priv->isr_stats, 0, sizeof(priv->isr_stats));
}
-int iwl_legacy_mac_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+int iwl_legacy_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct iwl_priv *priv = hw->priv;
@@ -1747,7 +1746,7 @@ int iwl_legacy_force_reset(struct iwl_priv *priv, bool external)
/* Set the FW error flag -- cleared on iwl_down */
set_bit(STATUS_FW_ERROR, &priv->status);
- wake_up(&priv->wait_command_queue);
+ wake_up_interruptible(&priv->wait_command_queue);
/*
* Keep the restart process from trying to send host
* commands by clearing the INIT status bit
@@ -2221,8 +2220,7 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)
}
EXPORT_SYMBOL(iwl_legacy_mac_config);
-void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
unsigned long flags;
diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-core.h b/trunk/drivers/net/wireless/iwlegacy/iwl-core.h
index d1271fe07d4b..84da79376ef8 100644
--- a/trunk/drivers/net/wireless/iwlegacy/iwl-core.h
+++ b/trunk/drivers/net/wireless/iwlegacy/iwl-core.h
@@ -286,8 +286,7 @@ struct iwl_cfg {
***************************/
struct ieee80211_hw *iwl_legacy_alloc_all(struct iwl_cfg *cfg);
-int iwl_legacy_mac_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+int iwl_legacy_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
int iwl_legacy_mac_tx_last_beacon(struct ieee80211_hw *hw);
void iwl_legacy_set_rxon_hwcrypto(struct iwl_priv *priv,
@@ -621,8 +620,7 @@ static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
/* mac80211 handlers */
int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed);
-void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif);
+void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw);
void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-hcmd.c b/trunk/drivers/net/wireless/iwlegacy/iwl-hcmd.c
index ce1fc9feb61f..62b4b09122cb 100644
--- a/trunk/drivers/net/wireless/iwlegacy/iwl-hcmd.c
+++ b/trunk/drivers/net/wireless/iwlegacy/iwl-hcmd.c
@@ -167,7 +167,7 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
goto out;
}
- ret = wait_event_timeout(priv->wait_command_queue,
+ ret = wait_event_interruptible_timeout(priv->wait_command_queue,
!test_bit(STATUS_HCMD_ACTIVE, &priv->status),
HOST_COMPLETE_TIMEOUT);
if (!ret) {
diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-tx.c b/trunk/drivers/net/wireless/iwlegacy/iwl-tx.c
index ef9e268bf8a0..4fff995c6f3e 100644
--- a/trunk/drivers/net/wireless/iwlegacy/iwl-tx.c
+++ b/trunk/drivers/net/wireless/iwlegacy/iwl-tx.c
@@ -625,8 +625,6 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
cmd = txq->cmd[cmd_index];
meta = &txq->meta[cmd_index];
- txq->time_stamp = jiffies;
-
pci_unmap_single(priv->pci_dev,
dma_unmap_addr(meta, mapping),
dma_unmap_len(meta, len),
@@ -647,7 +645,7 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s\n",
iwl_legacy_get_cmd_string(cmd->hdr.cmd));
- wake_up(&priv->wait_command_queue);
+ wake_up_interruptible(&priv->wait_command_queue);
}
/* Mark as unmapped */
diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl3945-base.c b/trunk/drivers/net/wireless/iwlegacy/iwl3945-base.c
index b282d869a546..015739d204f2 100644
--- a/trunk/drivers/net/wireless/iwlegacy/iwl3945-base.c
+++ b/trunk/drivers/net/wireless/iwlegacy/iwl3945-base.c
@@ -840,7 +840,7 @@ static void iwl3945_rx_card_state_notif(struct iwl_priv *priv,
wiphy_rfkill_set_hw_state(priv->hw->wiphy,
test_bit(STATUS_RF_KILL_HW, &priv->status));
else
- wake_up(&priv->wait_command_queue);
+ wake_up_interruptible(&priv->wait_command_queue);
}
/**
@@ -2268,7 +2268,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
iwl3945_reg_txpower_periodic(priv);
IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
- wake_up(&priv->wait_command_queue);
+ wake_up_interruptible(&priv->wait_command_queue);
return;
@@ -2299,7 +2299,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
iwl_legacy_clear_driver_stations(priv);
/* Unblock any waiting calls */
- wake_up_all(&priv->wait_command_queue);
+ wake_up_interruptible_all(&priv->wait_command_queue);
/* Wipe out the EXIT_PENDING status bit if we are not actually
* exiting the module */
@@ -2852,7 +2852,7 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
/* Wait for START_ALIVE from ucode. Otherwise callbacks from
* mac80211 will not be run successfully. */
- ret = wait_event_timeout(priv->wait_command_queue,
+ ret = wait_event_interruptible_timeout(priv->wait_command_queue,
test_bit(STATUS_READY, &priv->status),
UCODE_READY_TIMEOUT);
if (!ret) {
diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c b/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c
index d2fba9eae153..6bc5575c8dff 100644
--- a/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c
+++ b/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c
@@ -575,7 +575,7 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
wiphy_rfkill_set_hw_state(priv->hw->wiphy,
test_bit(STATUS_RF_KILL_HW, &priv->status));
else
- wake_up(&priv->wait_command_queue);
+ wake_up_interruptible(&priv->wait_command_queue);
}
/**
@@ -925,7 +925,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
handled |= CSR_INT_BIT_FH_TX;
/* Wake up uCode load routine, now that load is complete */
priv->ucode_write_complete = 1;
- wake_up(&priv->wait_command_queue);
+ wake_up_interruptible(&priv->wait_command_queue);
}
if (inta & ~handled) {
@@ -1794,7 +1794,7 @@ static void iwl4965_alive_start(struct iwl_priv *priv)
iwl4965_rf_kill_ct_config(priv);
IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
- wake_up(&priv->wait_command_queue);
+ wake_up_interruptible(&priv->wait_command_queue);
iwl_legacy_power_update_mode(priv, true);
IWL_DEBUG_INFO(priv, "Updated power mode\n");
@@ -1827,7 +1827,7 @@ static void __iwl4965_down(struct iwl_priv *priv)
iwl_legacy_clear_driver_stations(priv);
/* Unblock any waiting calls */
- wake_up_all(&priv->wait_command_queue);
+ wake_up_interruptible_all(&priv->wait_command_queue);
/* Wipe out the EXIT_PENDING status bit if we are not actually
* exiting the module */
@@ -2265,7 +2265,7 @@ int iwl4965_mac_start(struct ieee80211_hw *hw)
/* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
* mac80211 will not be run successfully. */
- ret = wait_event_timeout(priv->wait_command_queue,
+ ret = wait_event_interruptible_timeout(priv->wait_command_queue,
test_bit(STATUS_READY, &priv->status),
UCODE_READY_TIMEOUT);
if (!ret) {
diff --git a/trunk/drivers/net/wireless/iwlwifi/Kconfig b/trunk/drivers/net/wireless/iwlwifi/Kconfig
index e0441033788c..1d7572f9887f 100644
--- a/trunk/drivers/net/wireless/iwlwifi/Kconfig
+++ b/trunk/drivers/net/wireless/iwlwifi/Kconfig
@@ -1,5 +1,5 @@
-config IWLWIFI
- tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) "
+config IWLAGN
+ tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlagn) "
depends on PCI && MAC80211
select FW_LOADER
select NEW_LEDS
@@ -39,14 +39,14 @@ config IWLWIFI
If you want to compile the driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read . The
- module will be called iwlwifi.
+ module will be called iwlagn.
menu "Debugging Options"
- depends on IWLWIFI
+ depends on IWLAGN
config IWLWIFI_DEBUG
- bool "Enable full debugging output in the iwlwifi driver"
- depends on IWLWIFI
+ bool "Enable full debugging output in the iwlagn driver"
+ depends on IWLAGN
---help---
This option will enable debug tracing output for the iwlwifi drivers
@@ -70,8 +70,8 @@ config IWLWIFI_DEBUG
any problems you may encounter.
config IWLWIFI_DEBUGFS
- bool "iwlwifi debugfs support"
- depends on IWLWIFI && MAC80211_DEBUGFS
+ bool "iwlagn debugfs support"
+ depends on IWLAGN && MAC80211_DEBUGFS
---help---
Enable creation of debugfs files for the iwlwifi drivers. This
is a low-impact option that allows getting insight into the
@@ -79,13 +79,13 @@ config IWLWIFI_DEBUGFS
config IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
bool "Experimental uCode support"
- depends on IWLWIFI && IWLWIFI_DEBUG
+ depends on IWLAGN && IWLWIFI_DEBUG
---help---
Enable use of experimental ucode for testing and debugging.
config IWLWIFI_DEVICE_TRACING
bool "iwlwifi device access tracing"
- depends on IWLWIFI
+ depends on IWLAGN
depends on EVENT_TRACING
help
Say Y here to trace all commands, including TX frames and IO
@@ -104,7 +104,7 @@ endmenu
config IWLWIFI_DEVICE_SVTOOL
bool "iwlwifi device svtool support"
- depends on IWLWIFI
+ depends on IWLAGN
select NL80211_TESTMODE
help
This option enables the svtool support for iwlwifi device through
diff --git a/trunk/drivers/net/wireless/iwlwifi/Makefile b/trunk/drivers/net/wireless/iwlwifi/Makefile
index bacafa4a5f48..8fa59cdb3b49 100644
--- a/trunk/drivers/net/wireless/iwlwifi/Makefile
+++ b/trunk/drivers/net/wireless/iwlwifi/Makefile
@@ -1,25 +1,25 @@
-# WIFI
-obj-$(CONFIG_IWLWIFI) += iwlwifi.o
-iwlwifi-objs := iwl-agn.o iwl-agn-rs.o
-iwlwifi-objs += iwl-agn-ucode.o iwl-agn-tx.o
-iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o
-iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o
+# AGN
+obj-$(CONFIG_IWLAGN) += iwlagn.o
+iwlagn-objs := iwl-agn.o iwl-agn-rs.o
+iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o
+iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o
+iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o
-iwlwifi-objs += iwl-core.o iwl-eeprom.o iwl-power.o
-iwlwifi-objs += iwl-rx.o iwl-sta.o
-iwlwifi-objs += iwl-scan.o iwl-led.o
-iwlwifi-objs += iwl-agn-rxon.o
-iwlwifi-objs += iwl-5000.o
-iwlwifi-objs += iwl-6000.o
-iwlwifi-objs += iwl-1000.o
-iwlwifi-objs += iwl-2000.o
-iwlwifi-objs += iwl-pci.o
-iwlwifi-objs += iwl-trans.o
-iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o
+iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-power.o
+iwlagn-objs += iwl-rx.o iwl-sta.o
+iwlagn-objs += iwl-scan.o iwl-led.o
+iwlagn-objs += iwl-agn-rxon.o
+iwlagn-objs += iwl-5000.o
+iwlagn-objs += iwl-6000.o
+iwlagn-objs += iwl-1000.o
+iwlagn-objs += iwl-2000.o
+iwlagn-objs += iwl-pci.o
+iwlagn-objs += iwl-trans.o
+iwlagn-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o
-iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
-iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
-iwlwifi-$(CONFIG_IWLWIFI_DEVICE_SVTOOL) += iwl-sv-open.o
+iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
+iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
+iwlagn-$(CONFIG_IWLWIFI_DEVICE_SVTOOL) += iwl-sv-open.o
CFLAGS_iwl-devtrace.o := -I$(src)
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index d30714be515b..e8b324c84da8 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -190,6 +190,433 @@ int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
return -1;
}
+static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
+ struct ieee80211_vif *vif,
+ enum ieee80211_band band,
+ struct iwl_scan_channel *scan_ch)
+{
+ const struct ieee80211_supported_band *sband;
+ u16 passive_dwell = 0;
+ u16 active_dwell = 0;
+ int added = 0;
+ u16 channel = 0;
+
+ sband = iwl_get_hw_mode(priv, band);
+ if (!sband) {
+ IWL_ERR(priv, "invalid band\n");
+ return added;
+ }
+
+ active_dwell = iwl_get_active_dwell_time(priv, band, 0);
+ passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
+
+ if (passive_dwell <= active_dwell)
+ passive_dwell = active_dwell + 1;
+
+ channel = iwl_get_single_channel_number(priv, band);
+ if (channel) {
+ scan_ch->channel = cpu_to_le16(channel);
+ scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
+ scan_ch->active_dwell = cpu_to_le16(active_dwell);
+ scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
+ /* Set txpower levels to defaults */
+ scan_ch->dsp_atten = 110;
+ if (band == IEEE80211_BAND_5GHZ)
+ scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
+ else
+ scan_ch->tx_gain = ((1 << 5) | (5 << 3));
+ added++;
+ } else
+ IWL_ERR(priv, "no valid channel found\n");
+ return added;
+}
+
+static int iwl_get_channels_for_scan(struct iwl_priv *priv,
+ struct ieee80211_vif *vif,
+ enum ieee80211_band band,
+ u8 is_active, u8 n_probes,
+ struct iwl_scan_channel *scan_ch)
+{
+ struct ieee80211_channel *chan;
+ const struct ieee80211_supported_band *sband;
+ const struct iwl_channel_info *ch_info;
+ u16 passive_dwell = 0;
+ u16 active_dwell = 0;
+ int added, i;
+ u16 channel;
+
+ sband = iwl_get_hw_mode(priv, band);
+ if (!sband)
+ return 0;
+
+ active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
+ passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
+
+ if (passive_dwell <= active_dwell)
+ passive_dwell = active_dwell + 1;
+
+ for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
+ chan = priv->scan_request->channels[i];
+
+ if (chan->band != band)
+ continue;
+
+ channel = chan->hw_value;
+ scan_ch->channel = cpu_to_le16(channel);
+
+ ch_info = iwl_get_channel_info(priv, band, channel);
+ if (!is_channel_valid(ch_info)) {
+ IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
+ channel);
+ continue;
+ }
+
+ if (!is_active || is_channel_passive(ch_info) ||
+ (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
+ scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
+ else
+ scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
+
+ if (n_probes)
+ scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+
+ scan_ch->active_dwell = cpu_to_le16(active_dwell);
+ scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
+
+ /* Set txpower levels to defaults */
+ scan_ch->dsp_atten = 110;
+
+ /* NOTE: if we were doing 6Mb OFDM for scans we'd use
+ * power level:
+ * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
+ */
+ if (band == IEEE80211_BAND_5GHZ)
+ scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
+ else
+ scan_ch->tx_gain = ((1 << 5) | (5 << 3));
+
+ IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n",
+ channel, le32_to_cpu(scan_ch->type),
+ (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
+ "ACTIVE" : "PASSIVE",
+ (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
+ active_dwell : passive_dwell);
+
+ scan_ch++;
+ added++;
+ }
+
+ IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added);
+ return added;
+}
+
+int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
+{
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_SCAN_CMD,
+ .len = { sizeof(struct iwl_scan_cmd), },
+ .flags = CMD_SYNC,
+ };
+ struct iwl_scan_cmd *scan;
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+ u32 rate_flags = 0;
+ u16 cmd_len;
+ u16 rx_chain = 0;
+ enum ieee80211_band band;
+ u8 n_probes = 0;
+ u8 rx_ant = hw_params(priv).valid_rx_ant;
+ u8 rate;
+ bool is_active = false;
+ int chan_mod;
+ u8 active_chains;
+ u8 scan_tx_antennas = hw_params(priv).valid_tx_ant;
+ int ret;
+
+ lockdep_assert_held(&priv->shrd->mutex);
+
+ if (vif)
+ ctx = iwl_rxon_ctx_from_vif(vif);
+
+ if (!priv->scan_cmd) {
+ priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) +
+ IWL_MAX_SCAN_SIZE, GFP_KERNEL);
+ if (!priv->scan_cmd) {
+ IWL_DEBUG_SCAN(priv,
+ "fail to allocate memory for scan\n");
+ return -ENOMEM;
+ }
+ }
+ scan = priv->scan_cmd;
+ memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
+
+ scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
+ scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
+
+ if (priv->scan_type != IWL_SCAN_ROC &&
+ iwl_is_any_associated(priv)) {
+ u16 interval = 0;
+ u32 extra;
+ u32 suspend_time = 100;
+ u32 scan_suspend_time = 100;
+
+ IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
+ switch (priv->scan_type) {
+ case IWL_SCAN_ROC:
+ WARN_ON(1);
+ break;
+ case IWL_SCAN_RADIO_RESET:
+ interval = 0;
+ break;
+ case IWL_SCAN_NORMAL:
+ interval = vif->bss_conf.beacon_int;
+ break;
+ }
+
+ scan->suspend_time = 0;
+ scan->max_out_time = cpu_to_le32(200 * 1024);
+ if (!interval)
+ interval = suspend_time;
+
+ extra = (suspend_time / interval) << 22;
+ scan_suspend_time = (extra |
+ ((suspend_time % interval) * 1024));
+ scan->suspend_time = cpu_to_le32(scan_suspend_time);
+ IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
+ scan_suspend_time, interval);
+ } else if (priv->scan_type == IWL_SCAN_ROC) {
+ scan->suspend_time = 0;
+ scan->max_out_time = 0;
+ scan->quiet_time = 0;
+ scan->quiet_plcp_th = 0;
+ }
+
+ switch (priv->scan_type) {
+ case IWL_SCAN_RADIO_RESET:
+ IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
+ break;
+ case IWL_SCAN_NORMAL:
+ if (priv->scan_request->n_ssids) {
+ int i, p = 0;
+ IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
+ for (i = 0; i < priv->scan_request->n_ssids; i++) {
+ /* always does wildcard anyway */
+ if (!priv->scan_request->ssids[i].ssid_len)
+ continue;
+ scan->direct_scan[p].id = WLAN_EID_SSID;
+ scan->direct_scan[p].len =
+ priv->scan_request->ssids[i].ssid_len;
+ memcpy(scan->direct_scan[p].ssid,
+ priv->scan_request->ssids[i].ssid,
+ priv->scan_request->ssids[i].ssid_len);
+ n_probes++;
+ p++;
+ }
+ is_active = true;
+ } else
+ IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
+ break;
+ case IWL_SCAN_ROC:
+ IWL_DEBUG_SCAN(priv, "Start ROC scan.\n");
+ break;
+ }
+
+ scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
+ scan->tx_cmd.sta_id = ctx->bcast_sta_id;
+ scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
+
+ switch (priv->scan_band) {
+ case IEEE80211_BAND_2GHZ:
+ scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
+ chan_mod = le32_to_cpu(
+ priv->contexts[IWL_RXON_CTX_BSS].active.flags &
+ RXON_FLG_CHANNEL_MODE_MSK)
+ >> RXON_FLG_CHANNEL_MODE_POS;
+ if (chan_mod == CHANNEL_MODE_PURE_40) {
+ rate = IWL_RATE_6M_PLCP;
+ } else {
+ rate = IWL_RATE_1M_PLCP;
+ rate_flags = RATE_MCS_CCK_MSK;
+ }
+ /*
+ * Internal scans are passive, so we can indiscriminately set
+ * the BT ignore flag on 2.4 GHz since it applies to TX only.
+ */
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist)
+ scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
+ break;
+ case IEEE80211_BAND_5GHZ:
+ rate = IWL_RATE_6M_PLCP;
+ break;
+ default:
+ IWL_WARN(priv, "Invalid scan band\n");
+ return -EIO;
+ }
+
+ /*
+ * If active scanning is requested but a certain channel is
+ * marked passive, we can do active scanning if we detect
+ * transmissions.
+ *
+ * There is an issue with some firmware versions that triggers
+ * a sysassert on a "good CRC threshold" of zero (== disabled),
+ * on a radar channel even though this means that we should NOT
+ * send probes.
+ *
+ * The "good CRC threshold" is the number of frames that we
+ * need to receive during our dwell time on a channel before
+ * sending out probes -- setting this to a huge value will
+ * mean we never reach it, but at the same time work around
+ * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
+ * here instead of IWL_GOOD_CRC_TH_DISABLED.
+ *
+ * This was fixed in later versions along with some other
+ * scan changes, and the threshold behaves as a flag in those
+ * versions.
+ */
+ if (priv->new_scan_threshold_behaviour)
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+ IWL_GOOD_CRC_TH_DISABLED;
+ else
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+ IWL_GOOD_CRC_TH_NEVER;
+
+ band = priv->scan_band;
+
+ if (priv->cfg->scan_rx_antennas[band])
+ rx_ant = priv->cfg->scan_rx_antennas[band];
+
+ if (band == IEEE80211_BAND_2GHZ &&
+ priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist) {
+ /* transmit 2.4 GHz probes only on first antenna */
+ scan_tx_antennas = first_antenna(scan_tx_antennas);
+ }
+
+ priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band],
+ scan_tx_antennas);
+ rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
+ scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
+
+ /* In power save mode use one chain, otherwise use all chains */
+ if (test_bit(STATUS_POWER_PMI, &priv->shrd->status)) {
+ /* rx_ant has been set to all valid chains previously */
+ active_chains = rx_ant &
+ ((u8)(priv->chain_noise_data.active_chains));
+ if (!active_chains)
+ active_chains = rx_ant;
+
+ IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n",
+ priv->chain_noise_data.active_chains);
+
+ rx_ant = first_antenna(active_chains);
+ }
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist &&
+ priv->bt_full_concurrent) {
+ /* operated as 1x1 in full concurrency mode */
+ rx_ant = first_antenna(rx_ant);
+ }
+
+ /* MIMO is not used here, but value is required */
+ rx_chain |=
+ hw_params(priv).valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
+ rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+ rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
+ rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
+ scan->rx_chain = cpu_to_le16(rx_chain);
+ switch (priv->scan_type) {
+ case IWL_SCAN_NORMAL:
+ cmd_len = iwl_fill_probe_req(priv,
+ (struct ieee80211_mgmt *)scan->data,
+ vif->addr,
+ priv->scan_request->ie,
+ priv->scan_request->ie_len,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan));
+ break;
+ case IWL_SCAN_RADIO_RESET:
+ case IWL_SCAN_ROC:
+ /* use bcast addr, will not be transmitted but must be valid */
+ cmd_len = iwl_fill_probe_req(priv,
+ (struct ieee80211_mgmt *)scan->data,
+ iwl_bcast_addr, NULL, 0,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan));
+ break;
+ default:
+ BUG();
+ }
+ scan->tx_cmd.len = cpu_to_le16(cmd_len);
+
+ scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
+ RXON_FILTER_BCON_AWARE_MSK);
+
+ switch (priv->scan_type) {
+ case IWL_SCAN_RADIO_RESET:
+ scan->channel_count =
+ iwl_get_single_channel_for_scan(priv, vif, band,
+ (void *)&scan->data[cmd_len]);
+ break;
+ case IWL_SCAN_NORMAL:
+ scan->channel_count =
+ iwl_get_channels_for_scan(priv, vif, band,
+ is_active, n_probes,
+ (void *)&scan->data[cmd_len]);
+ break;
+ case IWL_SCAN_ROC: {
+ struct iwl_scan_channel *scan_ch;
+
+ scan->channel_count = 1;
+
+ scan_ch = (void *)&scan->data[cmd_len];
+ scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
+ scan_ch->channel =
+ cpu_to_le16(priv->hw_roc_channel->hw_value);
+ scan_ch->active_dwell =
+ scan_ch->passive_dwell =
+ cpu_to_le16(priv->hw_roc_duration);
+
+ /* Set txpower levels to defaults */
+ scan_ch->dsp_atten = 110;
+
+ /* NOTE: if we were doing 6Mb OFDM for scans we'd use
+ * power level:
+ * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
+ */
+ if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ)
+ scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
+ else
+ scan_ch->tx_gain = ((1 << 5) | (5 << 3));
+ }
+ break;
+ }
+
+ if (scan->channel_count == 0) {
+ IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
+ return -EIO;
+ }
+
+ cmd.len[0] += le16_to_cpu(scan->tx_cmd.len) +
+ scan->channel_count * sizeof(struct iwl_scan_channel);
+ cmd.data[0] = scan;
+ cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
+ scan->len = cpu_to_le16(cmd.len[0]);
+
+ /* set scan bit here for PAN params */
+ set_bit(STATUS_SCAN_HW, &priv->shrd->status);
+
+ ret = iwlagn_set_pan_params(priv);
+ if (ret)
+ return ret;
+
+ ret = iwl_trans_send_cmd(trans(priv), &cmd);
+ if (ret) {
+ clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
+ iwlagn_set_pan_params(priv);
+ }
+
+ return ret;
+}
+
int iwlagn_manage_ibss_station(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add)
{
@@ -705,9 +1132,8 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv,
}
}
-int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
unsigned long flags;
struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -716,7 +1142,7 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) {
/* bt coex disabled */
- return 0;
+ return;
}
IWL_DEBUG_COEX(priv, "BT Coex notification:\n");
@@ -758,7 +1184,6 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
spin_lock_irqsave(&priv->shrd->lock, flags);
priv->bt_ci_compliance = coex->bt_ci_compliance;
spin_unlock_irqrestore(&priv->shrd->lock, flags);
- return 0;
}
void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv)
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 7d6a3bf64950..ffee15ba06a8 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -346,7 +346,7 @@ static void rs_program_fix_rate(struct iwl_priv *priv,
{
struct iwl_station_priv *sta_priv =
container_of(lq_sta, struct iwl_station_priv, lq_sta);
- struct iwl_rxon_context *ctx = sta_priv->ctx;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
@@ -710,7 +710,7 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
static bool rs_use_green(struct ieee80211_sta *sta)
{
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
- struct iwl_rxon_context *ctx = sta_priv->ctx;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
!(ctx->ht.non_gf_sta_present);
@@ -917,7 +917,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
struct iwl_scale_tbl_info tbl_type;
struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
- struct iwl_rxon_context *ctx = sta_priv->ctx;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
@@ -1283,7 +1283,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
s32 rate;
s8 is_green = lq_sta->is_green;
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
- struct iwl_rxon_context *ctx = sta_priv->ctx;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
@@ -1339,7 +1339,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
s32 rate;
s8 is_green = lq_sta->is_green;
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
- struct iwl_rxon_context *ctx = sta_priv->ctx;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
@@ -1396,7 +1396,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
u8 is_green = lq_sta->is_green;
s32 rate;
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
- struct iwl_rxon_context *ctx = sta_priv->ctx;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
@@ -2263,7 +2263,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
u8 tid = IWL_MAX_TID_COUNT;
struct iwl_tid_data *tid_data;
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
- struct iwl_rxon_context *ctx = sta_priv->ctx;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
@@ -2273,6 +2273,9 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
info->flags & IEEE80211_TX_CTL_NO_ACK)
return;
+ if (!sta || !lq_sta)
+ return;
+
lq_sta->supp_rates = sta->supp_rates[lq_sta->band];
tid = rs_tl_add_packet(lq_sta, hdr);
@@ -2703,7 +2706,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
return;
sta_priv = (void *)sta->drv_priv;
- ctx = sta_priv->ctx;
+ ctx = sta_priv->common.ctx;
i = lq_sta->last_txrate_idx;
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index ca632f9b1cc8..00e6fc59e459 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -370,7 +370,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
slot1 = IWL_MIN_SLOT_TIME;
} else if (!ctx_pan->vif->bss_conf.idle &&
!ctx_pan->vif->bss_conf.assoc) {
- slot1 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME;
+ slot1 = bcnint * 3 - IWL_MIN_SLOT_TIME;
slot0 = IWL_MIN_SLOT_TIME;
}
} else if (ctx_pan->vif) {
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
index c27180a73351..495f93664741 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
@@ -114,6 +114,9 @@ static bool iwl_within_ct_kill_margin(struct iwl_priv *priv)
s32 temp = priv->temperature; /* degrees CELSIUS except specified */
bool within_margin = false;
+ if (priv->cfg->base_params->temperature_kelvin)
+ temp = KELVIN_TO_CELSIUS(priv->temperature);
+
if (!priv->thermal_throttle.advanced_tt)
within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
CT_KILL_THRESHOLD_LEGACY) ? true : false;
@@ -588,6 +591,9 @@ static void iwl_bg_tt_work(struct work_struct *work)
if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
return;
+ if (priv->cfg->base_params->temperature_kelvin)
+ temp = KELVIN_TO_CELSIUS(priv->temperature);
+
if (!priv->thermal_throttle.advanced_tt)
iwl_legacy_tt_handler(priv, temp, false);
else
@@ -635,13 +641,11 @@ void iwl_tt_initialize(struct iwl_priv *priv)
if (priv->cfg->base_params->adv_thermal_throttle) {
IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n");
- tt->restriction = kcalloc(IWL_TI_STATE_MAX,
- sizeof(struct iwl_tt_restriction),
- GFP_KERNEL);
- tt->transaction = kcalloc(IWL_TI_STATE_MAX *
- (IWL_TI_STATE_MAX - 1),
- sizeof(struct iwl_tt_trans),
- GFP_KERNEL);
+ tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) *
+ IWL_TI_STATE_MAX, GFP_KERNEL);
+ tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) *
+ IWL_TI_STATE_MAX * (IWL_TI_STATE_MAX - 1),
+ GFP_KERNEL);
if (!tt->restriction || !tt->transaction) {
IWL_ERR(priv, "Fallback to Legacy Throttling\n");
priv->thermal_throttle.advanced_tt = false;
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index dcb3bd67d4f9..459b82b8a2a7 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -300,7 +300,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
sta_priv = (void *)info->control.sta->drv_priv;
if (sta_priv && sta_priv->asleep &&
- (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)) {
+ (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)) {
/*
* This sends an asynchronous command to the device,
* but we can rely on it being processed before the
@@ -313,9 +313,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
}
- if (info->flags & IEEE80211_TX_CTL_AMPDU)
- is_agg = true;
-
/* irqs already disabled/saved above when locking priv->shrd->lock */
spin_lock(&priv->shrd->sta_lock);
@@ -325,7 +322,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
goto drop_unlock_sta;
memset(dev_cmd, 0, sizeof(*dev_cmd));
- tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload;
+ tx_cmd = &dev_cmd->cmd.tx;
+
+ /* Copy MAC header from skb into command buffer */
+ memcpy(tx_cmd->hdr, hdr, hdr_len);
/* Total # bytes to be transmitted */
len = (u16)skb->len;
@@ -342,8 +342,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
iwl_update_stats(priv, true, fc, len);
- memset(&info->status, 0, sizeof(info->status));
-
info->driver_data[0] = ctx;
info->driver_data[1] = dev_cmd;
@@ -582,9 +580,6 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
IWL_DEBUG_COEX(priv, "receive reply tx w/ bt_kill\n");
}
- if (tx_resp->frame_count == 1)
- return;
-
/* Construct bit-map of pending frames within Tx window */
for (i = 0; i < tx_resp->frame_count; i++) {
u16 fstatus = le16_to_cpu(frame_status[i].status);
@@ -741,8 +736,7 @@ static void iwl_check_abort_status(struct iwl_priv *priv,
}
}
-int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
@@ -830,7 +824,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
iwl_check_abort_status(priv, tx_resp->frame_count, status);
spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
- return 0;
}
/**
@@ -839,9 +832,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
* Handles block-acknowledge notification from device, which reports success
* of frames sent via aggregation.
*/
-int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
@@ -865,7 +857,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
if (scd_flow >= hw_params(priv).max_txq_num) {
IWL_ERR(priv,
"BUG_ON scd_flow is bigger than number of queues\n");
- return 0;
+ return;
}
sta_id = ba_resp->sta_id;
@@ -885,14 +877,14 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
"BA scd_flow %d does not match txq_id %d\n",
scd_flow, agg->txq_id);
spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
- return 0;
+ return;
}
if (unlikely(!agg->wait_for_ba)) {
if (unlikely(ba_resp->bitmap))
IWL_ERR(priv, "Received BA when not expected\n");
spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
- return 0;
+ return;
}
IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
@@ -943,10 +935,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
else
WARN_ON_ONCE(1);
- info = IEEE80211_SKB_CB(skb);
- kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1]));
-
- if (freed == 1) {
+ if (freed == 0) {
/* this is the first skb we deliver in this batch */
/* put the rate scaling data there */
info = IEEE80211_SKB_CB(skb);
@@ -959,9 +948,11 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
info);
}
+ info = IEEE80211_SKB_CB(skb);
+ kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1]));
+
ieee80211_tx_status_irqsafe(priv->hw, skb);
}
spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
- return 0;
}
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index b4e1e7c4c314..634f18f6125a 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -228,9 +228,8 @@ static int iwlagn_send_calib_cfg(struct iwl_priv *priv)
return iwl_trans_send_cmd(trans(priv), &cmd);
}
-int iwlagn_rx_calib_result(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+void iwlagn_rx_calib_result(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
@@ -263,10 +262,9 @@ int iwlagn_rx_calib_result(struct iwl_priv *priv,
default:
IWL_ERR(priv, "Unknown calibration notification %d\n",
hdr->op_code);
- return -1;
+ return;
}
iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
- return 0;
}
int iwlagn_init_alive_start(struct iwl_priv *priv)
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c
index d0fd6f063bf8..6def1c272775 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -79,7 +79,6 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
MODULE_LICENSE("GPL");
-MODULE_ALIAS("iwlagn");
void iwl_update_chain_flags(struct iwl_priv *priv)
{
@@ -2514,7 +2513,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
mutex_lock(&priv->shrd->mutex);
IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n",
sta->addr);
- sta_priv->sta_id = IWL_INVALID_STATION;
+ sta_priv->common.sta_id = IWL_INVALID_STATION;
atomic_set(&sta_priv->pending_frames, 0);
if (vif->type == NL80211_IFTYPE_AP)
@@ -2530,7 +2529,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
return ret;
}
- sta_priv->sta_id = sta_id;
+ sta_priv->common.sta_id = sta_id;
/* Initialize rate scaling */
IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
@@ -2771,6 +2770,15 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw,
mutex_lock(&priv->shrd->mutex);
+ /*
+ * TODO: Remove this hack! Firmware needs to be updated
+ * to allow longer off-channel periods in scanning for
+ * this use case, based on a flag (and we'll need an API
+ * flag in the firmware when it has that).
+ */
+ if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && duration > 80)
+ duration = 80;
+
if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) {
err = -EBUSY;
goto out;
@@ -2779,7 +2787,6 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw,
priv->hw_roc_channel = channel;
priv->hw_roc_chantype = channel_type;
priv->hw_roc_duration = duration;
- priv->hw_roc_start_notified = false;
cancel_delayed_work(&priv->hw_roc_disable_work);
if (!ctx->is_active) {
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h
index 2a297d1e6bc7..4bc1f4669e5a 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -88,9 +88,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
u32 changes);
/* uCode */
-int iwlagn_rx_calib_result(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd);
+void iwlagn_rx_calib_result(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
void iwlagn_send_prio_tbl(struct iwl_priv *priv);
int iwlagn_run_init_ucode(struct iwl_priv *priv);
@@ -117,11 +116,9 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid, u16 *ssn);
int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid);
-int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd);
-int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd);
+void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
static inline u32 iwl_tx_status_to_mac80211(u32 status)
{
@@ -149,6 +146,7 @@ static inline bool iwl_is_tx_success(u32 status)
u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
/* scan */
+int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
void iwlagn_post_scan(struct iwl_priv *priv);
void iwlagn_disable_roc(struct iwl_priv *priv);
@@ -158,9 +156,8 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
/* bt coex */
void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
-int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd);
+void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv);
void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv);
void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv);
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c
index 0725603dbf1d..cea6520fafdb 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -125,12 +125,12 @@ int iwl_init_geos(struct iwl_priv *priv)
return 0;
}
- channels = kcalloc(priv->channel_count,
- sizeof(struct ieee80211_channel), GFP_KERNEL);
+ channels = kzalloc(sizeof(struct ieee80211_channel) *
+ priv->channel_count, GFP_KERNEL);
if (!channels)
return -ENOMEM;
- rates = kcalloc(IWL_RATE_COUNT_LEGACY, sizeof(struct ieee80211_rate),
+ rates = kzalloc((sizeof(struct ieee80211_rate) * IWL_RATE_COUNT_LEGACY),
GFP_KERNEL);
if (!rates) {
kfree(channels);
@@ -1123,9 +1123,8 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
&statistics_cmd);
}
-int iwl_mac_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
- const struct ieee80211_tx_queue_params *params)
+int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *params)
{
struct iwl_priv *priv = hw->priv;
struct iwl_rxon_context *ctx;
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h
index db50b650756c..6d7ad45c6d6f 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -108,6 +108,7 @@ struct iwl_lib_ops {
* radio tuning when there is a high receiving plcp error rate
* @chain_noise_scale: default chain noise scale used for gain computation
* @wd_timeout: TX queues watchdog timeout
+ * @temperature_kelvin: temperature report by uCode in kelvin
* @max_event_log_size: size of event log buffer size for ucode event logging
* @shadow_reg_enable: HW shadhow register bit
* @no_idle_support: do not support idle mode
@@ -129,6 +130,7 @@ struct iwl_base_params {
u8 plcp_delta_threshold;
s32 chain_noise_scale;
unsigned int wd_timeout;
+ bool temperature_kelvin;
u32 max_event_log_size;
const bool shadow_reg_enable;
const bool no_idle_support;
@@ -236,8 +238,7 @@ struct iwl_cfg {
* L i b *
***************************/
-int iwl_mac_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw);
void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
@@ -319,7 +320,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
******************************************************************************/
void iwl_init_scan_params(struct iwl_priv *priv);
int iwl_scan_cancel(struct iwl_priv *priv);
-void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
+int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
void iwl_force_scan_end(struct iwl_priv *priv);
int iwl_mac_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
@@ -329,6 +330,12 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external);
u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
const u8 *ta, const u8 *ie, int ie_len, int left);
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
+u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u8 n_probes);
+u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ struct ieee80211_vif *vif);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
void iwl_cancel_scan_deferred_work(struct iwl_priv *priv);
int __must_check iwl_scan_initiate(struct iwl_priv *priv,
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 6d49dfbee964..bf2a678970a9 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -715,20 +715,6 @@ static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
-static ssize_t iwl_dbgfs_temperature_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = file->private_data;
- char buf[8];
- int pos = 0;
- const size_t bufsz = sizeof(buf);
-
- pos += scnprintf(buf + pos, bufsz - pos, "%d\n", priv->temperature);
- return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
-}
-
-
static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
@@ -823,7 +809,6 @@ DEBUGFS_READ_WRITE_FILE_OPS(rx_handlers);
DEBUGFS_READ_FILE_OPS(qos);
DEBUGFS_READ_FILE_OPS(thermal_throttling);
DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
-DEBUGFS_READ_FILE_OPS(temperature);
DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
DEBUGFS_READ_FILE_OPS(current_sleep_command);
@@ -2551,7 +2536,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
- DEBUGFS_ADD_FILE(temperature, dir_data, S_IRUSR);
+ DEBUGFS_ADD_U32(temperature, dir_data, &priv->temperature, S_IRUSR);
DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR);
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h
index 257aa9a407ca..f69e556bd3c2 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -202,6 +202,11 @@ struct iwl_station_entry {
struct iwl_link_quality_cmd *lq;
};
+struct iwl_station_priv_common {
+ struct iwl_rxon_context *ctx;
+ u8 sta_id;
+};
+
/*
* iwl_station_priv: Driver's private station information
*
@@ -210,13 +215,12 @@ struct iwl_station_entry {
* space.
*/
struct iwl_station_priv {
- struct iwl_rxon_context *ctx;
+ struct iwl_station_priv_common common;
struct iwl_lq_sta lq_sta;
atomic_t pending_frames;
bool client;
bool asleep;
u8 max_agg_bufsize;
- u8 sta_id;
};
/**
@@ -841,9 +845,8 @@ struct iwl_priv {
void (*pre_rx_handler)(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
- int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd);
+ void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
@@ -877,7 +880,7 @@ struct iwl_priv {
u8 channel_count; /* # of channels */
/* thermal calibration */
- s32 temperature; /* Celsius */
+ s32 temperature; /* degrees Kelvin */
s32 last_temperature;
/* init calibration results */
@@ -1030,7 +1033,7 @@ struct iwl_priv {
struct delayed_work hw_roc_disable_work;
enum nl80211_channel_type hw_roc_chantype;
int hw_roc_duration;
- bool hw_roc_setup, hw_roc_start_notified;
+ bool hw_roc_setup;
/* bt coex */
u8 bt_enable_flag;
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index a4e43bd4a547..0b669417b0a6 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -899,9 +899,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
IWL_DEBUG_EEPROM(priv, "Parsing data for %d channels.\n",
priv->channel_count);
- priv->channel_info = kcalloc(priv->channel_count,
- sizeof(struct iwl_channel_info),
- GFP_KERNEL);
+ priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) *
+ priv->channel_count, GFP_KERNEL);
if (!priv->channel_info) {
IWL_ERR(priv, "Could not allocate channel_info\n");
priv->channel_count = 0;
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-led.c b/trunk/drivers/net/wireless/iwlwifi/iwl-led.c
index f149165e8010..7dffed186f0a 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -104,6 +104,7 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
.len = { sizeof(struct iwl_led_cmd), },
.data = { led_cmd, },
.flags = CMD_ASYNC,
+ .callback = NULL,
};
u32 reg;
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-rx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-rx.c
index bcd7f64683aa..2ee61031e207 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -130,9 +130,8 @@ const char *get_cmd_string(u8 cmd)
*
******************************************************************************/
-static int iwl_rx_reply_error(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_reply_error(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -143,11 +142,9 @@ static int iwl_rx_reply_error(struct iwl_priv *priv,
pkt->u.err_resp.cmd_id,
le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
le32_to_cpu(pkt->u.err_resp.error_info));
- return 0;
}
-static int iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
@@ -159,7 +156,7 @@ static int iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status))
- return 0;
+ return;
if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) {
rxon->channel = csa->channel;
@@ -172,13 +169,11 @@ static int iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
le16_to_cpu(csa->channel));
iwl_chswitch_done(priv, false);
}
- return 0;
}
-static int iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
@@ -186,17 +181,15 @@ static int iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
if (!report->state) {
IWL_DEBUG_11H(priv,
"Spectrum Measure Notification: Start\n");
- return 0;
+ return;
}
memcpy(&priv->measure_report, report, sizeof(*report));
priv->measurement_status |= MEASUREMENT_READY;
- return 0;
}
-static int iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -204,12 +197,10 @@ static int iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
sleep->pm_sleep_mode, sleep->pm_wakeup_src);
#endif
- return 0;
}
-static int iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
u32 __maybe_unused len =
@@ -218,12 +209,10 @@ static int iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
"notification for %s:\n", len,
get_cmd_string(pkt->hdr.cmd));
iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len);
- return 0;
}
-static int iwl_rx_beacon_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_beacon_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw;
@@ -244,7 +233,6 @@ static int iwl_rx_beacon_notif(struct iwl_priv *priv,
if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
queue_work(priv->shrd->workqueue, &priv->beacon_update);
- return 0;
}
/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
@@ -487,9 +475,8 @@ iwl_accumulative_statistics(struct iwl_priv *priv,
}
#endif
-static int iwl_rx_statistics(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_statistics(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
unsigned long stamp = jiffies;
const int reg_recalib_period = 60;
@@ -543,7 +530,7 @@ static int iwl_rx_statistics(struct iwl_priv *priv,
WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n",
len, sizeof(struct iwl_bt_notif_statistics),
sizeof(struct iwl_notif_statistics));
- return 0;
+ return;
}
change = common->temperature != priv->statistics.common.temperature ||
@@ -586,12 +573,10 @@ static int iwl_rx_statistics(struct iwl_priv *priv,
}
if (priv->cfg->lib->temperature && change)
priv->cfg->lib->temperature(priv);
- return 0;
}
-static int iwl_rx_reply_statistics(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_reply_statistics(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -606,15 +591,13 @@ static int iwl_rx_reply_statistics(struct iwl_priv *priv,
#endif
IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
}
- iwl_rx_statistics(priv, rxb, cmd);
- return 0;
+ iwl_rx_statistics(priv, rxb);
}
/* Handle notification from uCode that card's power state is changing
* due to software, hardware, or critical temperature RFKILL */
-static int iwl_rx_card_state_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_card_state_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
@@ -662,12 +645,10 @@ static int iwl_rx_card_state_notif(struct iwl_priv *priv,
test_bit(STATUS_RF_KILL_HW, &priv->shrd->status));
else
wake_up(&priv->shrd->wait_command_queue);
- return 0;
}
-static int iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -685,21 +666,18 @@ static int iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
if (!test_bit(STATUS_SCANNING, &priv->shrd->status))
iwl_init_sensitivity(priv);
}
- return 0;
}
/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
* This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
-static int iwl_rx_reply_rx_phy(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
priv->last_phy_res_valid = true;
memcpy(&priv->last_phy_res, pkt->u.raw,
sizeof(struct iwl_rx_phy_res));
- return 0;
}
/*
@@ -914,9 +892,8 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv,
/* Called for REPLY_RX (legacy ABG frames), or
* REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
-static int iwl_rx_reply_rx(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_reply_rx(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct ieee80211_hdr *header;
struct ieee80211_rx_status rx_status;
@@ -949,7 +926,7 @@ static int iwl_rx_reply_rx(struct iwl_priv *priv,
} else {
if (!priv->last_phy_res_valid) {
IWL_ERR(priv, "MPDU frame without cached PHY data\n");
- return 0;
+ return;
}
phy_res = &priv->last_phy_res;
amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw;
@@ -963,14 +940,14 @@ static int iwl_rx_reply_rx(struct iwl_priv *priv,
if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
phy_res->cfg_phy_cnt);
- return 0;
+ return;
}
if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
!(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
le32_to_cpu(rx_pkt_status));
- return 0;
+ return;
}
/* This will be used in several places later */
@@ -1031,7 +1008,6 @@ static int iwl_rx_reply_rx(struct iwl_priv *priv,
iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status,
rxb, &rx_status);
- return 0;
}
/**
@@ -1042,8 +1018,7 @@ static int iwl_rx_reply_rx(struct iwl_priv *priv,
*/
void iwl_setup_rx_handlers(struct iwl_priv *priv)
{
- int (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd);
+ void (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
handlers = priv->rx_handlers;
@@ -1053,7 +1028,6 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
handlers[PM_DEBUG_STATISTIC_NOTIFIC] = iwl_rx_pm_debug_statistics_notif;
handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif;
- handlers[REPLY_ADD_STA] = iwl_add_sta_callback;
/*
* The same handler is used for both the REPLY to a discrete
@@ -1091,11 +1065,9 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
}
-int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
- int err = 0;
/*
* Do the notification wait before RX handlers so
@@ -1130,12 +1102,11 @@ int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
* rx_handlers table. See iwl_setup_rx_handlers() */
if (priv->rx_handlers[pkt->hdr.cmd]) {
priv->rx_handlers_stats[pkt->hdr.cmd]++;
- err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
+ priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
} else {
/* No handling needed */
IWL_DEBUG_RX(priv,
"No handler needed for %s, 0x%02x\n",
get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
}
- return err;
}
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c b/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c
index c5c95d5319b1..fc5af3475392 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -114,65 +114,6 @@ static void iwl_complete_scan(struct iwl_priv *priv, bool aborted)
priv->scan_request = NULL;
}
-static void iwl_process_scan_complete(struct iwl_priv *priv)
-{
- bool aborted;
-
- lockdep_assert_held(&priv->shrd->mutex);
-
- if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status))
- return;
-
- IWL_DEBUG_SCAN(priv, "Completed scan.\n");
-
- cancel_delayed_work(&priv->scan_check);
-
- aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status);
- if (aborted)
- IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n");
-
- if (!test_and_clear_bit(STATUS_SCANNING, &priv->shrd->status)) {
- IWL_DEBUG_SCAN(priv, "Scan already completed.\n");
- goto out_settings;
- }
-
- if (priv->scan_type == IWL_SCAN_ROC) {
- ieee80211_remain_on_channel_expired(priv->hw);
- priv->hw_roc_channel = NULL;
- schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ);
- }
-
- if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) {
- int err;
-
- /* Check if mac80211 requested scan during our internal scan */
- if (priv->scan_request == NULL)
- goto out_complete;
-
- /* If so request a new scan */
- err = iwl_scan_initiate(priv, priv->scan_vif, IWL_SCAN_NORMAL,
- priv->scan_request->channels[0]->band);
- if (err) {
- IWL_DEBUG_SCAN(priv,
- "failed to initiate pending scan: %d\n", err);
- aborted = true;
- goto out_complete;
- }
-
- return;
- }
-
-out_complete:
- iwl_complete_scan(priv, aborted);
-
-out_settings:
- /* Can we still talk to firmware ? */
- if (!iwl_is_ready_rf(priv->shrd))
- return;
-
- iwlagn_post_scan(priv);
-}
-
void iwl_force_scan_end(struct iwl_priv *priv)
{
lockdep_assert_held(&priv->shrd->mutex);
@@ -186,7 +127,6 @@ void iwl_force_scan_end(struct iwl_priv *priv)
clear_bit(STATUS_SCANNING, &priv->shrd->status);
clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status);
- clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status);
iwl_complete_scan(priv, true);
}
@@ -229,7 +169,7 @@ int iwl_scan_cancel(struct iwl_priv *priv)
* @ms: amount of time to wait (in milliseconds) for scan to abort
*
*/
-void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
+int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
{
unsigned long timeout = jiffies + msecs_to_jiffies(ms);
@@ -241,30 +181,16 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
while (time_before_eq(jiffies, timeout)) {
if (!test_bit(STATUS_SCAN_HW, &priv->shrd->status))
- goto finished;
+ break;
msleep(20);
}
- return;
-
- finished:
- /*
- * Now STATUS_SCAN_HW is clear. This means that the
- * device finished, but the background work is going
- * to execute at best as soon as we release the mutex.
- * Since we need to be able to issue a new scan right
- * after this function returns, run the complete here.
- * The STATUS_SCAN_COMPLETE bit will then be cleared
- * and prevent the background work from "completing"
- * a possible new scan.
- */
- iwl_process_scan_complete(priv);
+ return test_bit(STATUS_SCAN_HW, &priv->shrd->status);
}
/* Service response to REPLY_SCAN_CMD (0x80) */
-static int iwl_rx_reply_scan(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_reply_scan(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -273,13 +199,11 @@ static int iwl_rx_reply_scan(struct iwl_priv *priv,
IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status);
#endif
- return 0;
}
/* Service SCAN_START_NOTIFICATION (0x82) */
-static int iwl_rx_scan_start_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_scanstart_notification *notif =
@@ -294,19 +218,13 @@ static int iwl_rx_scan_start_notif(struct iwl_priv *priv,
le32_to_cpu(notif->tsf_low),
notif->status, notif->beacon_timer);
- if (priv->scan_type == IWL_SCAN_ROC &&
- !priv->hw_roc_start_notified) {
+ if (priv->scan_type == IWL_SCAN_ROC)
ieee80211_ready_on_channel(priv->hw);
- priv->hw_roc_start_notified = true;
- }
-
- return 0;
}
/* Service SCAN_RESULTS_NOTIFICATION (0x83) */
-static int iwl_rx_scan_results_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -315,24 +233,20 @@ static int iwl_rx_scan_results_notif(struct iwl_priv *priv,
IWL_DEBUG_SCAN(priv, "Scan ch.res: "
"%d [802.11%s] "
- "probe status: %u:%u "
"(TSF: 0x%08X:%08X) - %d "
"elapsed=%lu usec\n",
notif->channel,
notif->band ? "bg" : "a",
- notif->probe_status, notif->num_probe_not_sent,
le32_to_cpu(notif->tsf_high),
le32_to_cpu(notif->tsf_low),
le32_to_cpu(notif->statistics[0]),
le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf);
#endif
- return 0;
}
/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
-static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
@@ -342,20 +256,13 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
scan_notif->tsf_low,
scan_notif->tsf_high, scan_notif->status);
+ /* The HW is no longer scanning */
+ clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
+
IWL_DEBUG_SCAN(priv, "Scan on %sGHz took %dms\n",
(priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2",
jiffies_to_msecs(jiffies - priv->scan_start));
- /*
- * When aborting, we run the scan completed background work inline
- * and the background work must then do nothing. The SCAN_COMPLETE
- * bit helps implement that logic and thus needs to be set before
- * queueing the work. Also, since the scan abort waits for SCAN_HW
- * to clear, we need to set SCAN_COMPLETE before clearing SCAN_HW
- * to avoid a race there.
- */
- set_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status);
- clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
queue_work(priv->shrd->workqueue, &priv->scan_completed);
if (priv->iw_mode != NL80211_IFTYPE_ADHOC &&
@@ -379,7 +286,6 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
queue_work(priv->shrd->workqueue,
&priv->bt_traffic_change_work);
}
- return 0;
}
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
@@ -393,8 +299,9 @@ void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
iwl_rx_scan_complete_notif;
}
-static u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band, u8 n_probes)
+inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u8 n_probes)
{
if (band == IEEE80211_BAND_5GHZ)
return IWL_ACTIVE_DWELL_TIME_52 +
@@ -404,481 +311,35 @@ static u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
}
-static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time)
+u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ struct ieee80211_vif *vif)
{
struct iwl_rxon_context *ctx;
-
- /*
- * If we're associated, we clamp the dwell time 98%
- * of the smallest beacon interval (minus 2 * channel
- * tune time)
- */
- for_each_context(priv, ctx) {
- u16 value;
-
- if (!iwl_is_associated_ctx(ctx))
- continue;
- value = ctx->beacon_int;
- if (!value)
- value = IWL_PASSIVE_DWELL_BASE;
- value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
- dwell_time = min(value, dwell_time);
- }
-
- return dwell_time;
-}
-
-static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band)
-{
u16 passive = (band == IEEE80211_BAND_2GHZ) ?
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
- return iwl_limit_dwell(priv, passive);
-}
-
-static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
- struct ieee80211_vif *vif,
- enum ieee80211_band band,
- struct iwl_scan_channel *scan_ch)
-{
- const struct ieee80211_supported_band *sband;
- u16 passive_dwell = 0;
- u16 active_dwell = 0;
- int added = 0;
- u16 channel = 0;
-
- sband = iwl_get_hw_mode(priv, band);
- if (!sband) {
- IWL_ERR(priv, "invalid band\n");
- return added;
- }
-
- active_dwell = iwl_get_active_dwell_time(priv, band, 0);
- passive_dwell = iwl_get_passive_dwell_time(priv, band);
-
- if (passive_dwell <= active_dwell)
- passive_dwell = active_dwell + 1;
-
- channel = iwl_get_single_channel_number(priv, band);
- if (channel) {
- scan_ch->channel = cpu_to_le16(channel);
- scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
- scan_ch->active_dwell = cpu_to_le16(active_dwell);
- scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
- /* Set txpower levels to defaults */
- scan_ch->dsp_atten = 110;
- if (band == IEEE80211_BAND_5GHZ)
- scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
- else
- scan_ch->tx_gain = ((1 << 5) | (5 << 3));
- added++;
- } else
- IWL_ERR(priv, "no valid channel found\n");
- return added;
-}
-
-static int iwl_get_channels_for_scan(struct iwl_priv *priv,
- struct ieee80211_vif *vif,
- enum ieee80211_band band,
- u8 is_active, u8 n_probes,
- struct iwl_scan_channel *scan_ch)
-{
- struct ieee80211_channel *chan;
- const struct ieee80211_supported_band *sband;
- const struct iwl_channel_info *ch_info;
- u16 passive_dwell = 0;
- u16 active_dwell = 0;
- int added, i;
- u16 channel;
-
- sband = iwl_get_hw_mode(priv, band);
- if (!sband)
- return 0;
-
- active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
- passive_dwell = iwl_get_passive_dwell_time(priv, band);
-
- if (passive_dwell <= active_dwell)
- passive_dwell = active_dwell + 1;
-
- for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
- chan = priv->scan_request->channels[i];
-
- if (chan->band != band)
- continue;
-
- channel = chan->hw_value;
- scan_ch->channel = cpu_to_le16(channel);
-
- ch_info = iwl_get_channel_info(priv, band, channel);
- if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN(priv,
- "Channel %d is INVALID for this band.\n",
- channel);
- continue;
- }
-
- if (!is_active || is_channel_passive(ch_info) ||
- (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
- scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
- else
- scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
-
- if (n_probes)
- scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
-
- scan_ch->active_dwell = cpu_to_le16(active_dwell);
- scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
-
- /* Set txpower levels to defaults */
- scan_ch->dsp_atten = 110;
-
- /* NOTE: if we were doing 6Mb OFDM for scans we'd use
- * power level:
- * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
- */
- if (band == IEEE80211_BAND_5GHZ)
- scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
- else
- scan_ch->tx_gain = ((1 << 5) | (5 << 3));
-
- IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n",
- channel, le32_to_cpu(scan_ch->type),
- (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
- "ACTIVE" : "PASSIVE",
- (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
- active_dwell : passive_dwell);
-
- scan_ch++;
- added++;
- }
-
- IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added);
- return added;
-}
-
-static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
-{
- struct iwl_host_cmd cmd = {
- .id = REPLY_SCAN_CMD,
- .len = { sizeof(struct iwl_scan_cmd), },
- .flags = CMD_SYNC,
- };
- struct iwl_scan_cmd *scan;
- struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
- u32 rate_flags = 0;
- u16 cmd_len;
- u16 rx_chain = 0;
- enum ieee80211_band band;
- u8 n_probes = 0;
- u8 rx_ant = hw_params(priv).valid_rx_ant;
- u8 rate;
- bool is_active = false;
- int chan_mod;
- u8 active_chains;
- u8 scan_tx_antennas = hw_params(priv).valid_tx_ant;
- int ret;
-
- lockdep_assert_held(&priv->shrd->mutex);
-
- if (vif)
- ctx = iwl_rxon_ctx_from_vif(vif);
-
- if (!priv->scan_cmd) {
- priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) +
- IWL_MAX_SCAN_SIZE, GFP_KERNEL);
- if (!priv->scan_cmd) {
- IWL_DEBUG_SCAN(priv,
- "fail to allocate memory for scan\n");
- return -ENOMEM;
- }
- }
- scan = priv->scan_cmd;
- memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
-
- scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
- scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
-
- if (priv->scan_type != IWL_SCAN_ROC &&
- iwl_is_any_associated(priv)) {
- u16 interval = 0;
- u32 extra;
- u32 suspend_time = 100;
- u32 scan_suspend_time = 100;
-
- IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
- switch (priv->scan_type) {
- case IWL_SCAN_ROC:
- WARN_ON(1);
- break;
- case IWL_SCAN_RADIO_RESET:
- interval = 0;
- break;
- case IWL_SCAN_NORMAL:
- interval = vif->bss_conf.beacon_int;
- break;
- }
-
- scan->suspend_time = 0;
- scan->max_out_time = cpu_to_le32(200 * 1024);
- if (!interval)
- interval = suspend_time;
-
- extra = (suspend_time / interval) << 22;
- scan_suspend_time = (extra |
- ((suspend_time % interval) * 1024));
- scan->suspend_time = cpu_to_le32(scan_suspend_time);
- IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
- scan_suspend_time, interval);
- } else if (priv->scan_type == IWL_SCAN_ROC) {
- scan->suspend_time = 0;
- scan->max_out_time = 0;
- scan->quiet_time = 0;
- scan->quiet_plcp_th = 0;
- }
-
- switch (priv->scan_type) {
- case IWL_SCAN_RADIO_RESET:
- IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
- break;
- case IWL_SCAN_NORMAL:
- if (priv->scan_request->n_ssids) {
- int i, p = 0;
- IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
- for (i = 0; i < priv->scan_request->n_ssids; i++) {
- /* always does wildcard anyway */
- if (!priv->scan_request->ssids[i].ssid_len)
- continue;
- scan->direct_scan[p].id = WLAN_EID_SSID;
- scan->direct_scan[p].len =
- priv->scan_request->ssids[i].ssid_len;
- memcpy(scan->direct_scan[p].ssid,
- priv->scan_request->ssids[i].ssid,
- priv->scan_request->ssids[i].ssid_len);
- n_probes++;
- p++;
- }
- is_active = true;
- } else
- IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
- break;
- case IWL_SCAN_ROC:
- IWL_DEBUG_SCAN(priv, "Start ROC scan.\n");
- break;
- }
-
- scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
- scan->tx_cmd.sta_id = ctx->bcast_sta_id;
- scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
-
- switch (priv->scan_band) {
- case IEEE80211_BAND_2GHZ:
- scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
- chan_mod = le32_to_cpu(
- priv->contexts[IWL_RXON_CTX_BSS].active.flags &
- RXON_FLG_CHANNEL_MODE_MSK)
- >> RXON_FLG_CHANNEL_MODE_POS;
- if (chan_mod == CHANNEL_MODE_PURE_40) {
- rate = IWL_RATE_6M_PLCP;
- } else {
- rate = IWL_RATE_1M_PLCP;
- rate_flags = RATE_MCS_CCK_MSK;
- }
+ if (iwl_is_any_associated(priv)) {
/*
- * Internal scans are passive, so we can indiscriminately set
- * the BT ignore flag on 2.4 GHz since it applies to TX only.
+ * If we're associated, we clamp the maximum passive
+ * dwell time to be 98% of the smallest beacon interval
+ * (minus 2 * channel tune time)
*/
- if (priv->cfg->bt_params &&
- priv->cfg->bt_params->advanced_bt_coexist)
- scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
- break;
- case IEEE80211_BAND_5GHZ:
- rate = IWL_RATE_6M_PLCP;
- break;
- default:
- IWL_WARN(priv, "Invalid scan band\n");
- return -EIO;
- }
-
- /*
- * If active scanning is requested but a certain channel is
- * marked passive, we can do active scanning if we detect
- * transmissions.
- *
- * There is an issue with some firmware versions that triggers
- * a sysassert on a "good CRC threshold" of zero (== disabled),
- * on a radar channel even though this means that we should NOT
- * send probes.
- *
- * The "good CRC threshold" is the number of frames that we
- * need to receive during our dwell time on a channel before
- * sending out probes -- setting this to a huge value will
- * mean we never reach it, but at the same time work around
- * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
- * here instead of IWL_GOOD_CRC_TH_DISABLED.
- *
- * This was fixed in later versions along with some other
- * scan changes, and the threshold behaves as a flag in those
- * versions.
- */
- if (priv->new_scan_threshold_behaviour)
- scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
- IWL_GOOD_CRC_TH_DISABLED;
- else
- scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
- IWL_GOOD_CRC_TH_NEVER;
-
- band = priv->scan_band;
-
- if (priv->cfg->scan_rx_antennas[band])
- rx_ant = priv->cfg->scan_rx_antennas[band];
-
- if (band == IEEE80211_BAND_2GHZ &&
- priv->cfg->bt_params &&
- priv->cfg->bt_params->advanced_bt_coexist) {
- /* transmit 2.4 GHz probes only on first antenna */
- scan_tx_antennas = first_antenna(scan_tx_antennas);
- }
-
- priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv,
- priv->scan_tx_ant[band],
- scan_tx_antennas);
- rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
- scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
-
- /* In power save mode use one chain, otherwise use all chains */
- if (test_bit(STATUS_POWER_PMI, &priv->shrd->status)) {
- /* rx_ant has been set to all valid chains previously */
- active_chains = rx_ant &
- ((u8)(priv->chain_noise_data.active_chains));
- if (!active_chains)
- active_chains = rx_ant;
-
- IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n",
- priv->chain_noise_data.active_chains);
-
- rx_ant = first_antenna(active_chains);
- }
- if (priv->cfg->bt_params &&
- priv->cfg->bt_params->advanced_bt_coexist &&
- priv->bt_full_concurrent) {
- /* operated as 1x1 in full concurrency mode */
- rx_ant = first_antenna(rx_ant);
- }
-
- /* MIMO is not used here, but value is required */
- rx_chain |=
- hw_params(priv).valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
- rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
- rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
- rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
- scan->rx_chain = cpu_to_le16(rx_chain);
- switch (priv->scan_type) {
- case IWL_SCAN_NORMAL:
- cmd_len = iwl_fill_probe_req(priv,
- (struct ieee80211_mgmt *)scan->data,
- vif->addr,
- priv->scan_request->ie,
- priv->scan_request->ie_len,
- IWL_MAX_SCAN_SIZE - sizeof(*scan));
- break;
- case IWL_SCAN_RADIO_RESET:
- case IWL_SCAN_ROC:
- /* use bcast addr, will not be transmitted but must be valid */
- cmd_len = iwl_fill_probe_req(priv,
- (struct ieee80211_mgmt *)scan->data,
- iwl_bcast_addr, NULL, 0,
- IWL_MAX_SCAN_SIZE - sizeof(*scan));
- break;
- default:
- BUG();
- }
- scan->tx_cmd.len = cpu_to_le16(cmd_len);
-
- scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
- RXON_FILTER_BCON_AWARE_MSK);
-
- switch (priv->scan_type) {
- case IWL_SCAN_RADIO_RESET:
- scan->channel_count =
- iwl_get_single_channel_for_scan(priv, vif, band,
- (void *)&scan->data[cmd_len]);
- break;
- case IWL_SCAN_NORMAL:
- scan->channel_count =
- iwl_get_channels_for_scan(priv, vif, band,
- is_active, n_probes,
- (void *)&scan->data[cmd_len]);
- break;
- case IWL_SCAN_ROC: {
- struct iwl_scan_channel *scan_ch;
- int n_chan, i;
- u16 dwell;
-
- dwell = iwl_limit_dwell(priv, priv->hw_roc_duration);
- n_chan = DIV_ROUND_UP(priv->hw_roc_duration, dwell);
-
- scan->channel_count = n_chan;
-
- scan_ch = (void *)&scan->data[cmd_len];
-
- for (i = 0; i < n_chan; i++) {
- scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
- scan_ch->channel =
- cpu_to_le16(priv->hw_roc_channel->hw_value);
-
- if (i == n_chan - 1)
- dwell = priv->hw_roc_duration - i * dwell;
-
- scan_ch->active_dwell =
- scan_ch->passive_dwell = cpu_to_le16(dwell);
-
- /* Set txpower levels to defaults */
- scan_ch->dsp_atten = 110;
-
- /* NOTE: if we were doing 6Mb OFDM for scans we'd use
- * power level:
- * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
- */
- if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ)
- scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
- else
- scan_ch->tx_gain = ((1 << 5) | (5 << 3));
-
- scan_ch++;
- }
+ for_each_context(priv, ctx) {
+ u16 value;
+
+ if (!iwl_is_associated_ctx(ctx))
+ continue;
+ value = ctx->vif ? ctx->vif->bss_conf.beacon_int : 0;
+ if ((value > IWL_PASSIVE_DWELL_BASE) || !value)
+ value = IWL_PASSIVE_DWELL_BASE;
+ value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
+ passive = min(value, passive);
}
-
- break;
- }
-
- if (scan->channel_count == 0) {
- IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
- return -EIO;
- }
-
- cmd.len[0] += le16_to_cpu(scan->tx_cmd.len) +
- scan->channel_count * sizeof(struct iwl_scan_channel);
- cmd.data[0] = scan;
- cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
- scan->len = cpu_to_le16(cmd.len[0]);
-
- /* set scan bit here for PAN params */
- set_bit(STATUS_SCAN_HW, &priv->shrd->status);
-
- ret = iwlagn_set_pan_params(priv);
- if (ret)
- return ret;
-
- ret = iwl_trans_send_cmd(trans(priv), &cmd);
- if (ret) {
- clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
- iwlagn_set_pan_params(priv);
}
- return ret;
+ return passive;
}
void iwl_init_scan_params(struct iwl_priv *priv)
@@ -954,33 +415,31 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
mutex_lock(&priv->shrd->mutex);
+ if (test_bit(STATUS_SCANNING, &priv->shrd->status) &&
+ priv->scan_type != IWL_SCAN_NORMAL) {
+ IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
+ ret = -EAGAIN;
+ goto out_unlock;
+ }
+
+ /* mac80211 will only ask for one band at a time */
+ priv->scan_request = req;
+ priv->scan_vif = vif;
+
/*
* If an internal scan is in progress, just set
* up the scan_request as per above.
*/
if (priv->scan_type != IWL_SCAN_NORMAL) {
- IWL_DEBUG_SCAN(priv,
- "SCAN request during internal scan - defer\n");
- priv->scan_request = req;
- priv->scan_vif = vif;
+ IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n");
ret = 0;
- } else {
- priv->scan_request = req;
- priv->scan_vif = vif;
- /*
- * mac80211 will only ask for one band at a time
- * so using channels[0] here is ok
- */
+ } else
ret = iwl_scan_initiate(priv, vif, IWL_SCAN_NORMAL,
req->channels[0]->band);
- if (ret) {
- priv->scan_request = NULL;
- priv->scan_vif = NULL;
- }
- }
IWL_DEBUG_MAC80211(priv, "leave\n");
+out_unlock:
mutex_unlock(&priv->shrd->mutex);
return ret;
@@ -1098,10 +557,61 @@ static void iwl_bg_abort_scan(struct work_struct *work)
static void iwl_bg_scan_completed(struct work_struct *work)
{
struct iwl_priv *priv =
- container_of(work, struct iwl_priv, scan_completed);
+ container_of(work, struct iwl_priv, scan_completed);
+ bool aborted;
+
+ IWL_DEBUG_SCAN(priv, "Completed scan.\n");
+
+ cancel_delayed_work(&priv->scan_check);
mutex_lock(&priv->shrd->mutex);
- iwl_process_scan_complete(priv);
+
+ aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status);
+ if (aborted)
+ IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n");
+
+ if (!test_and_clear_bit(STATUS_SCANNING, &priv->shrd->status)) {
+ IWL_DEBUG_SCAN(priv, "Scan already completed.\n");
+ goto out_settings;
+ }
+
+ if (priv->scan_type == IWL_SCAN_ROC) {
+ ieee80211_remain_on_channel_expired(priv->hw);
+ priv->hw_roc_channel = NULL;
+ schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ);
+ }
+
+ if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) {
+ int err;
+
+ /* Check if mac80211 requested scan during our internal scan */
+ if (priv->scan_request == NULL)
+ goto out_complete;
+
+ /* If so request a new scan */
+ err = iwl_scan_initiate(priv, priv->scan_vif, IWL_SCAN_NORMAL,
+ priv->scan_request->channels[0]->band);
+ if (err) {
+ IWL_DEBUG_SCAN(priv,
+ "failed to initiate pending scan: %d\n", err);
+ aborted = true;
+ goto out_complete;
+ }
+
+ goto out;
+ }
+
+out_complete:
+ iwl_complete_scan(priv, aborted);
+
+out_settings:
+ /* Can we still talk to firmware ? */
+ if (!iwl_is_ready_rf(priv->shrd))
+ goto out;
+
+ iwlagn_post_scan(priv);
+
+out:
mutex_unlock(&priv->shrd->mutex);
}
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-shared.h b/trunk/drivers/net/wireless/iwlwifi/iwl-shared.h
index 3a24b477b8fb..40186a61f20a 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-shared.h
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-shared.h
@@ -100,7 +100,7 @@ struct iwl_priv;
struct iwl_sensitivity_ranges;
struct iwl_trans_ops;
-#define DRV_NAME "iwlwifi"
+#define DRV_NAME "iwlagn"
#define IWLWIFI_VERSION "in-tree:"
#define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation"
#define DRV_AUTHOR ""
@@ -423,11 +423,8 @@ enum iwl_rxon_context_id {
int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
struct iwl_cfg *cfg);
void __devexit iwl_remove(struct iwl_priv * priv);
-struct iwl_device_cmd;
-int __must_check iwl_rx_dispatch(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd);
+void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
int iwlagn_hw_valid_rtc_data_addr(u32 addr);
void iwl_start_tx_ba_trans_ready(struct iwl_priv *priv,
enum iwl_rxon_context_id ctx,
@@ -489,7 +486,6 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv,
#define STATUS_FW_ERROR 17
#define STATUS_DEVICE_ENABLED 18
#define STATUS_CHANNEL_SWITCH_PENDING 19
-#define STATUS_SCAN_COMPLETE 20
static inline int iwl_is_ready(struct iwl_shared *shrd)
{
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-sta.c b/trunk/drivers/net/wireless/iwlwifi/iwl-sta.c
index 580a4d702ff3..e24135e7d37d 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -59,7 +59,8 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
static int iwl_process_add_sta_resp(struct iwl_priv *priv,
struct iwl_addsta_cmd *addsta,
- struct iwl_rx_packet *pkt)
+ struct iwl_rx_packet *pkt,
+ bool sync)
{
u8 sta_id = addsta->sta.sta_id;
unsigned long flags;
@@ -122,14 +123,15 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
return ret;
}
-int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd)
+static void iwl_add_sta_callback(struct iwl_shared *shrd,
+ struct iwl_device_cmd *cmd,
+ struct iwl_rx_packet *pkt)
{
- struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_addsta_cmd *addsta =
- (struct iwl_addsta_cmd *) cmd->payload;
+ (struct iwl_addsta_cmd *)cmd->cmd.payload;
+
+ iwl_process_add_sta_resp(shrd->priv, addsta, pkt, false);
- return iwl_process_add_sta_resp(priv, addsta, pkt);
}
static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
@@ -145,6 +147,7 @@ static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
int iwl_send_add_sta(struct iwl_priv *priv,
struct iwl_addsta_cmd *sta, u8 flags)
{
+ struct iwl_rx_packet *pkt = NULL;
int ret = 0;
u8 data[sizeof(*sta)];
struct iwl_host_cmd cmd = {
@@ -157,7 +160,9 @@ int iwl_send_add_sta(struct iwl_priv *priv,
IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n",
sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : "");
- if (!(flags & CMD_ASYNC)) {
+ if (flags & CMD_ASYNC)
+ cmd.callback = iwl_add_sta_callback;
+ else {
cmd.flags |= CMD_WANT_SKB;
might_sleep();
}
@@ -167,16 +172,14 @@ int iwl_send_add_sta(struct iwl_priv *priv,
if (ret || (flags & CMD_ASYNC))
return ret;
- /*else the command was successfully sent in SYNC mode, need to free
- * the reply page */
+ if (ret == 0) {
+ pkt = (struct iwl_rx_packet *)cmd.reply_page;
+ ret = iwl_process_add_sta_resp(priv, sta, pkt, true);
+ }
iwl_free_pages(priv->shrd, cmd.reply_page);
- if (cmd.handler_status)
- IWL_ERR(priv, "%s - error in the CMD response %d", __func__,
- cmd.handler_status);
-
- return cmd.handler_status;
+ return ret;
}
static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
@@ -302,7 +305,7 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
station->ctxid = ctx->ctxid;
if (sta) {
- struct iwl_station_priv *sta_priv;
+ struct iwl_station_priv_common *sta_priv;
sta_priv = (void *)sta->drv_priv;
sta_priv->ctx = ctx;
@@ -818,7 +821,7 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw,
struct ieee80211_sta *sta)
{
struct iwl_priv *priv = hw->priv;
- struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_station_priv_common *sta_common = (void *)sta->drv_priv;
int ret;
IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
@@ -826,7 +829,7 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw,
mutex_lock(&priv->shrd->mutex);
IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n",
sta->addr);
- ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr);
+ ret = iwl_remove_station(priv, sta_common->sta_id, sta->addr);
if (ret)
IWL_ERR(priv, "Error removing station %pM\n",
sta->addr);
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-sta.h b/trunk/drivers/net/wireless/iwlwifi/iwl-sta.h
index 1bca0dabde8d..9641eb6b1d0a 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -61,9 +61,6 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct iwl_link_quality_cmd *lq, u8 flags, bool init);
void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
-int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
- struct iwl_device_cmd *cmd);
-
/**
* iwl_clear_driver_stations - clear knowledge of all stations from driver
@@ -105,7 +102,7 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta)
if (WARN_ON(!sta))
return IWL_INVALID_STATION;
- return ((struct iwl_station_priv *)sta->drv_priv)->sta_id;
+ return ((struct iwl_station_priv_common *)sta->drv_priv)->sta_id;
}
/**
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
index 2b6756e8b8f9..49cd5a768280 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
@@ -118,6 +118,16 @@ struct iwl_dma_ptr {
struct iwl_cmd_meta {
/* only for SYNC commands, iff the reply skb is wanted */
struct iwl_host_cmd *source;
+ /*
+ * only for ASYNC commands
+ * (which is somewhat stupid -- look at iwl-sta.c for instance
+ * which duplicates a bunch of code because the callback isn't
+ * invoked for SYNC commands, if it were and its result passed
+ * through it would be simpler...)
+ */
+ void (*callback)(struct iwl_shared *shrd,
+ struct iwl_device_cmd *cmd,
+ struct iwl_rx_packet *pkt);
u32 flags;
@@ -275,8 +285,10 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans,
dma_addr_t addr, u16 len, u8 reset);
int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id);
int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
+int __must_check iwl_trans_pcie_send_cmd_pdu(struct iwl_trans *trans, u8 id,
+ u32 flags, u16 len, const void *data);
void iwl_tx_cmd_complete(struct iwl_trans *trans,
- struct iwl_rx_mem_buffer *rxb, int handler_status);
+ struct iwl_rx_mem_buffer *rxb);
void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
struct iwl_tx_queue *txq,
u16 byte_cnt);
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
index b4eff556cd0a..6f3f07dd817d 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
@@ -372,15 +372,12 @@ static void iwl_rx_handle(struct iwl_trans *trans)
struct iwl_trans_pcie *trans_pcie =
IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_rx_queue *rxq = &trans_pcie->rxq;
- struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue];
- struct iwl_device_cmd *cmd;
u32 r, i;
int reclaim;
unsigned long flags;
u8 fill_rx = 0;
u32 count = 8;
int total_empty;
- int index, cmd_index;
/* uCode's read index (stored in shared DRAM) indicates the last Rx
* buffer that the driver may process (last buffer filled by ucode). */
@@ -400,8 +397,8 @@ static void iwl_rx_handle(struct iwl_trans *trans)
fill_rx = 1;
while (i != r) {
- int len, err;
- u16 sequence;
+ int len;
+ u16 txq_id, sequence;
rxb = rxq->queue[i];
@@ -442,26 +439,17 @@ static void iwl_rx_handle(struct iwl_trans *trans)
(pkt->hdr.cmd != REPLY_TX);
sequence = le16_to_cpu(pkt->hdr.sequence);
- index = SEQ_TO_INDEX(sequence);
- cmd_index = get_cmd_index(&txq->q, index);
-
- if (reclaim)
- cmd = txq->cmd[cmd_index];
- else
- cmd = NULL;
+ txq_id = SEQ_TO_QUEUE(le16_to_cpu(pkt->hdr.sequence));
/* warn if this is cmd response / notification and the uCode
* didn't set the SEQ_RX_FRAME for a frame that is
- * uCode-originated
- * If you saw this code after the second half of 2012, then
- * please remove it
- */
- WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false &&
+ * uCode-originated*/
+ WARN(txq_id == trans->shrd->cmd_queue && reclaim == false &&
(!(pkt->hdr.sequence & SEQ_RX_FRAME)),
"reclaim is false, SEQ_RX_FRAME unset: %s\n",
get_cmd_string(pkt->hdr.cmd));
- err = iwl_rx_dispatch(priv(trans), rxb, cmd);
+ iwl_rx_dispatch(priv(trans), rxb);
/*
* XXX: After here, we should always check rxb->page
@@ -476,7 +464,7 @@ static void iwl_rx_handle(struct iwl_trans *trans)
* iwl_trans_send_cmd()
* as we reclaim the driver command queue */
if (rxb->page)
- iwl_tx_cmd_complete(trans, rxb, err);
+ iwl_tx_cmd_complete(trans, rxb);
else
IWL_WARN(trans, "Claim null rxb?\n");
}
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
index ee7059dcbbcb..031a291a13dc 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
@@ -59,15 +59,13 @@ void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
u8 sta_id = 0;
u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
__le16 bc_ent;
- struct iwl_tx_cmd *tx_cmd =
- (struct iwl_tx_cmd *) txq->cmd[txq->q.write_ptr]->payload;
scd_bc_tbl = trans_pcie->scd_bc_tbls.addr;
WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
- sta_id = tx_cmd->sta_id;
- sec_ctl = tx_cmd->sec_ctl;
+ sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
+ sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
switch (sec_ctl & TX_CMD_SEC_MSK) {
case TX_CMD_SEC_CCM:
@@ -355,13 +353,11 @@ static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans,
int read_ptr = txq->q.read_ptr;
u8 sta_id = 0;
__le16 bc_ent;
- struct iwl_tx_cmd *tx_cmd =
- (struct iwl_tx_cmd *) txq->cmd[txq->q.read_ptr]->payload;
WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
if (txq_id != trans->shrd->cmd_queue)
- sta_id = tx_cmd->sta_id;
+ sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
bc_ent = cpu_to_le16(1 | (sta_id << 12));
scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
@@ -766,6 +762,8 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */
if (cmd->flags & CMD_WANT_SKB)
out_meta->source = cmd;
+ if (cmd->flags & CMD_ASYNC)
+ out_meta->callback = cmd->callback;
/* set up the header */
@@ -777,7 +775,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
/* and copy the data that needs to be copied */
- cmd_dest = out_cmd->payload;
+ cmd_dest = &out_cmd->cmd.payload[0];
for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
if (!cmd->len[i])
continue;
@@ -896,15 +894,12 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id,
/**
* iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
* @rxb: Rx buffer to reclaim
- * @handler_status: return value of the handler of the command
- * (put in setup_rx_handlers)
*
* If an Rx buffer has an async callback associated with it the callback
* will be executed. The attached skb (if present) will only be freed
* if the callback returns 1
*/
-void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
- int handler_status)
+void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
@@ -941,9 +936,9 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
/* Input error checking is done when commands are added to queue. */
if (meta->flags & CMD_WANT_SKB) {
meta->source->reply_page = (unsigned long)rxb_addr(rxb);
- meta->source->handler_status = handler_status;
rxb->page = NULL;
- }
+ } else if (meta->callback)
+ meta->callback(trans->shrd, cmd, pkt);
spin_lock_irqsave(&trans->hcmd_lock, flags);
@@ -963,6 +958,30 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
#define HOST_COMPLETE_TIMEOUT (2 * HZ)
+static void iwl_generic_cmd_callback(struct iwl_shared *shrd,
+ struct iwl_device_cmd *cmd,
+ struct iwl_rx_packet *pkt)
+{
+ if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
+ IWL_ERR(shrd->trans, "Bad return from %s (0x%08X)\n",
+ get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
+ return;
+ }
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ switch (cmd->hdr.cmd) {
+ case REPLY_TX_LINK_QUALITY_CMD:
+ case SENSITIVITY_CMD:
+ IWL_DEBUG_HC_DUMP(shrd->trans, "back from %s (0x%08X)\n",
+ get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
+ break;
+ default:
+ IWL_DEBUG_HC(shrd->trans, "back from %s (0x%08X)\n",
+ get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
+ }
+#endif
+}
+
static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
{
int ret;
@@ -971,6 +990,9 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
if (WARN_ON(cmd->flags & CMD_WANT_SKB))
return -EINVAL;
+ /* Assign a generic callback if one is not provided */
+ if (!cmd->callback)
+ cmd->callback = iwl_generic_cmd_callback;
if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status))
return -EBUSY;
@@ -992,6 +1014,10 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
lockdep_assert_held(&trans->shrd->mutex);
+ /* A synchronous command can not have a callback set. */
+ if (WARN_ON(cmd->callback))
+ return -EINVAL;
+
IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n",
get_cmd_string(cmd->id));
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index 416e9920e4d9..ca13eebbdb4f 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -83,6 +83,8 @@ static int iwl_trans_rx_alloc(struct iwl_trans *trans)
memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq));
spin_lock_init(&rxq->lock);
+ INIT_LIST_HEAD(&rxq->rx_free);
+ INIT_LIST_HEAD(&rxq->rx_used);
if (WARN_ON(rxq->bd || rxq->rb_stts))
return -EINVAL;
@@ -304,8 +306,8 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans,
txq->q.n_window = slots_num;
- txq->meta = kcalloc(slots_num, sizeof(txq->meta[0]), GFP_KERNEL);
- txq->cmd = kcalloc(slots_num, sizeof(txq->cmd[0]), GFP_KERNEL);
+ txq->meta = kzalloc(sizeof(txq->meta[0]) * slots_num, GFP_KERNEL);
+ txq->cmd = kzalloc(sizeof(txq->cmd[0]) * slots_num, GFP_KERNEL);
if (!txq->meta || !txq->cmd)
goto error;
@@ -322,8 +324,8 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans,
/* Driver private data, only for Tx (not command) queues,
* not shared with device. */
if (txq_id != trans->shrd->cmd_queue) {
- txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->skbs[0]),
- GFP_KERNEL);
+ txq->skbs = kzalloc(sizeof(txq->skbs[0]) *
+ TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
if (!txq->skbs) {
IWL_ERR(trans, "kmalloc for auxiliary BD "
"structures failed\n");
@@ -534,8 +536,8 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans)
goto error;
}
- trans_pcie->txq = kcalloc(hw_params(trans).max_txq_num,
- sizeof(struct iwl_tx_queue), GFP_KERNEL);
+ trans_pcie->txq = kzalloc(sizeof(struct iwl_tx_queue) *
+ hw_params(trans).max_txq_num, GFP_KERNEL);
if (!trans_pcie->txq) {
IWL_ERR(trans, "Not enough memory for txq\n");
ret = ENOMEM;
@@ -1041,7 +1043,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct iwl_tx_cmd *tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload;
+ struct iwl_tx_cmd *tx_cmd = &dev_cmd->cmd.tx;
struct iwl_cmd_meta *out_meta;
struct iwl_tx_queue *txq;
struct iwl_queue *q;
@@ -1094,16 +1096,13 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
hdr->seq_ctrl |= cpu_to_le16(seq_number);
seq_number += 0x10;
/* aggregation is on for this */
- if (info->flags & IEEE80211_TX_CTL_AMPDU) {
- WARN_ON(tid_data->agg.state != IWL_AGG_ON);
+ if (info->flags & IEEE80211_TX_CTL_AMPDU &&
+ tid_data->agg.state == IWL_AGG_ON) {
txq_id = tid_data->agg.txq_id;
is_agg = true;
}
}
- /* Copy MAC header from skb into command buffer */
- memcpy(tx_cmd->hdr, hdr, hdr_len);
-
txq = &trans_pcie->txq[txq_id];
q = &txq->q;
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h b/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h
index c5923125c3f9..5b6e6842d5fc 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -97,7 +97,15 @@ enum {
*/
struct iwl_device_cmd {
struct iwl_cmd_header hdr; /* uCode API */
- u8 payload[DEF_CMD_PAYLOAD_SIZE];
+ union {
+ u32 flags;
+ u8 val8;
+ u16 val16;
+ u32 val32;
+ struct iwl_tx_cmd tx;
+ struct iwl6000_channel_switch_cmd chswitch;
+ u8 payload[DEF_CMD_PAYLOAD_SIZE];
+ } __packed cmd;
} __packed;
#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
@@ -112,8 +120,6 @@ enum iwl_hcmd_dataflag {
* struct iwl_host_cmd - Host command to the uCode
* @data: array of chunks that composes the data of the host command
* @reply_page: pointer to the page that holds the response to the host command
- * @handler_status: return value of the handler of the command
- * (put in setup_rx_handlers) - valid for SYNC mode only
* @callback:
* @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC
* @len: array of the lenths of the chunks in data
@@ -123,8 +129,9 @@ enum iwl_hcmd_dataflag {
struct iwl_host_cmd {
const void *data[IWL_MAX_CMD_TFDS];
unsigned long reply_page;
- int handler_status;
-
+ void (*callback)(struct iwl_shared *shrd,
+ struct iwl_device_cmd *cmd,
+ struct iwl_rx_packet *pkt);
u32 flags;
u16 len[IWL_MAX_CMD_TFDS];
u8 dataflags[IWL_MAX_CMD_TFDS];
diff --git a/trunk/drivers/net/wireless/libertas/cfg.c b/trunk/drivers/net/wireless/libertas/cfg.c
index 610bfcee3cf6..85b3169c40d7 100644
--- a/trunk/drivers/net/wireless/libertas/cfg.c
+++ b/trunk/drivers/net/wireless/libertas/cfg.c
@@ -695,7 +695,7 @@ static void lbs_scan_worker(struct work_struct *work)
tlv = scan_cmd->tlvbuffer;
/* add SSID TLV */
- if (priv->scan_req->n_ssids && priv->scan_req->ssids[0].ssid_len > 0)
+ if (priv->scan_req->n_ssids)
tlv += lbs_add_ssid_tlv(tlv,
priv->scan_req->ssids[0].ssid,
priv->scan_req->ssids[0].ssid_len);
@@ -736,6 +736,7 @@ static void lbs_scan_worker(struct work_struct *work)
cfg80211_scan_done(priv->scan_req, false);
priv->scan_req = NULL;
+ priv->last_scan = jiffies;
}
/* Restart network */
@@ -1301,26 +1302,24 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
lbs_deb_enter(LBS_DEB_CFG80211);
if (!sme->bssid) {
- struct cfg80211_scan_request *creq;
-
- /*
- * Scan for the requested network after waiting for existing
- * scans to finish.
+ /* Run a scan if one isn't in-progress already and if the last
+ * scan was done more than 2 seconds ago.
*/
- lbs_deb_assoc("assoc: waiting for existing scans\n");
- wait_event_interruptible_timeout(priv->scan_q,
- (priv->scan_req == NULL),
- (15 * HZ));
+ if (priv->scan_req == NULL &&
+ time_after(jiffies, priv->last_scan + (2 * HZ))) {
+ struct cfg80211_scan_request *creq;
- creq = _new_connect_scan_req(wiphy, sme);
- if (!creq) {
- ret = -EINVAL;
- goto done;
- }
+ creq = _new_connect_scan_req(wiphy, sme);
+ if (!creq) {
+ ret = -EINVAL;
+ goto done;
+ }
- lbs_deb_assoc("assoc: scanning for compatible AP\n");
- _internal_start_scan(priv, true, creq);
+ lbs_deb_assoc("assoc: scanning for compatible AP\n");
+ _internal_start_scan(priv, true, creq);
+ }
+ /* Wait for any in-progress scan to complete */
lbs_deb_assoc("assoc: waiting for scan to complete\n");
wait_event_interruptible_timeout(priv->scan_q,
(priv->scan_req == NULL),
diff --git a/trunk/drivers/net/wireless/libertas/dev.h b/trunk/drivers/net/wireless/libertas/dev.h
index f3fd447131c2..b9ff0dc53e8d 100644
--- a/trunk/drivers/net/wireless/libertas/dev.h
+++ b/trunk/drivers/net/wireless/libertas/dev.h
@@ -158,7 +158,6 @@ struct lbs_private {
/* protected by hard_start_xmit serialization */
u8 txretrycount;
struct sk_buff *currenttxskb;
- struct timer_list tx_lockup_timer;
/* Locks */
struct mutex lock;
@@ -180,6 +179,7 @@ struct lbs_private {
wait_queue_head_t scan_q;
/* Whether the scan was initiated internally and not by cfg80211 */
bool internal_scan;
+ unsigned long last_scan;
};
extern struct cmd_confirm_sleep confirm_sleep;
diff --git a/trunk/drivers/net/wireless/libertas/main.c b/trunk/drivers/net/wireless/libertas/main.c
index 6a326233391f..d62d1fb4177f 100644
--- a/trunk/drivers/net/wireless/libertas/main.c
+++ b/trunk/drivers/net/wireless/libertas/main.c
@@ -188,7 +188,6 @@ int lbs_stop_iface(struct lbs_private *priv)
spin_unlock_irqrestore(&priv->driver_lock, flags);
cancel_work_sync(&priv->mcast_work);
- del_timer_sync(&priv->tx_lockup_timer);
/* Disable command processing, and wait for all commands to complete */
lbs_deb_main("waiting for commands to complete\n");
@@ -244,7 +243,6 @@ void lbs_host_to_card_done(struct lbs_private *priv)
lbs_deb_enter(LBS_DEB_THREAD);
spin_lock_irqsave(&priv->driver_lock, flags);
- del_timer(&priv->tx_lockup_timer);
priv->dnld_sent = DNLD_RES_RECEIVED;
@@ -587,9 +585,6 @@ static int lbs_thread(void *data)
if (ret) {
lbs_deb_tx("host_to_card failed %d\n", ret);
priv->dnld_sent = DNLD_RES_RECEIVED;
- } else {
- mod_timer(&priv->tx_lockup_timer,
- jiffies + (HZ * 5));
}
priv->tx_pending_len = 0;
if (!priv->currenttxskb) {
@@ -606,7 +601,6 @@ static int lbs_thread(void *data)
}
del_timer(&priv->command_timer);
- del_timer(&priv->tx_lockup_timer);
del_timer(&priv->auto_deepsleep_timer);
lbs_deb_leave(LBS_DEB_THREAD);
@@ -740,32 +734,6 @@ static void lbs_cmd_timeout_handler(unsigned long data)
lbs_deb_leave(LBS_DEB_CMD);
}
-/**
- * lbs_tx_lockup_handler - handles the timeout of the passing of TX frames
- * to the hardware. This is known to frequently happen with SD8686 when
- * waking up after a Wake-on-WLAN-triggered resume.
- *
- * @data: &struct lbs_private pointer
- */
-static void lbs_tx_lockup_handler(unsigned long data)
-{
- struct lbs_private *priv = (struct lbs_private *)data;
- unsigned long flags;
-
- lbs_deb_enter(LBS_DEB_TX);
- spin_lock_irqsave(&priv->driver_lock, flags);
-
- netdev_info(priv->dev, "TX lockup detected\n");
- if (priv->reset_card)
- priv->reset_card(priv);
-
- priv->dnld_sent = DNLD_RES_RECEIVED;
- wake_up_interruptible(&priv->waitq);
-
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- lbs_deb_leave(LBS_DEB_TX);
-}
-
/**
* auto_deepsleep_timer_fn - put the device back to deep sleep mode when
* timer expires and no activity (command, event, data etc.) is detected.
@@ -852,8 +820,6 @@ static int lbs_init_adapter(struct lbs_private *priv)
setup_timer(&priv->command_timer, lbs_cmd_timeout_handler,
(unsigned long)priv);
- setup_timer(&priv->tx_lockup_timer, lbs_tx_lockup_handler,
- (unsigned long)priv);
setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn,
(unsigned long)priv);
@@ -891,7 +857,6 @@ static void lbs_free_adapter(struct lbs_private *priv)
lbs_free_cmd_buffer(priv);
kfifo_free(&priv->event_fifo);
del_timer(&priv->command_timer);
- del_timer(&priv->tx_lockup_timer);
del_timer(&priv->auto_deepsleep_timer);
lbs_deb_leave(LBS_DEB_MAIN);
diff --git a/trunk/drivers/net/wireless/mac80211_hwsim.c b/trunk/drivers/net/wireless/mac80211_hwsim.c
index 68455a2307cb..34b79fc91e39 100644
--- a/trunk/drivers/net/wireless/mac80211_hwsim.c
+++ b/trunk/drivers/net/wireless/mac80211_hwsim.c
@@ -970,8 +970,7 @@ static int mac80211_hwsim_set_tim(struct ieee80211_hw *hw,
}
static int mac80211_hwsim_conf_tx(
- struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+ struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
wiphy_debug(hw->wiphy,
diff --git a/trunk/drivers/net/wireless/mwifiex/11n_aggr.c b/trunk/drivers/net/wireless/mwifiex/11n_aggr.c
index 9e63d16365e3..1a453a605b3f 100644
--- a/trunk/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/trunk/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -193,6 +193,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
skb_src = skb_dequeue(&pra_list->skb_head);
pra_list->total_pkts_size -= skb_src->len;
+ pra_list->total_pkts--;
atomic_dec(&priv->wmm.tx_pkts_queued);
@@ -268,6 +269,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
skb_queue_tail(&pra_list->skb_head, skb_aggr);
pra_list->total_pkts_size += skb_aggr->len;
+ pra_list->total_pkts++;
atomic_inc(&priv->wmm.tx_pkts_queued);
diff --git a/trunk/drivers/net/wireless/mwifiex/11n_aggr.h b/trunk/drivers/net/wireless/mwifiex/11n_aggr.h
index 900e1c62a0cc..9c6dca7ab02c 100644
--- a/trunk/drivers/net/wireless/mwifiex/11n_aggr.h
+++ b/trunk/drivers/net/wireless/mwifiex/11n_aggr.h
@@ -21,7 +21,6 @@
#define _MWIFIEX_11N_AGGR_H_
#define PKT_TYPE_AMSDU 0xE6
-#define MIN_NUM_AMSDU 2
int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv,
struct sk_buff *skb);
diff --git a/trunk/drivers/net/wireless/mwifiex/cfg80211.c b/trunk/drivers/net/wireless/mwifiex/cfg80211.c
index 462c71067bfb..6fd53e4e3fe6 100644
--- a/trunk/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/trunk/drivers/net/wireless/mwifiex/cfg80211.c
@@ -543,28 +543,12 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
ret = -EFAULT;
}
- /*
- * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid
- * MCS index values for us are 0 to 7.
- */
- if ((priv->tx_htinfo & BIT(0)) && (priv->tx_rate < 8)) {
- sinfo->txrate.mcs = priv->tx_rate;
- sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
- /* 40MHz rate */
- if (priv->tx_htinfo & BIT(1))
- sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
- /* SGI enabled */
- if (priv->tx_htinfo & BIT(2))
- sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
- }
-
sinfo->rx_bytes = priv->stats.rx_bytes;
sinfo->tx_bytes = priv->stats.tx_bytes;
sinfo->rx_packets = priv->stats.rx_packets;
sinfo->tx_packets = priv->stats.tx_packets;
sinfo->signal = priv->qual_level;
- /* bit rate is in 500 kb/s units. Convert it to 100kb/s units */
- sinfo->txrate.legacy = rate.rate * 5;
+ sinfo->txrate.legacy = rate.rate;
return ret;
}
@@ -581,6 +565,8 @@ mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
{
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ mwifiex_dump_station_info(priv, sinfo);
+
if (!priv->media_connected)
return -ENOENT;
if (memcmp(mac, priv->cfg_bssid, ETH_ALEN))
@@ -782,7 +768,6 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
struct mwifiex_bss_info bss_info;
int ie_len;
u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)];
- enum ieee80211_band band;
if (mwifiex_get_bss_info(priv, &bss_info))
return -1;
@@ -795,10 +780,9 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
bss_info.ssid.ssid_len);
ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
- band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
chan = __ieee80211_get_channel(priv->wdev->wiphy,
ieee80211_channel_to_frequency(bss_info.bss_chan,
- band));
+ priv->curr_bss_params.band));
cfg80211_inform_bss(priv->wdev->wiphy, chan,
bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
@@ -1162,150 +1146,8 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
}
-/*
- * create a new virtual interface with the given name
- */
-struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
- char *name,
- enum nl80211_iftype type,
- u32 *flags,
- struct vif_params *params)
-{
- struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
- struct mwifiex_adapter *adapter;
- struct net_device *dev;
- void *mdev_priv;
-
- if (!priv)
- return NULL;
-
- adapter = priv->adapter;
- if (!adapter)
- return NULL;
-
- switch (type) {
- case NL80211_IFTYPE_UNSPECIFIED:
- case NL80211_IFTYPE_STATION:
- case NL80211_IFTYPE_ADHOC:
- if (priv->bss_mode) {
- wiphy_err(wiphy, "cannot create multiple"
- " station/adhoc interfaces\n");
- return NULL;
- }
-
- if (type == NL80211_IFTYPE_UNSPECIFIED)
- priv->bss_mode = NL80211_IFTYPE_STATION;
- else
- priv->bss_mode = type;
-
- priv->bss_type = MWIFIEX_BSS_TYPE_STA;
- priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
- priv->bss_priority = 0;
- priv->bss_role = MWIFIEX_BSS_ROLE_STA;
- priv->bss_index = 0;
- priv->bss_num = 0;
-
- break;
- default:
- wiphy_err(wiphy, "type not supported\n");
- return NULL;
- }
-
- dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name,
- ether_setup, 1);
- if (!dev) {
- wiphy_err(wiphy, "no memory available for netdevice\n");
- goto error;
- }
-
- dev_net_set(dev, wiphy_net(wiphy));
- dev->ieee80211_ptr = priv->wdev;
- dev->ieee80211_ptr->iftype = priv->bss_mode;
- memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
- memcpy(dev->perm_addr, wiphy->perm_addr, ETH_ALEN);
- SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
-
- dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
- dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT;
- dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN;
-
- mdev_priv = netdev_priv(dev);
- *((unsigned long *) mdev_priv) = (unsigned long) priv;
-
- priv->netdev = dev;
- mwifiex_init_priv_params(priv, dev);
-
- SET_NETDEV_DEV(dev, adapter->dev);
-
- /* Register network device */
- if (register_netdevice(dev)) {
- wiphy_err(wiphy, "cannot register virtual network device\n");
- goto error;
- }
-
- sema_init(&priv->async_sem, 1);
- priv->scan_pending_on_block = false;
-
- dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name);
-
-#ifdef CONFIG_DEBUG_FS
- mwifiex_dev_debugfs_init(priv);
-#endif
- return dev;
-error:
- if (dev && (dev->reg_state == NETREG_UNREGISTERED))
- free_netdev(dev);
- priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
-
- return NULL;
-}
-EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
-
-/*
- * del_virtual_intf: remove the virtual interface determined by dev
- */
-int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
-{
- struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
-
- if (!priv || !dev)
- return 0;
-
-#ifdef CONFIG_DEBUG_FS
- mwifiex_dev_debugfs_remove(priv);
-#endif
-
- if (!netif_queue_stopped(priv->netdev))
- netif_stop_queue(priv->netdev);
-
- if (netif_carrier_ok(priv->netdev))
- netif_carrier_off(priv->netdev);
-
- if (dev->reg_state == NETREG_REGISTERED)
- unregister_netdevice(dev);
-
- if (dev->reg_state == NETREG_UNREGISTERED)
- free_netdev(dev);
-
- /* Clear the priv in adapter */
- priv->netdev = NULL;
-
- priv->media_connected = false;
-
- cancel_work_sync(&priv->cfg_workqueue);
- flush_workqueue(priv->workqueue);
- destroy_workqueue(priv->workqueue);
-
- priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf);
-
/* station cfg80211 operations */
static struct cfg80211_ops mwifiex_cfg80211_ops = {
- .add_virtual_intf = mwifiex_add_virtual_intf,
- .del_virtual_intf = mwifiex_del_virtual_intf,
.change_virtual_intf = mwifiex_cfg80211_change_virtual_intf,
.scan = mwifiex_cfg80211_scan,
.connect = mwifiex_cfg80211_connect,
@@ -1330,7 +1172,8 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
* default parameters and handler function pointers, and finally
* registers the device.
*/
-int mwifiex_register_cfg80211(struct mwifiex_private *priv)
+int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac,
+ struct mwifiex_private *priv)
{
int ret;
void *wdev_priv;
@@ -1370,15 +1213,12 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
wdev->wiphy->cipher_suites = mwifiex_cipher_suites;
wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
- memcpy(wdev->wiphy->perm_addr, priv->curr_addr, ETH_ALEN);
+ memcpy(wdev->wiphy->perm_addr, mac, 6);
wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
/* We are using custom domains */
wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
- /* Reserve space for bss band information */
- wdev->wiphy->bss_priv_size = sizeof(u8);
-
wdev->wiphy->reg_notifier = mwifiex_reg_notifier;
/* Set struct mwifiex_private pointer in wiphy_priv */
@@ -1400,8 +1240,17 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
"info: successfully registered wiphy device\n");
}
+ dev_net_set(dev, wiphy_net(wdev->wiphy));
+ dev->ieee80211_ptr = wdev;
+ memcpy(dev->dev_addr, wdev->wiphy->perm_addr, 6);
+ memcpy(dev->perm_addr, wdev->wiphy->perm_addr, 6);
+ SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
priv->wdev = wdev;
+ dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
+ dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT;
+ dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN;
+
return ret;
}
diff --git a/trunk/drivers/net/wireless/mwifiex/cfg80211.h b/trunk/drivers/net/wireless/mwifiex/cfg80211.h
index 8d010f2500c5..c4db8f36aa16 100644
--- a/trunk/drivers/net/wireless/mwifiex/cfg80211.h
+++ b/trunk/drivers/net/wireless/mwifiex/cfg80211.h
@@ -24,7 +24,8 @@
#include "main.h"
-int mwifiex_register_cfg80211(struct mwifiex_private *);
+int mwifiex_register_cfg80211(struct net_device *, u8 *,
+ struct mwifiex_private *);
void mwifiex_cfg80211_results(struct work_struct *work);
#endif
diff --git a/trunk/drivers/net/wireless/mwifiex/cmdevt.c b/trunk/drivers/net/wireless/mwifiex/cmdevt.c
index d12e25d0c880..b5352afb8714 100644
--- a/trunk/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/trunk/drivers/net/wireless/mwifiex/cmdevt.c
@@ -90,9 +90,6 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter,
cmd_node->data_buf = NULL;
cmd_node->wait_q_enabled = false;
- if (cmd_node->cmd_skb)
- skb_trim(cmd_node->cmd_skb, 0);
-
if (cmd_node->resp_skb) {
dev_kfree_skb_any(cmd_node->resp_skb);
cmd_node->resp_skb = NULL;
diff --git a/trunk/drivers/net/wireless/mwifiex/decl.h b/trunk/drivers/net/wireless/mwifiex/decl.h
index 6ca62c809cb9..94ddc9038cb3 100644
--- a/trunk/drivers/net/wireless/mwifiex/decl.h
+++ b/trunk/drivers/net/wireless/mwifiex/decl.h
@@ -114,6 +114,14 @@ struct mwifiex_txinfo {
u8 bss_index;
};
+struct mwifiex_bss_attr {
+ u8 bss_type;
+ u8 frame_type;
+ u8 active;
+ u8 bss_priority;
+ u8 bss_num;
+};
+
enum mwifiex_wmm_ac_e {
WMM_AC_BK,
WMM_AC_BE,
diff --git a/trunk/drivers/net/wireless/mwifiex/init.c b/trunk/drivers/net/wireless/mwifiex/init.c
index e1076b46401e..26e685a31bc0 100644
--- a/trunk/drivers/net/wireless/mwifiex/init.c
+++ b/trunk/drivers/net/wireless/mwifiex/init.c
@@ -76,7 +76,7 @@ static int mwifiex_init_priv(struct mwifiex_private *priv)
memset(priv->curr_addr, 0xff, ETH_ALEN);
priv->pkt_tx_ctrl = 0;
- priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
+ priv->bss_mode = NL80211_IFTYPE_STATION;
priv->data_rate = 0; /* Initially indicate the rate as auto */
priv->is_data_rate_auto = true;
priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
diff --git a/trunk/drivers/net/wireless/mwifiex/main.c b/trunk/drivers/net/wireless/mwifiex/main.c
index 848645118ad4..53579ad83e5c 100644
--- a/trunk/drivers/net/wireless/mwifiex/main.c
+++ b/trunk/drivers/net/wireless/mwifiex/main.c
@@ -26,6 +26,21 @@
const char driver_version[] = "mwifiex " VERSION " (%s) ";
+static struct mwifiex_bss_attr mwifiex_bss_sta[] = {
+ {MWIFIEX_BSS_TYPE_STA, MWIFIEX_DATA_FRAME_TYPE_ETH_II, true, 0, 0},
+};
+
+static int drv_mode = DRV_MODE_STA;
+
+/* Supported drv_mode table */
+static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = {
+ {
+ .drv_mode = DRV_MODE_STA,
+ .intf_num = ARRAY_SIZE(mwifiex_bss_sta),
+ .bss_attr = mwifiex_bss_sta,
+ },
+};
+
/*
* This function registers the device and performs all the necessary
* initializations.
@@ -42,6 +57,7 @@ const char driver_version[] = "mwifiex " VERSION " (%s) ";
* proper cleanup before exiting.
*/
static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
+ struct mwifiex_drv_mode *drv_mode_ptr,
void **padapter)
{
struct mwifiex_adapter *adapter;
@@ -62,20 +78,44 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
goto error;
adapter->priv_num = 0;
+ for (i = 0; i < drv_mode_ptr->intf_num; i++) {
+ adapter->priv[i] = NULL;
- /* Allocate memory for private structure */
- adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private),
- GFP_KERNEL);
- if (!adapter->priv[0]) {
- dev_err(adapter->dev, "%s: failed to alloc priv[0]\n",
- __func__);
- goto error;
- }
+ if (!drv_mode_ptr->bss_attr[i].active)
+ continue;
+
+ /* Allocate memory for private structure */
+ adapter->priv[i] = kzalloc(sizeof(struct mwifiex_private),
+ GFP_KERNEL);
+ if (!adapter->priv[i]) {
+ dev_err(adapter->dev, "%s: failed to alloc priv[%d]\n",
+ __func__, i);
+ goto error;
+ }
- adapter->priv_num++;
+ adapter->priv_num++;
+ adapter->priv[i]->adapter = adapter;
+ /* Save bss_type, frame_type & bss_priority */
+ adapter->priv[i]->bss_type = drv_mode_ptr->bss_attr[i].bss_type;
+ adapter->priv[i]->frame_type =
+ drv_mode_ptr->bss_attr[i].frame_type;
+ adapter->priv[i]->bss_priority =
+ drv_mode_ptr->bss_attr[i].bss_priority;
+
+ if (drv_mode_ptr->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_STA)
+ adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_STA;
+ else if (drv_mode_ptr->bss_attr[i].bss_type ==
+ MWIFIEX_BSS_TYPE_UAP)
+ adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_UAP;
+
+ /* Save bss_index & bss_num */
+ adapter->priv[i]->bss_index = i;
+ adapter->priv[i]->bss_num = drv_mode_ptr->bss_attr[i].bss_num;
+ }
+ adapter->drv_mode = drv_mode_ptr;
- adapter->priv[0]->adapter = adapter;
- mwifiex_init_lock_list(adapter);
+ if (mwifiex_init_lock_list(adapter))
+ goto error;
init_timer(&adapter->cmd_timer);
adapter->cmd_timer.function = mwifiex_cmd_timeout_func;
@@ -86,9 +126,9 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
error:
dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n");
- for (i = 0; i < adapter->priv_num; i++)
+ mwifiex_free_lock_list(adapter);
+ for (i = 0; i < drv_mode_ptr->intf_num; i++)
kfree(adapter->priv[i]);
-
kfree(adapter);
return -1;
@@ -275,6 +315,38 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
return ret;
}
+/*
+ * This function initializes the software.
+ *
+ * The main work includes allocating and initializing the adapter structure
+ * and initializing the private structures.
+ */
+static int
+mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **padapter)
+{
+ int i;
+ struct mwifiex_drv_mode *drv_mode_ptr;
+
+ /* find mwifiex_drv_mode entry from mwifiex_drv_mode_tbl */
+ drv_mode_ptr = NULL;
+ for (i = 0; i < ARRAY_SIZE(mwifiex_drv_mode_tbl); i++) {
+ if (mwifiex_drv_mode_tbl[i].drv_mode == drv_mode) {
+ drv_mode_ptr = &mwifiex_drv_mode_tbl[i];
+ break;
+ }
+ }
+
+ if (!drv_mode_ptr) {
+ pr_err("invalid drv_mode=%d\n", drv_mode);
+ return -1;
+ }
+
+ if (mwifiex_register(card, if_ops, drv_mode_ptr, padapter))
+ return -1;
+
+ return 0;
+}
+
/*
* This function frees the adapter structure.
*
@@ -577,8 +649,8 @@ static const struct net_device_ops mwifiex_netdev_ops = {
*
* In addition, the CFG80211 work queue is also created.
*/
-void mwifiex_init_priv_params(struct mwifiex_private *priv,
- struct net_device *dev)
+static void
+mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev)
{
dev->netdev_ops = &mwifiex_netdev_ops;
/* Initialize private structure */
@@ -591,6 +663,118 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
}
+/*
+ * This function adds a new logical interface.
+ *
+ * It allocates, initializes and registers the interface by performing
+ * the following opearations -
+ * - Allocate a new net device structure
+ * - Assign device name
+ * - Register the new device with CFG80211 subsystem
+ * - Initialize semaphore and private structure
+ * - Register the new device with kernel
+ * - Create the complete debug FS structure if configured
+ */
+static struct mwifiex_private *mwifiex_add_interface(
+ struct mwifiex_adapter *adapter,
+ u8 bss_index, u8 bss_type)
+{
+ struct net_device *dev;
+ struct mwifiex_private *priv;
+ void *mdev_priv;
+
+ dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), "mlan%d",
+ ether_setup, 1);
+ if (!dev) {
+ dev_err(adapter->dev, "no memory available for netdevice\n");
+ goto error;
+ }
+
+ if (mwifiex_register_cfg80211(dev, adapter->priv[bss_index]->curr_addr,
+ adapter->priv[bss_index]) != 0) {
+ dev_err(adapter->dev, "cannot register netdevice with cfg80211\n");
+ goto error;
+ }
+ /* Save the priv pointer in netdev */
+ priv = adapter->priv[bss_index];
+ mdev_priv = netdev_priv(dev);
+ *((unsigned long *) mdev_priv) = (unsigned long) priv;
+
+ priv->netdev = dev;
+
+ sema_init(&priv->async_sem, 1);
+ priv->scan_pending_on_block = false;
+
+ mwifiex_init_priv_params(priv, dev);
+
+ SET_NETDEV_DEV(dev, adapter->dev);
+
+ /* Register network device */
+ if (register_netdev(dev)) {
+ dev_err(adapter->dev, "cannot register virtual network device\n");
+ goto error;
+ }
+
+ dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name);
+#ifdef CONFIG_DEBUG_FS
+ mwifiex_dev_debugfs_init(priv);
+#endif
+ return priv;
+error:
+ if (dev)
+ free_netdev(dev);
+ return NULL;
+}
+
+/*
+ * This function removes a logical interface.
+ *
+ * It deregisters, resets and frees the interface by performing
+ * the following operations -
+ * - Disconnect the device if connected, send wireless event to
+ * notify applications.
+ * - Remove the debug FS structure if configured
+ * - Unregister the device from kernel
+ * - Free the net device structure
+ * - Cancel all works and destroy work queue
+ * - Unregister and free the wireless device from CFG80211 subsystem
+ */
+static void
+mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index)
+{
+ struct net_device *dev;
+ struct mwifiex_private *priv = adapter->priv[bss_index];
+
+ if (!priv)
+ return;
+ dev = priv->netdev;
+
+ if (priv->media_connected)
+ priv->media_connected = false;
+
+#ifdef CONFIG_DEBUG_FS
+ mwifiex_dev_debugfs_remove(priv);
+#endif
+ /* Last reference is our one */
+ dev_dbg(adapter->dev, "info: %s: refcnt = %d\n",
+ dev->name, netdev_refcnt_read(dev));
+
+ if (dev->reg_state == NETREG_REGISTERED)
+ unregister_netdev(dev);
+
+ /* Clear the priv in adapter */
+ priv->netdev = NULL;
+ if (dev)
+ free_netdev(dev);
+
+ cancel_work_sync(&priv->cfg_workqueue);
+ flush_workqueue(priv->workqueue);
+ destroy_workqueue(priv->workqueue);
+ wiphy_unregister(priv->wdev->wiphy);
+ wiphy_free(priv->wdev->wiphy);
+ kfree(priv->wdev);
+}
+
/*
* This function check if command is pending.
*/
@@ -663,14 +847,14 @@ int
mwifiex_add_card(void *card, struct semaphore *sem,
struct mwifiex_if_ops *if_ops)
{
+ int i;
struct mwifiex_adapter *adapter;
char fmt[64];
- struct mwifiex_private *priv;
if (down_interruptible(sem))
goto exit_sem_err;
- if (mwifiex_register(card, if_ops, (void **)&adapter)) {
+ if (mwifiex_init_sw(card, if_ops, (void **)&adapter)) {
pr_err("%s: software init failed\n", __func__);
goto err_init_sw;
}
@@ -704,26 +888,14 @@ mwifiex_add_card(void *card, struct semaphore *sem,
goto err_init_fw;
}
- priv = adapter->priv[0];
-
- if (mwifiex_register_cfg80211(priv) != 0) {
- dev_err(adapter->dev, "cannot register netdevice"
- " with cfg80211\n");
- goto err_init_fw;
- }
-
- rtnl_lock();
- /* Create station interface by default */
- if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d",
- NL80211_IFTYPE_STATION, NULL, NULL)) {
- rtnl_unlock();
- dev_err(adapter->dev, "cannot create default station"
- " interface\n");
- goto err_add_intf;
+ /* Add interfaces */
+ for (i = 0; i < adapter->drv_mode->intf_num; i++) {
+ if (!mwifiex_add_interface(adapter, i,
+ adapter->drv_mode->bss_attr[i].bss_type)) {
+ goto err_add_intf;
+ }
}
- rtnl_unlock();
-
up(sem);
mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
@@ -732,9 +904,8 @@ mwifiex_add_card(void *card, struct semaphore *sem,
return 0;
err_add_intf:
- rtnl_lock();
- mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
- rtnl_unlock();
+ for (i = 0; i < adapter->priv_num; i++)
+ mwifiex_remove_interface(adapter, i);
err_init_fw:
pr_debug("info: %s: unregister device\n", __func__);
adapter->if_ops.unregister_dev(adapter);
@@ -789,7 +960,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
/* Stop data */
for (i = 0; i < adapter->priv_num; i++) {
priv = adapter->priv[i];
- if (priv && priv->netdev) {
+ if (priv) {
if (!netif_queue_stopped(priv->netdev))
netif_stop_queue(priv->netdev);
if (netif_carrier_ok(priv->netdev))
@@ -814,20 +985,9 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
atomic_read(&adapter->cmd_pending));
}
- for (i = 0; i < adapter->priv_num; i++) {
- priv = adapter->priv[i];
-
- if (!priv)
- continue;
-
- rtnl_lock();
- mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
- rtnl_unlock();
- }
-
- wiphy_unregister(priv->wdev->wiphy);
- wiphy_free(priv->wdev->wiphy);
- kfree(priv->wdev);
+ /* Remove interface */
+ for (i = 0; i < adapter->priv_num; i++)
+ mwifiex_remove_interface(adapter, i);
mwifiex_terminate_workqueue(adapter);
diff --git a/trunk/drivers/net/wireless/mwifiex/main.h b/trunk/drivers/net/wireless/mwifiex/main.h
index 907ab746dc4b..e6b6c0cfb63e 100644
--- a/trunk/drivers/net/wireless/mwifiex/main.h
+++ b/trunk/drivers/net/wireless/mwifiex/main.h
@@ -45,6 +45,15 @@ enum {
MWIFIEX_SYNC_CMD
};
+#define DRV_MODE_STA 0x1
+
+struct mwifiex_drv_mode {
+ u16 drv_mode;
+ u16 intf_num;
+ struct mwifiex_bss_attr *bss_attr;
+};
+
+
#define MWIFIEX_MAX_AP 64
#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ)
@@ -173,6 +182,7 @@ struct mwifiex_ra_list_tbl {
struct sk_buff_head skb_head;
u8 ra[ETH_ALEN];
u32 total_pkts_size;
+ u32 total_pkts;
u32 is_11n_enabled;
};
@@ -536,6 +546,7 @@ struct mwifiex_if_ops {
struct mwifiex_adapter {
struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM];
u8 priv_num;
+ struct mwifiex_drv_mode *drv_mode;
const struct firmware *firmware;
char fw_name[32];
struct device *dev;
@@ -781,8 +792,6 @@ int mwifiex_cmd_get_hw_spec(struct mwifiex_private *priv,
int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp);
int is_command_pending(struct mwifiex_adapter *adapter);
-void mwifiex_init_priv_params(struct mwifiex_private *priv,
- struct net_device *dev);
/*
* This function checks if the queuing is RA based or not.
@@ -949,7 +958,7 @@ int mwifiex_get_bss_info(struct mwifiex_private *,
int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
u8 *bssid, s32 rssi, u8 *ie_buf,
size_t ie_len, u16 beacon_period,
- u16 cap_info_bitmap, u8 band,
+ u16 cap_info_bitmap,
struct mwifiex_bssdescriptor *bss_desc);
int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
struct mwifiex_bssdescriptor *bss_entry,
@@ -957,12 +966,6 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
struct mwifiex_bssdescriptor *bss_desc);
-struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
- char *name, enum nl80211_iftype type,
- u32 *flags, struct vif_params *params);
-int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev);
-
-
#ifdef CONFIG_DEBUG_FS
void mwifiex_debugfs_init(void);
void mwifiex_debugfs_remove(void);
diff --git a/trunk/drivers/net/wireless/mwifiex/scan.c b/trunk/drivers/net/wireless/mwifiex/scan.c
index ca3761965e85..8d8588db1cd9 100644
--- a/trunk/drivers/net/wireless/mwifiex/scan.c
+++ b/trunk/drivers/net/wireless/mwifiex/scan.c
@@ -532,7 +532,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
sband = priv->wdev->wiphy->bands[band];
- for (i = 0; (i < sband->n_channels) ; i++) {
+ for (i = 0; (i < sband->n_channels) ; i++, chan_idx++) {
ch = &sband->channels[i];
if (ch->flags & IEEE80211_CHAN_DISABLED)
continue;
@@ -563,7 +563,6 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
scan_chan_list[chan_idx].chan_scan_mode_bitmap
|= MWIFIEX_DISABLE_CHAN_FILT;
}
- chan_idx++;
}
}
@@ -1464,9 +1463,9 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
}
static int
-mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
- s32 rssi, const u8 *ie_buf, size_t ie_len,
- u16 beacon_period, u16 cap_info_bitmap, u8 band)
+mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
+ u8 *bssid, s32 rssi, const u8 *ie_buf,
+ size_t ie_len, u16 beacon_period, u16 cap_info_bitmap)
{
struct mwifiex_bssdescriptor *bss_desc = NULL;
int ret;
@@ -1489,7 +1488,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
ret = mwifiex_fill_new_bss_desc(priv, bssid, rssi, beacon_ie,
ie_len, beacon_period,
- cap_info_bitmap, band, bss_desc);
+ cap_info_bitmap, bss_desc);
if (ret)
goto done;
@@ -1533,11 +1532,6 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
return 0;
}
-static void mwifiex_free_bss_priv(struct cfg80211_bss *bss)
-{
- kfree(bss->priv);
-}
-
/*
* This function handles the command response of scan.
*
@@ -1576,7 +1570,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
struct chan_band_param_set *chan_band;
u8 is_bgscan_resp;
unsigned long flags;
- struct cfg80211_bss *bss;
is_bgscan_resp = (le16_to_cpu(resp->command)
== HostCmd_CMD_802_11_BG_SCAN_QUERY);
@@ -1758,12 +1751,10 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
chan = ieee80211_get_channel(priv->wdev->wiphy, freq);
if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
- bss = cfg80211_inform_bss(priv->wdev->wiphy,
- chan, bssid, network_tsf,
- cap_info_bitmap, beacon_period,
- ie_buf, ie_len, rssi, GFP_KERNEL);
- *(u8 *)bss->priv = band;
- bss->free_priv = mwifiex_free_bss_priv;
+ cfg80211_inform_bss(priv->wdev->wiphy, chan,
+ bssid, network_tsf, cap_info_bitmap,
+ beacon_period, ie_buf, ie_len, rssi,
+ GFP_KERNEL);
if (priv->media_connected && !memcmp(bssid,
priv->curr_bss_params.bss_descriptor
@@ -1771,7 +1762,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
mwifiex_update_curr_bss_params(priv,
bssid, rssi, ie_buf,
ie_len, beacon_period,
- cap_info_bitmap, band);
+ cap_info_bitmap);
}
} else {
dev_dbg(adapter->dev, "missing BSS channel IE\n");
diff --git a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c
index 520800b618e7..eb569fa9adba 100644
--- a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -148,7 +148,7 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
u8 *bssid, s32 rssi, u8 *ie_buf,
size_t ie_len, u16 beacon_period,
- u16 cap_info_bitmap, u8 band,
+ u16 cap_info_bitmap,
struct mwifiex_bssdescriptor *bss_desc)
{
int ret;
@@ -159,7 +159,6 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
bss_desc->beacon_buf_size = ie_len;
bss_desc->beacon_period = beacon_period;
bss_desc->cap_info_bitmap = cap_info_bitmap;
- bss_desc->bss_band = band;
if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) {
dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n");
bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
@@ -204,7 +203,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
beacon_ie = kmemdup(bss->information_elements,
bss->len_beacon_ies, GFP_KERNEL);
if (!beacon_ie) {
- kfree(bss_desc);
dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
return -ENOMEM;
}
@@ -212,8 +210,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
ret = mwifiex_fill_new_bss_desc(priv, bss->bssid, bss->signal,
beacon_ie, bss->len_beacon_ies,
bss->beacon_interval,
- bss->capability,
- *(u8 *)bss->priv, bss_desc);
+ bss->capability, bss_desc);
if (ret)
goto done;
}
@@ -655,7 +652,6 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
u16 curr_chan = 0;
struct cfg80211_bss *bss = NULL;
struct ieee80211_channel *chan;
- enum ieee80211_band band;
memset(&bss_info, 0, sizeof(bss_info));
@@ -692,9 +688,9 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
goto done;
}
- band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
chan = __ieee80211_get_channel(priv->wdev->wiphy,
- ieee80211_channel_to_frequency(channel, band));
+ ieee80211_channel_to_frequency(channel,
+ priv->curr_bss_params.band));
/* Find the BSS we want using available scan results */
bss = cfg80211_get_bss(priv->wdev->wiphy, chan, bss_info.bssid,
@@ -720,9 +716,51 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv,
struct mwifiex_rate_cfg *rate_cfg)
{
+ struct mwifiex_adapter *adapter = priv->adapter;
+
rate_cfg->is_rate_auto = priv->is_data_rate_auto;
- return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_TX_RATE_QUERY,
- HostCmd_ACT_GEN_GET, 0, NULL);
+ if (!priv->media_connected) {
+ switch (adapter->config_bands) {
+ case BAND_B:
+ /* Return the lowest supported rate for B band */
+ rate_cfg->rate = supported_rates_b[0] & 0x7f;
+ break;
+ case BAND_G:
+ case BAND_G | BAND_GN:
+ /* Return the lowest supported rate for G band */
+ rate_cfg->rate = supported_rates_g[0] & 0x7f;
+ break;
+ case BAND_B | BAND_G:
+ case BAND_A | BAND_B | BAND_G:
+ case BAND_A | BAND_B:
+ case BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN:
+ case BAND_B | BAND_G | BAND_GN:
+ /* Return the lowest supported rate for BG band */
+ rate_cfg->rate = supported_rates_bg[0] & 0x7f;
+ break;
+ case BAND_A:
+ case BAND_A | BAND_G:
+ case BAND_A | BAND_G | BAND_AN | BAND_GN:
+ case BAND_A | BAND_AN:
+ /* Return the lowest supported rate for A band */
+ rate_cfg->rate = supported_rates_a[0] & 0x7f;
+ break;
+ case BAND_GN:
+ /* Return the lowest supported rate for N band */
+ rate_cfg->rate = supported_rates_n[0] & 0x7f;
+ break;
+ default:
+ dev_warn(adapter->dev, "invalid band %#x\n",
+ adapter->config_bands);
+ break;
+ }
+ } else {
+ return mwifiex_send_cmd_sync(priv,
+ HostCmd_CMD_802_11_TX_RATE_QUERY,
+ HostCmd_ACT_GEN_GET, 0, NULL);
+ }
+
+ return 0;
}
/*
@@ -829,10 +867,10 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
ret = mwifiex_rate_ioctl_cfg(priv, rate);
if (!ret) {
- if (rate->is_rate_auto)
+ if (rate && rate->is_rate_auto)
rate->rate = mwifiex_index_to_data_rate(priv->tx_rate,
priv->tx_htinfo);
- else
+ else if (rate)
rate->rate = priv->data_rate;
} else {
ret = -1;
diff --git a/trunk/drivers/net/wireless/mwifiex/wmm.c b/trunk/drivers/net/wireless/mwifiex/wmm.c
index eda24474c1fc..69e260b41711 100644
--- a/trunk/drivers/net/wireless/mwifiex/wmm.c
+++ b/trunk/drivers/net/wireless/mwifiex/wmm.c
@@ -121,6 +121,7 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra)
memcpy(ra_list->ra, ra, ETH_ALEN);
ra_list->total_pkts_size = 0;
+ ra_list->total_pkts = 0;
dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list);
@@ -647,6 +648,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
skb_queue_tail(&ra_list->skb_head, skb);
ra_list->total_pkts_size += skb->len;
+ ra_list->total_pkts++;
atomic_inc(&priv->wmm.tx_pkts_queued);
@@ -972,28 +974,6 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
return NULL;
}
-/*
- * This function checks if 11n aggregation is possible.
- */
-static int
-mwifiex_is_11n_aggragation_possible(struct mwifiex_private *priv,
- struct mwifiex_ra_list_tbl *ptr,
- int max_buf_size)
-{
- int count = 0, total_size = 0;
- struct sk_buff *skb, *tmp;
-
- skb_queue_walk_safe(&ptr->skb_head, skb, tmp) {
- total_size += skb->len;
- if (total_size >= max_buf_size)
- break;
- if (++count >= MIN_NUM_AMSDU)
- return true;
- }
-
- return false;
-}
-
/*
* This function sends a single packet to firmware for transmission.
*/
@@ -1021,6 +1001,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb);
ptr->total_pkts_size -= skb->len;
+ ptr->total_pkts--;
if (!skb_queue_empty(&ptr->skb_head))
skb_next = skb_peek(&ptr->skb_head);
@@ -1046,6 +1027,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
skb_queue_tail(&ptr->skb_head, skb);
ptr->total_pkts_size += skb->len;
+ ptr->total_pkts++;
tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
ra_list_flags);
@@ -1231,9 +1213,11 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
mwifiex_send_delba(priv, tid_del, ra, 1);
}
}
+/* Minimum number of AMSDU */
+#define MIN_NUM_AMSDU 2
+
if (mwifiex_is_amsdu_allowed(priv, tid) &&
- mwifiex_is_11n_aggragation_possible(priv, ptr,
- adapter->tx_buf_size))
+ (ptr->total_pkts >= MIN_NUM_AMSDU))
mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN,
ptr_index, flags);
/* ra_list_spinlock has been freed in
diff --git a/trunk/drivers/net/wireless/mwl8k.c b/trunk/drivers/net/wireless/mwl8k.c
index 995695c28d5c..ea1395aafa39 100644
--- a/trunk/drivers/net/wireless/mwl8k.c
+++ b/trunk/drivers/net/wireless/mwl8k.c
@@ -4915,8 +4915,7 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw,
return ret;
}
-static int mwl8k_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct mwl8k_priv *priv = hw->priv;
@@ -5463,7 +5462,7 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image)
goto fail;
for (i = 0; i < MWL8K_TX_WMM_QUEUES; i++) {
- rc = mwl8k_conf_tx(hw, NULL, i, &priv->wmm_params[i]);
+ rc = mwl8k_conf_tx(hw, i, &priv->wmm_params[i]);
if (rc)
goto fail;
}
diff --git a/trunk/drivers/net/wireless/p54/main.c b/trunk/drivers/net/wireless/p54/main.c
index ad9ae04d07aa..726a9343f514 100644
--- a/trunk/drivers/net/wireless/p54/main.c
+++ b/trunk/drivers/net/wireless/p54/main.c
@@ -404,8 +404,7 @@ static void p54_configure_filter(struct ieee80211_hw *dev,
p54_set_groupfilter(priv);
}
-static int p54_conf_tx(struct ieee80211_hw *dev,
- struct ieee80211_vif *vif, u16 queue,
+static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct p54_common *priv = dev->priv;
diff --git a/trunk/drivers/net/wireless/p54/txrx.c b/trunk/drivers/net/wireless/p54/txrx.c
index f485784a60ae..2b97a89e7ff8 100644
--- a/trunk/drivers/net/wireless/p54/txrx.c
+++ b/trunk/drivers/net/wireless/p54/txrx.c
@@ -689,7 +689,7 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb,
if (!(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
*flags |= P54_HDR_FLAG_DATA_OUT_SEQNR;
- if (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)
+ if (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)
*flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
diff --git a/trunk/drivers/net/wireless/rt2x00/rt2400pci.c b/trunk/drivers/net/wireless/rt2x00/rt2400pci.c
index 3a6b40239bc1..daa32fc9398b 100644
--- a/trunk/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/trunk/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1239,7 +1239,7 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry,
* call, we must decrease the higher 32bits with 1 to get
* to correct value.
*/
- tsf = rt2x00dev->ops->hw->get_tsf(rt2x00dev->hw, NULL);
+ tsf = rt2x00dev->ops->hw->get_tsf(rt2x00dev->hw);
rx_low = rt2x00_get_field32(word4, RXD_W4_RX_END_TIME);
rx_high = upper_32_bits(tsf);
@@ -1648,8 +1648,7 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* IEEE80211 stack callback functions.
*/
-static int rt2400pci_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+static int rt2400pci_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -1662,7 +1661,7 @@ static int rt2400pci_conf_tx(struct ieee80211_hw *hw,
if (queue != 0)
return -EINVAL;
- if (rt2x00mac_conf_tx(hw, vif, queue, params))
+ if (rt2x00mac_conf_tx(hw, queue, params))
return -EINVAL;
/*
@@ -1674,8 +1673,7 @@ static int rt2400pci_conf_tx(struct ieee80211_hw *hw,
return 0;
}
-static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
u64 tsf;
diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500pci.c b/trunk/drivers/net/wireless/rt2x00/rt2500pci.c
index dcc0e1fcca77..b46c3b8866fa 100644
--- a/trunk/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/trunk/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1966,8 +1966,7 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* IEEE80211 stack callback functions.
*/
-static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
u64 tsf;
diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c
index 3f183a15186e..31c98509f7e6 100644
--- a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -4398,8 +4398,7 @@ int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
}
EXPORT_SYMBOL_GPL(rt2800_set_rts_threshold);
-int rt2800_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue_idx,
+int rt2800_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
const struct ieee80211_tx_queue_params *params)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -4415,7 +4414,7 @@ int rt2800_conf_tx(struct ieee80211_hw *hw,
* we are free to update the registers based on the value
* in the queue parameter.
*/
- retval = rt2x00mac_conf_tx(hw, vif, queue_idx, params);
+ retval = rt2x00mac_conf_tx(hw, queue_idx, params);
if (retval)
return retval;
@@ -4467,7 +4466,7 @@ int rt2800_conf_tx(struct ieee80211_hw *hw,
}
EXPORT_SYMBOL_GPL(rt2800_conf_tx);
-u64 rt2800_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+u64 rt2800_get_tsf(struct ieee80211_hw *hw)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
u64 tsf;
diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800lib.h b/trunk/drivers/net/wireless/rt2x00/rt2800lib.h
index 8c3c281904fe..7a2511f6785c 100644
--- a/trunk/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/trunk/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -197,10 +197,9 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev);
void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, u32 *iv32,
u16 *iv16);
int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
-int rt2800_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue_idx,
+int rt2800_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
const struct ieee80211_tx_queue_params *params);
-u64 rt2800_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
+u64 rt2800_get_tsf(struct ieee80211_hw *hw);
int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum ieee80211_ampdu_mlme_action action,
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00.h b/trunk/drivers/net/wireless/rt2x00/rt2x00.h
index 2ec5c00235e6..cbf8eb334e96 100644
--- a/trunk/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/trunk/drivers/net/wireless/rt2x00/rt2x00.h
@@ -1299,8 +1299,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changes);
-int rt2x00mac_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop);
diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c
index bf0acff07807..cef1c878c37e 100644
--- a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -713,8 +713,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
}
EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
-int rt2x00mac_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue_idx,
+int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
const struct ieee80211_tx_queue_params *params)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
diff --git a/trunk/drivers/net/wireless/rt2x00/rt61pci.c b/trunk/drivers/net/wireless/rt2x00/rt61pci.c
index bf55b4a311e3..058ef4b19d1d 100644
--- a/trunk/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/trunk/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2883,8 +2883,7 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* IEEE80211 stack callback functions.
*/
-static int rt61pci_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue_idx,
+static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
const struct ieee80211_tx_queue_params *params)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -2900,7 +2899,7 @@ static int rt61pci_conf_tx(struct ieee80211_hw *hw,
* we are free to update the registers based on the value
* in the queue parameter.
*/
- retval = rt2x00mac_conf_tx(hw, vif, queue_idx, params);
+ retval = rt2x00mac_conf_tx(hw, queue_idx, params);
if (retval)
return retval;
@@ -2941,7 +2940,7 @@ static int rt61pci_conf_tx(struct ieee80211_hw *hw,
return 0;
}
-static u64 rt61pci_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+static u64 rt61pci_get_tsf(struct ieee80211_hw *hw)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
u64 tsf;
diff --git a/trunk/drivers/net/wireless/rt2x00/rt73usb.c b/trunk/drivers/net/wireless/rt2x00/rt73usb.c
index cfb19dbb0a67..0baeb894f093 100644
--- a/trunk/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/trunk/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2222,8 +2222,7 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* IEEE80211 stack callback functions.
*/
-static int rt73usb_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue_idx,
+static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
const struct ieee80211_tx_queue_params *params)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -2239,7 +2238,7 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw,
* we are free to update the registers based on the value
* in the queue parameter.
*/
- retval = rt2x00mac_conf_tx(hw, vif, queue_idx, params);
+ retval = rt2x00mac_conf_tx(hw, queue_idx, params);
if (retval)
return retval;
@@ -2280,7 +2279,7 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw,
return 0;
}
-static u64 rt73usb_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+static u64 rt73usb_get_tsf(struct ieee80211_hw *hw)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
u64 tsf;
diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c
index 0082015ff664..66b29dc07cc3 100644
--- a/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c
+++ b/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c
@@ -669,8 +669,7 @@ static void rtl8180_stop(struct ieee80211_hw *dev)
rtl8180_free_tx_ring(dev, i);
}
-static u64 rtl8180_get_tsf(struct ieee80211_hw *dev,
- struct ieee80211_vif *vif)
+static u64 rtl8180_get_tsf(struct ieee80211_hw *dev)
{
struct rtl8180_priv *priv = dev->priv;
@@ -702,7 +701,7 @@ static void rtl8180_beacon_work(struct work_struct *work)
* TODO: make hardware update beacon timestamp
*/
mgmt = (struct ieee80211_mgmt *)skb->data;
- mgmt->u.beacon.timestamp = cpu_to_le64(rtl8180_get_tsf(dev, vif));
+ mgmt->u.beacon.timestamp = cpu_to_le64(rtl8180_get_tsf(dev));
/* TODO: use actual beacon queue */
skb_set_queue_mapping(skb, 0);
diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8187/dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8187/dev.c
index 24873b55b55c..1e0be14d10d4 100644
--- a/trunk/drivers/net/wireless/rtl818x/rtl8187/dev.c
+++ b/trunk/drivers/net/wireless/rtl818x/rtl8187/dev.c
@@ -1241,8 +1241,7 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev,
rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf);
}
-static int rtl8187_conf_tx(struct ieee80211_hw *dev,
- struct ieee80211_vif *vif, u16 queue,
+static int rtl8187_conf_tx(struct ieee80211_hw *dev, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct rtl8187_priv *priv = dev->priv;
@@ -1278,7 +1277,7 @@ static int rtl8187_conf_tx(struct ieee80211_hw *dev,
return 0;
}
-static u64 rtl8187_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif)
+static u64 rtl8187_get_tsf(struct ieee80211_hw *dev)
{
struct rtl8187_priv *priv = dev->priv;
diff --git a/trunk/drivers/net/wireless/rtlwifi/core.c b/trunk/drivers/net/wireless/rtlwifi/core.c
index 3f0f056fae9c..04c4e9eb6ee6 100644
--- a/trunk/drivers/net/wireless/rtlwifi/core.c
+++ b/trunk/drivers/net/wireless/rtlwifi/core.c
@@ -504,8 +504,7 @@ static int _rtl_get_hal_qnum(u16 queue)
*for mac80211 VO=0, VI=1, BE=2, BK=3
*for rtl819x BE=0, BK=1, VI=2, VO=3
*/
-static int rtl_op_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+static int rtl_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *param)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -776,7 +775,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
mutex_unlock(&rtlpriv->locks.conf_mutex);
}
-static u64 rtl_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+static u64 rtl_op_get_tsf(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u64 tsf;
@@ -785,8 +784,7 @@ static u64 rtl_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
return tsf;
}
-static void rtl_op_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- u64 tsf)
+static void rtl_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
@@ -796,8 +794,7 @@ static void rtl_op_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&bibss));
}
-static void rtl_op_reset_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static void rtl_op_reset_tsf(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 tmp = 0;
diff --git a/trunk/drivers/net/wireless/rtlwifi/usb.c b/trunk/drivers/net/wireless/rtlwifi/usb.c
index b42c2e2b2055..8b1cef0ffde6 100644
--- a/trunk/drivers/net/wireless/rtlwifi/usb.c
+++ b/trunk/drivers/net/wireless/rtlwifi/usb.c
@@ -191,6 +191,44 @@ static void _usb_write32_async(struct rtl_priv *rtlpriv, u32 addr, u32 val)
_usb_write_async(to_usb_device(dev), addr, val, 4);
}
+static int _usb_nbytes_read_write(struct usb_device *udev, bool read, u32 addr,
+ u16 len, u8 *pdata)
+{
+ int status;
+ u8 request;
+ u16 wvalue;
+ u16 index;
+
+ request = REALTEK_USB_VENQT_CMD_REQ;
+ index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */
+ wvalue = (u16)addr;
+ if (read)
+ status = _usbctrl_vendorreq_sync_read(udev, request, wvalue,
+ index, pdata, len);
+ else
+ status = _usbctrl_vendorreq_async_write(udev, request, wvalue,
+ index, pdata, len);
+ return status;
+}
+
+static int _usb_readN_sync(struct rtl_priv *rtlpriv, u32 addr, u16 len,
+ u8 *pdata)
+{
+ struct device *dev = rtlpriv->io.dev;
+
+ return _usb_nbytes_read_write(to_usb_device(dev), true, addr, len,
+ pdata);
+}
+
+static int _usb_writeN_async(struct rtl_priv *rtlpriv, u32 addr, u16 len,
+ u8 *pdata)
+{
+ struct device *dev = rtlpriv->io.dev;
+
+ return _usb_nbytes_read_write(to_usb_device(dev), false, addr, len,
+ pdata);
+}
+
static void _rtl_usb_io_handler_init(struct device *dev,
struct ieee80211_hw *hw)
{
@@ -201,9 +239,11 @@ static void _rtl_usb_io_handler_init(struct device *dev,
rtlpriv->io.write8_async = _usb_write8_async;
rtlpriv->io.write16_async = _usb_write16_async;
rtlpriv->io.write32_async = _usb_write32_async;
+ rtlpriv->io.writeN_async = _usb_writeN_async;
rtlpriv->io.read8_sync = _usb_read8_sync;
rtlpriv->io.read16_sync = _usb_read16_sync;
rtlpriv->io.read32_sync = _usb_read32_sync;
+ rtlpriv->io.readN_sync = _usb_readN_sync;
}
static void _rtl_usb_io_handler_release(struct ieee80211_hw *hw)
@@ -823,7 +863,6 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb,
u8 tid = 0;
u16 seq_number = 0;
- memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
if (ieee80211_is_auth(fc)) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
rtl_ips_nic_on(hw);
diff --git a/trunk/drivers/net/wireless/rtlwifi/wifi.h b/trunk/drivers/net/wireless/rtlwifi/wifi.h
index 3126485393d9..615f6b4463e6 100644
--- a/trunk/drivers/net/wireless/rtlwifi/wifi.h
+++ b/trunk/drivers/net/wireless/rtlwifi/wifi.h
@@ -942,12 +942,16 @@ struct rtl_io {
unsigned long pci_base_addr; /*device I/O address */
void (*write8_async) (struct rtl_priv *rtlpriv, u32 addr, u8 val);
- void (*write16_async) (struct rtl_priv *rtlpriv, u32 addr, __le16 val);
- void (*write32_async) (struct rtl_priv *rtlpriv, u32 addr, __le32 val);
+ void (*write16_async) (struct rtl_priv *rtlpriv, u32 addr, u16 val);
+ void (*write32_async) (struct rtl_priv *rtlpriv, u32 addr, u32 val);
+ int (*writeN_async) (struct rtl_priv *rtlpriv, u32 addr, u16 len,
+ u8 *pdata);
u8(*read8_sync) (struct rtl_priv *rtlpriv, u32 addr);
u16(*read16_sync) (struct rtl_priv *rtlpriv, u32 addr);
u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr);
+ int (*readN_sync) (struct rtl_priv *rtlpriv, u32 addr, u16 len,
+ u8 *pdata);
};
diff --git a/trunk/drivers/net/wireless/wl1251/main.c b/trunk/drivers/net/wireless/wl1251/main.c
index ba3268ea81fe..a14a48c99cdc 100644
--- a/trunk/drivers/net/wireless/wl1251/main.c
+++ b/trunk/drivers/net/wireless/wl1251/main.c
@@ -1158,8 +1158,7 @@ static struct ieee80211_channel wl1251_channels[] = {
{ .hw_value = 13, .center_freq = 2472},
};
-static int wl1251_op_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
enum wl1251_acx_ps_scheme ps_scheme;
diff --git a/trunk/drivers/net/wireless/wl12xx/Makefile b/trunk/drivers/net/wireless/wl12xx/Makefile
index 621b3483ca2c..521c0414e52e 100644
--- a/trunk/drivers/net/wireless/wl12xx/Makefile
+++ b/trunk/drivers/net/wireless/wl12xx/Makefile
@@ -1,16 +1,16 @@
wl12xx-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \
boot.o init.o debugfs.o scan.o
-wl12xx_spi-objs = spi.o
+wl12xx_spi-objs = spi.o
wl12xx_sdio-objs = sdio.o
-wl12xx_sdio_test-objs = sdio_test.o
+wl12xx_sdio_test-objs = sdio_test.o
wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o
obj-$(CONFIG_WL12XX) += wl12xx.o
obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o
obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o
-obj-$(CONFIG_WL12XX_SDIO_TEST) += wl12xx_sdio_test.o
+obj-$(CONFIG_WL12XX_SDIO_TEST) += wl12xx_sdio_test.o
# small builtin driver bit
obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o
diff --git a/trunk/drivers/net/wireless/wl12xx/cmd.c b/trunk/drivers/net/wireless/wl12xx/cmd.c
index 287fe95ecb40..084262f169b2 100644
--- a/trunk/drivers/net/wireless/wl12xx/cmd.c
+++ b/trunk/drivers/net/wireless/wl12xx/cmd.c
@@ -661,9 +661,12 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl)
wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wl->role_id);
- /* trying to use hidden SSID with an old hostapd version */
- if (wl->ssid_len == 0 && !bss_conf->hidden_ssid) {
- wl1271_error("got a null SSID from beacon/bss");
+ /*
+ * We currently do not support hidden SSID. The real SSID
+ * should be fetched from mac80211 first.
+ */
+ if (wl->ssid_len == 0) {
+ wl1271_warning("Hidden SSID currently not supported for AP");
ret = -EINVAL;
goto out;
}
@@ -692,18 +695,9 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl)
cmd->ap.dtim_interval = bss_conf->dtim_period;
cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
cmd->channel = wl->channel;
-
- if (!bss_conf->hidden_ssid) {
- /* take the SSID from the beacon for backward compatibility */
- cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC;
- cmd->ap.ssid_len = wl->ssid_len;
- memcpy(cmd->ap.ssid, wl->ssid, wl->ssid_len);
- } else {
- cmd->ap.ssid_type = WL12XX_SSID_TYPE_HIDDEN;
- cmd->ap.ssid_len = bss_conf->ssid_len;
- memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len);
- }
-
+ cmd->ap.ssid_len = wl->ssid_len;
+ cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC;
+ memcpy(cmd->ap.ssid, wl->ssid, wl->ssid_len);
cmd->ap.local_rates = cpu_to_le32(0xffffffff);
switch (wl->band) {
@@ -1112,7 +1106,6 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl,
{
struct sk_buff *skb;
int ret;
- u32 rate;
skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
ie, ie_len);
@@ -1123,13 +1116,14 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl,
wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
- rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
if (band == IEEE80211_BAND_2GHZ)
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
- skb->data, skb->len, 0, rate);
+ skb->data, skb->len, 0,
+ wl->conf.tx.basic_rate);
else
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
- skb->data, skb->len, 0, rate);
+ skb->data, skb->len, 0,
+ wl->conf.tx.basic_rate_5);
out:
dev_kfree_skb(skb);
@@ -1140,7 +1134,6 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
struct sk_buff *skb)
{
int ret;
- u32 rate;
if (!skb)
skb = ieee80211_ap_probereq_get(wl->hw, wl->vif);
@@ -1149,13 +1142,14 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len);
- rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[wl->band]);
if (wl->band == IEEE80211_BAND_2GHZ)
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
- skb->data, skb->len, 0, rate);
+ skb->data, skb->len, 0,
+ wl->conf.tx.basic_rate);
else
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
- skb->data, skb->len, 0, rate);
+ skb->data, skb->len, 0,
+ wl->conf.tx.basic_rate_5);
if (ret < 0)
wl1271_error("Unable to set ap probe request template.");
@@ -1448,8 +1442,7 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
sta_rates |= sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET;
cmd->supported_rates =
- cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates,
- wl->band));
+ cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates));
wl1271_debug(DEBUG_CMD, "new peer rates=0x%x queues=0x%x",
cmd->supported_rates, sta->uapsd_queues);
diff --git a/trunk/drivers/net/wireless/wl12xx/conf.h b/trunk/drivers/net/wireless/wl12xx/conf.h
index 6a6805c3cc74..45428a21f9e2 100644
--- a/trunk/drivers/net/wireless/wl12xx/conf.h
+++ b/trunk/drivers/net/wireless/wl12xx/conf.h
@@ -454,10 +454,12 @@ struct conf_rx_settings {
#define CONF_TX_AP_DEFAULT_MGMT_RATES (CONF_HW_BIT_RATE_1MBPS | \
CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS)
-/* default rates for working as IBSS (11b and OFDM) */
+/*
+ * Default rates for working as IBSS. use 11b rates
+ */
#define CONF_TX_IBSS_DEFAULT_RATES (CONF_HW_BIT_RATE_1MBPS | \
CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \
- CONF_HW_BIT_RATE_11MBPS | CONF_TX_OFDM_RATES);
+ CONF_HW_BIT_RATE_11MBPS);
struct conf_tx_rate_class {
diff --git a/trunk/drivers/net/wireless/wl12xx/event.c b/trunk/drivers/net/wireless/wl12xx/event.c
index e66db69f8d17..c73fe4c6b616 100644
--- a/trunk/drivers/net/wireless/wl12xx/event.c
+++ b/trunk/drivers/net/wireless/wl12xx/event.c
@@ -181,7 +181,7 @@ static void wl1271_stop_ba_event(struct wl1271 *wl)
} else {
int i;
struct wl1271_link *lnk;
- for (i = WL1271_AP_STA_HLID_START; i < AP_MAX_LINKS; i++) {
+ for (i = WL1271_AP_STA_HLID_START; i < WL12XX_MAX_LINKS; i++) {
lnk = &wl->links[i];
if (!wl1271_is_active_sta(wl, i) || !lnk->ba_bitmap)
continue;
diff --git a/trunk/drivers/net/wireless/wl12xx/init.c b/trunk/drivers/net/wireless/wl12xx/init.c
index 04db64c94e9a..09515f5e5e1d 100644
--- a/trunk/drivers/net/wireless/wl12xx/init.c
+++ b/trunk/drivers/net/wireless/wl12xx/init.c
@@ -103,7 +103,6 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl)
{
struct wl12xx_disconn_template *tmpl;
int ret;
- u32 rate;
tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
if (!tmpl) {
@@ -114,9 +113,9 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl)
tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_DEAUTH);
- rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP,
- tmpl, sizeof(*tmpl), 0, rate);
+ tmpl, sizeof(*tmpl), 0,
+ wl1271_tx_min_rate_get(wl));
out:
kfree(tmpl);
@@ -127,7 +126,6 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl)
{
struct ieee80211_hdr_3addr *nullfunc;
int ret;
- u32 rate;
nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL);
if (!nullfunc) {
@@ -144,9 +142,9 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl)
memcpy(nullfunc->addr2, wl->mac_addr, ETH_ALEN);
memcpy(nullfunc->addr3, wl->mac_addr, ETH_ALEN);
- rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc,
- sizeof(*nullfunc), 0, rate);
+ sizeof(*nullfunc), 0,
+ wl1271_tx_min_rate_get(wl));
out:
kfree(nullfunc);
@@ -157,7 +155,6 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl)
{
struct ieee80211_qos_hdr *qosnull;
int ret;
- u32 rate;
qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL);
if (!qosnull) {
@@ -174,9 +171,9 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl)
memcpy(qosnull->addr2, wl->mac_addr, ETH_ALEN);
memcpy(qosnull->addr3, wl->mac_addr, ETH_ALEN);
- rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull,
- sizeof(*qosnull), 0, rate);
+ sizeof(*qosnull), 0,
+ wl1271_tx_min_rate_get(wl));
out:
kfree(qosnull);
@@ -501,7 +498,7 @@ int wl1271_init_ap_rates(struct wl1271 *wl)
return ret;
/* use the min basic rate for AP broadcast/multicast */
- rc.enabled_rates = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
+ rc.enabled_rates = wl1271_tx_min_rate_get(wl);
rc.short_retry_limit = 10;
rc.long_retry_limit = 10;
rc.aflags = 0;
diff --git a/trunk/drivers/net/wireless/wl12xx/main.c b/trunk/drivers/net/wireless/wl12xx/main.c
index e2d6edd2fcd2..680f5582618e 100644
--- a/trunk/drivers/net/wireless/wl12xx/main.c
+++ b/trunk/drivers/net/wireless/wl12xx/main.c
@@ -2099,8 +2099,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
wl->time_offset = 0;
wl->session_counter = 0;
wl->rate_set = CONF_TX_RATE_MASK_BASIC;
- wl->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate;
- wl->bitrate_masks[IEEE80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5;
wl->vif = NULL;
wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
wl1271_free_ap_keys(wl);
@@ -2239,8 +2237,14 @@ static int wl1271_unjoin(struct wl1271 *wl)
static void wl1271_set_band_rate(struct wl1271 *wl)
{
- wl->basic_rate_set = wl->bitrate_masks[wl->band];
- wl->rate_set = wl->basic_rate_set;
+ if (wl->band == IEEE80211_BAND_2GHZ) {
+ wl->basic_rate_set = wl->conf.tx.basic_rate;
+ wl->rate_set = wl->conf.tx.basic_rate;
+ } else {
+ wl->basic_rate_set = wl->conf.tx.basic_rate_5;
+ wl->rate_set = wl->conf.tx.basic_rate_5;
+ }
+
}
static bool wl12xx_is_roc(struct wl1271 *wl)
@@ -2269,7 +2273,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle)
if (ret < 0)
goto out;
}
- wl->rate_set = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
+ wl->rate_set = wl1271_tx_min_rate_get(wl);
ret = wl1271_acx_sta_rate_policies(wl);
if (ret < 0)
goto out;
@@ -2351,8 +2355,6 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
if (changed & IEEE80211_CONF_CHANGE_CHANNEL &&
((wl->band != conf->channel->band) ||
(wl->channel != channel))) {
- /* send all pending packets */
- wl1271_tx_work_locked(wl);
wl->band = conf->channel->band;
wl->channel = channel;
@@ -2366,8 +2368,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
wl1271_set_band_rate(wl);
- wl->basic_rate =
- wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
+ wl->basic_rate = wl1271_tx_min_rate_get(wl);
ret = wl1271_acx_sta_rate_policies(wl);
if (ret < 0)
wl1271_warning("rate policy for channel "
@@ -3068,93 +3069,6 @@ static int wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb,
return 0;
}
-static void wl12xx_remove_ie(struct sk_buff *skb, u8 eid, int ieoffset)
-{
- int len;
- const u8 *next, *end = skb->data + skb->len;
- u8 *ie = (u8 *)cfg80211_find_ie(eid, skb->data + ieoffset,
- skb->len - ieoffset);
- if (!ie)
- return;
- len = ie[1] + 2;
- next = ie + len;
- memmove(ie, next, end - next);
- skb_trim(skb, skb->len - len);
-}
-
-static void wl12xx_remove_vendor_ie(struct sk_buff *skb,
- unsigned int oui, u8 oui_type,
- int ieoffset)
-{
- int len;
- const u8 *next, *end = skb->data + skb->len;
- u8 *ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
- skb->data + ieoffset,
- skb->len - ieoffset);
- if (!ie)
- return;
- len = ie[1] + 2;
- next = ie + len;
- memmove(ie, next, end - next);
- skb_trim(skb, skb->len - len);
-}
-
-static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl,
- u8 *probe_rsp_data,
- size_t probe_rsp_len,
- u32 rates)
-{
- struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf;
- u8 probe_rsp_templ[WL1271_CMD_TEMPL_MAX_SIZE];
- int ssid_ie_offset, ie_offset, templ_len;
- const u8 *ptr;
-
- /* no need to change probe response if the SSID is set correctly */
- if (wl->ssid_len > 0)
- return wl1271_cmd_template_set(wl,
- CMD_TEMPL_AP_PROBE_RESPONSE,
- probe_rsp_data,
- probe_rsp_len, 0,
- rates);
-
- if (probe_rsp_len + bss_conf->ssid_len > WL1271_CMD_TEMPL_MAX_SIZE) {
- wl1271_error("probe_rsp template too big");
- return -EINVAL;
- }
-
- /* start searching from IE offset */
- ie_offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
-
- ptr = cfg80211_find_ie(WLAN_EID_SSID, probe_rsp_data + ie_offset,
- probe_rsp_len - ie_offset);
- if (!ptr) {
- wl1271_error("No SSID in beacon!");
- return -EINVAL;
- }
-
- ssid_ie_offset = ptr - probe_rsp_data;
- ptr += (ptr[1] + 2);
-
- memcpy(probe_rsp_templ, probe_rsp_data, ssid_ie_offset);
-
- /* insert SSID from bss_conf */
- probe_rsp_templ[ssid_ie_offset] = WLAN_EID_SSID;
- probe_rsp_templ[ssid_ie_offset + 1] = bss_conf->ssid_len;
- memcpy(probe_rsp_templ + ssid_ie_offset + 2,
- bss_conf->ssid, bss_conf->ssid_len);
- templ_len = ssid_ie_offset + 2 + bss_conf->ssid_len;
-
- memcpy(probe_rsp_templ + ssid_ie_offset + 2 + bss_conf->ssid_len,
- ptr, probe_rsp_len - (ptr - probe_rsp_data));
- templ_len += probe_rsp_len - (ptr - probe_rsp_data);
-
- return wl1271_cmd_template_set(wl,
- CMD_TEMPL_AP_PROBE_RESPONSE,
- probe_rsp_templ,
- templ_len, 0,
- rates);
-}
-
static int wl1271_bss_erp_info_changed(struct wl1271 *wl,
struct ieee80211_bss_conf *bss_conf,
u32 changed)
@@ -3211,7 +3125,6 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
if ((changed & BSS_CHANGED_BEACON)) {
struct ieee80211_hdr *hdr;
- u32 min_rate;
int ieoffset = offsetof(struct ieee80211_mgmt,
u.beacon.variable);
struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif);
@@ -3227,46 +3140,28 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
dev_kfree_skb(beacon);
goto out;
}
- min_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON :
CMD_TEMPL_BEACON;
ret = wl1271_cmd_template_set(wl, tmpl_id,
beacon->data,
beacon->len, 0,
- min_rate);
+ wl1271_tx_min_rate_get(wl));
if (ret < 0) {
dev_kfree_skb(beacon);
goto out;
}
- /* remove TIM ie from probe response */
- wl12xx_remove_ie(beacon, WLAN_EID_TIM, ieoffset);
-
- /*
- * remove p2p ie from probe response.
- * the fw reponds to probe requests that don't include
- * the p2p ie. probe requests with p2p ie will be passed,
- * and will be responded by the supplicant (the spec
- * forbids including the p2p ie when responding to probe
- * requests that didn't include it).
- */
- wl12xx_remove_vendor_ie(beacon, WLAN_OUI_WFA,
- WLAN_OUI_TYPE_WFA_P2P, ieoffset);
-
hdr = (struct ieee80211_hdr *) beacon->data;
hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_PROBE_RESP);
- if (is_ap)
- ret = wl1271_ap_set_probe_resp_tmpl(wl,
- beacon->data,
- beacon->len,
- min_rate);
- else
- ret = wl1271_cmd_template_set(wl,
- CMD_TEMPL_PROBE_RESPONSE,
- beacon->data,
- beacon->len, 0,
- min_rate);
+
+ tmpl_id = is_ap ? CMD_TEMPL_AP_PROBE_RESPONSE :
+ CMD_TEMPL_PROBE_RESPONSE;
+ ret = wl1271_cmd_template_set(wl,
+ tmpl_id,
+ beacon->data,
+ beacon->len, 0,
+ wl1271_tx_min_rate_get(wl));
dev_kfree_skb(beacon);
if (ret < 0)
goto out;
@@ -3287,10 +3182,8 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
if ((changed & BSS_CHANGED_BASIC_RATES)) {
u32 rates = bss_conf->basic_rates;
- wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates,
- wl->band);
- wl->basic_rate = wl1271_tx_min_rate_get(wl,
- wl->basic_rate_set);
+ wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates);
+ wl->basic_rate = wl1271_tx_min_rate_get(wl);
ret = wl1271_init_ap_rates(wl);
if (ret < 0) {
@@ -3472,15 +3365,12 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
* to use with control frames.
*/
rates = bss_conf->basic_rates;
- wl->basic_rate_set =
- wl1271_tx_enabled_rates_get(wl, rates,
- wl->band);
- wl->basic_rate =
- wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
+ wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
+ rates);
+ wl->basic_rate = wl1271_tx_min_rate_get(wl);
if (sta_rate_set)
wl->rate_set = wl1271_tx_enabled_rates_get(wl,
- sta_rate_set,
- wl->band);
+ sta_rate_set);
ret = wl1271_acx_sta_rate_policies(wl);
if (ret < 0)
goto out;
@@ -3527,8 +3417,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
/* revert back to minimum rates for the current band */
wl1271_set_band_rate(wl);
- wl->basic_rate =
- wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
+ wl->basic_rate = wl1271_tx_min_rate_get(wl);
ret = wl1271_acx_sta_rate_policies(wl);
if (ret < 0)
goto out;
@@ -3579,13 +3468,11 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
if (bss_conf->ibss_joined) {
u32 rates = bss_conf->basic_rates;
- wl->basic_rate_set =
- wl1271_tx_enabled_rates_get(wl, rates,
- wl->band);
- wl->basic_rate =
- wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
+ wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
+ rates);
+ wl->basic_rate = wl1271_tx_min_rate_get(wl);
- /* by default, use 11b + OFDM rates */
+ /* by default, use 11b rates */
wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES;
ret = wl1271_acx_sta_rate_policies(wl);
if (ret < 0)
@@ -3744,8 +3631,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
mutex_unlock(&wl->mutex);
}
-static int wl1271_op_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct wl1271 *wl = hw->priv;
@@ -3816,8 +3702,7 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw,
return ret;
}
-static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw)
{
struct wl1271 *wl = hw->priv;
@@ -4107,29 +3992,6 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
return ret;
}
-static int wl12xx_set_bitrate_mask(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- const struct cfg80211_bitrate_mask *mask)
-{
- struct wl1271 *wl = hw->priv;
- int i;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 set_bitrate_mask 0x%x 0x%x",
- mask->control[NL80211_BAND_2GHZ].legacy,
- mask->control[NL80211_BAND_5GHZ].legacy);
-
- mutex_lock(&wl->mutex);
-
- for (i = 0; i < IEEE80211_NUM_BANDS; i++)
- wl->bitrate_masks[i] =
- wl1271_tx_enabled_rates_get(wl,
- mask->control[i].legacy,
- i);
- mutex_unlock(&wl->mutex);
-
- return 0;
-}
-
static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
{
struct wl1271 *wl = hw->priv;
@@ -4405,7 +4267,6 @@ static const struct ieee80211_ops wl1271_ops = {
.sta_remove = wl1271_op_sta_remove,
.ampdu_action = wl1271_op_ampdu_action,
.tx_frames_pending = wl1271_tx_frames_pending,
- .set_bitrate_mask = wl12xx_set_bitrate_mask,
CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
};
@@ -4724,8 +4585,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
int i, j, ret;
unsigned int order;
- BUILD_BUG_ON(AP_MAX_LINKS > WL12XX_MAX_LINKS);
-
hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
if (!hw) {
wl1271_error("could not alloc ieee80211_hw");
@@ -4828,8 +4687,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
/* Apply default driver configuration. */
wl1271_conf_init(wl);
- wl->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate;
- wl->bitrate_masks[IEEE80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5;
order = get_order(WL1271_AGGR_BUFFER_SIZE);
wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
diff --git a/trunk/drivers/net/wireless/wl12xx/scan.c b/trunk/drivers/net/wireless/wl12xx/scan.c
index 128ccb79318c..eeccc9f095bb 100644
--- a/trunk/drivers/net/wireless/wl12xx/scan.c
+++ b/trunk/drivers/net/wireless/wl12xx/scan.c
@@ -28,7 +28,6 @@
#include "scan.h"
#include "acx.h"
#include "ps.h"
-#include "tx.h"
void wl1271_scan_complete_work(struct work_struct *work)
{
@@ -100,18 +99,14 @@ static int wl1271_get_scan_channels(struct wl1271 *wl,
for (i = 0, j = 0;
i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS;
i++) {
+
flags = req->channels[i]->flags;
if (!test_bit(i, wl->scan.scanned_ch) &&
!(flags & IEEE80211_CHAN_DISABLED) &&
- (req->channels[i]->band == band) &&
- /*
- * In passive scans, we scan all remaining
- * channels, even if not marked as such.
- * In active scans, we only scan channels not
- * marked as passive.
- */
- (passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) {
+ ((!!(flags & IEEE80211_CHAN_PASSIVE_SCAN)) == passive) &&
+ (req->channels[i]->band == band)) {
+
wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
req->channels[i]->band,
req->channels[i]->center_freq);
@@ -163,10 +158,6 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
int ret;
u16 scan_options = 0;
- /* skip active scans if we don't have SSIDs */
- if (!passive && wl->scan.req->n_ssids == 0)
- return WL1271_NOTHING_TO_SCAN;
-
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
if (!cmd || !trigger) {
@@ -174,7 +165,8 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
goto out;
}
- if (passive)
+ /* No SSIDs means that we have a forced passive scan */
+ if (passive || wl->scan.req->n_ssids == 0)
scan_options |= WL1271_SCAN_OPT_PASSIVE;
if (WARN_ON(wl->role_id == WL12XX_INVALID_ROLE_ID)) {
@@ -244,17 +236,14 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
void wl1271_scan_stm(struct wl1271 *wl)
{
int ret = 0;
- enum ieee80211_band band;
- u32 rate;
switch (wl->scan.state) {
case WL1271_SCAN_STATE_IDLE:
break;
case WL1271_SCAN_STATE_2GHZ_ACTIVE:
- band = IEEE80211_BAND_2GHZ;
- rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
- ret = wl1271_scan_send(wl, band, false, rate);
+ ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, false,
+ wl->conf.tx.basic_rate);
if (ret == WL1271_NOTHING_TO_SCAN) {
wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE;
wl1271_scan_stm(wl);
@@ -263,9 +252,8 @@ void wl1271_scan_stm(struct wl1271 *wl)
break;
case WL1271_SCAN_STATE_2GHZ_PASSIVE:
- band = IEEE80211_BAND_2GHZ;
- rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
- ret = wl1271_scan_send(wl, band, true, rate);
+ ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true,
+ wl->conf.tx.basic_rate);
if (ret == WL1271_NOTHING_TO_SCAN) {
if (wl->enable_11a)
wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
@@ -277,9 +265,8 @@ void wl1271_scan_stm(struct wl1271 *wl)
break;
case WL1271_SCAN_STATE_5GHZ_ACTIVE:
- band = IEEE80211_BAND_5GHZ;
- rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
- ret = wl1271_scan_send(wl, band, false, rate);
+ ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, false,
+ wl->conf.tx.basic_rate_5);
if (ret == WL1271_NOTHING_TO_SCAN) {
wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE;
wl1271_scan_stm(wl);
@@ -288,9 +275,8 @@ void wl1271_scan_stm(struct wl1271 *wl)
break;
case WL1271_SCAN_STATE_5GHZ_PASSIVE:
- band = IEEE80211_BAND_5GHZ;
- rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
- ret = wl1271_scan_send(wl, band, true, rate);
+ ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, true,
+ wl->conf.tx.basic_rate_5);
if (ret == WL1271_NOTHING_TO_SCAN) {
wl->scan.state = WL1271_SCAN_STATE_DONE;
wl1271_scan_stm(wl);
diff --git a/trunk/drivers/net/wireless/wl12xx/sdio_test.c b/trunk/drivers/net/wireless/wl12xx/sdio_test.c
index f25d5d9212e7..c3610492852e 100644
--- a/trunk/drivers/net/wireless/wl12xx/sdio_test.c
+++ b/trunk/drivers/net/wireless/wl12xx/sdio_test.c
@@ -30,7 +30,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -143,23 +142,14 @@ static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
ret = pm_runtime_get_sync(&func->dev);
if (ret < 0)
goto out;
-
- /* Runtime PM might be disabled, power up the card manually */
- ret = mmc_power_restore_host(func->card->host);
- if (ret < 0)
- goto out;
-
sdio_claim_host(func);
sdio_enable_func(func);
+ sdio_release_host(func);
} else {
+ sdio_claim_host(func);
sdio_disable_func(func);
sdio_release_host(func);
- /* Runtime PM might be disabled, power off the card manually */
- ret = mmc_power_save_host(func->card->host);
- if (ret < 0)
- goto out;
-
/* Power down the card */
ret = pm_runtime_put_sync(&func->dev);
}
@@ -443,6 +433,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,
sdio_set_drvdata(func, wl_test);
+
/* power up the device */
ret = wl1271_chip_wakeup(wl);
if (ret) {
diff --git a/trunk/drivers/net/wireless/wl12xx/tx.c b/trunk/drivers/net/wireless/wl12xx/tx.c
index bad9e29d49b0..9d4157ce0950 100644
--- a/trunk/drivers/net/wireless/wl12xx/tx.c
+++ b/trunk/drivers/net/wireless/wl12xx/tx.c
@@ -81,7 +81,8 @@ static int wl1271_tx_update_filters(struct wl1271 *wl,
struct ieee80211_hdr *hdr;
int ret;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr *)(skb->data +
+ sizeof(struct wl1271_tx_hw_descr));
/*
* stop bssid-based filtering before transmitting authentication
@@ -180,20 +181,14 @@ u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct sk_buff *skb)
static u8 wl1271_tx_get_hlid(struct wl1271 *wl, struct sk_buff *skb)
{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-
if (wl12xx_is_dummy_packet(wl, skb))
return wl->system_hlid;
if (wl->bss_type == BSS_TYPE_AP_BSS)
return wl12xx_tx_get_hlid_ap(wl, skb);
- wl1271_tx_update_filters(wl, skb);
-
- if ((test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) ||
- test_bit(WL1271_FLAG_IBSS_JOINED, &wl->flags)) &&
- !ieee80211_is_auth(hdr->frame_control) &&
- !ieee80211_is_assoc_req(hdr->frame_control))
+ if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) ||
+ test_bit(WL1271_FLAG_IBSS_JOINED, &wl->flags))
return wl->sta_hlid;
else
return wl->dev_hlid;
@@ -428,6 +423,8 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
if (wl->bss_type == BSS_TYPE_AP_BSS) {
wl1271_tx_ap_update_inconnection_sta(wl, skb);
wl1271_tx_regulate_link(wl, hlid);
+ } else {
+ wl1271_tx_update_filters(wl, skb);
}
/*
@@ -450,14 +447,13 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
return total_len;
}
-u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set,
- enum ieee80211_band rate_band)
+u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
{
struct ieee80211_supported_band *band;
u32 enabled_rates = 0;
int bit;
- band = wl->hw->wiphy->bands[rate_band];
+ band = wl->hw->wiphy->bands[wl->band];
for (bit = 0; bit < band->n_bitrates; bit++) {
if (rate_set & 0x1)
enabled_rates |= band->bitrates[bit].hw_value;
@@ -990,10 +986,20 @@ void wl1271_tx_flush(struct wl1271 *wl)
wl1271_warning("Unable to flush all TX buffers, timed out.");
}
-u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set)
+u32 wl1271_tx_min_rate_get(struct wl1271 *wl)
{
- if (WARN_ON(!rate_set))
- return 0;
+ int i;
+ u32 rate = 0;
+
+ if (!wl->basic_rate_set) {
+ WARN_ON(1);
+ wl->basic_rate_set = wl->conf.tx.basic_rate;
+ }
+
+ for (i = 0; !rate; i++) {
+ if ((wl->basic_rate_set >> i) & 0x1)
+ rate = 1 << i;
+ }
- return BIT(__ffs(rate_set));
+ return rate;
}
diff --git a/trunk/drivers/net/wireless/wl12xx/tx.h b/trunk/drivers/net/wireless/wl12xx/tx.h
index dc4f09adf088..d6fdbf904a09 100644
--- a/trunk/drivers/net/wireless/wl12xx/tx.h
+++ b/trunk/drivers/net/wireless/wl12xx/tx.h
@@ -209,9 +209,8 @@ void wl1271_tx_complete(struct wl1271 *wl);
void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues);
void wl1271_tx_flush(struct wl1271 *wl);
u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
-u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set,
- enum ieee80211_band rate_band);
-u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set);
+u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
+u32 wl1271_tx_min_rate_get(struct wl1271 *wl);
u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct sk_buff *skb);
void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid);
void wl1271_handle_tx_low_watermark(struct wl1271 *wl);
diff --git a/trunk/drivers/net/wireless/wl12xx/wl12xx.h b/trunk/drivers/net/wireless/wl12xx/wl12xx.h
index 997f53245011..3ceb20c170bc 100644
--- a/trunk/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/trunk/drivers/net/wireless/wl12xx/wl12xx.h
@@ -138,7 +138,7 @@ extern u32 wl12xx_debug_level;
#define WL1271_DEFAULT_DTIM_PERIOD 1
#define WL12XX_MAX_ROLES 4
-#define WL12XX_MAX_LINKS 12
+#define WL12XX_MAX_LINKS 8
#define WL12XX_INVALID_ROLE_ID 0xff
#define WL12XX_INVALID_LINK_ID 0xff
@@ -279,7 +279,7 @@ struct wl12xx_fw_status {
/* Cumulative counter of released Voice memory blocks */
u8 tx_voice_released_blks;
- u8 padding_1[3];
+ u8 padding_1[7];
__le32 log_start_addr;
} __packed;
@@ -526,7 +526,6 @@ struct wl1271 {
u32 basic_rate_set;
u32 basic_rate;
u32 rate_set;
- u32 bitrate_masks[IEEE80211_NUM_BANDS];
/* The current band */
enum ieee80211_band band;
diff --git a/trunk/drivers/net/wireless/wl3501_cs.c b/trunk/drivers/net/wireless/wl3501_cs.c
index 98fbf54f6004..6bc7c92fbff7 100644
--- a/trunk/drivers/net/wireless/wl3501_cs.c
+++ b/trunk/drivers/net/wireless/wl3501_cs.c
@@ -1781,7 +1781,7 @@ static int wl3501_get_encode(struct net_device *dev,
keys, len_keys);
if (rc)
goto out;
- tocopy = min_t(u16, len_keys, wrqu->encoding.length);
+ tocopy = min_t(u8, len_keys, wrqu->encoding.length);
tocopy = min_t(u8, tocopy, 100);
wrqu->encoding.length = tocopy;
memcpy(extra, keys, tocopy);
diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_mac.c b/trunk/drivers/net/wireless/zd1211rw/zd_mac.c
index 0a70149df3fc..cabfae1e70b1 100644
--- a/trunk/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/trunk/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -1332,7 +1332,7 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
}
}
-static u64 zd_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+static u64 zd_op_get_tsf(struct ieee80211_hw *hw)
{
struct zd_mac *mac = zd_hw_mac(hw);
return zd_chip_get_tsf(&mac->chip);
diff --git a/trunk/drivers/nfc/Kconfig b/trunk/drivers/nfc/Kconfig
index 5af959274d4e..8a56fd3da989 100644
--- a/trunk/drivers/nfc/Kconfig
+++ b/trunk/drivers/nfc/Kconfig
@@ -29,7 +29,7 @@ config NFC_PN533
config NFC_WILINK
tristate "Texas Instruments NFC WiLink driver"
- depends on TI_ST && NFC_NCI
+ depends on TI_ST
help
This enables the NFC driver for Texas Instrument's BT/FM/GPS/NFC
combo devices. This makes use of shared transport line discipline
diff --git a/trunk/drivers/staging/brcm80211/brcmsmac/mac80211_if.c b/trunk/drivers/staging/brcm80211/brcmsmac/mac80211_if.c
index 6d71cba3a0a5..d6de44e430d3 100644
--- a/trunk/drivers/staging/brcm80211/brcmsmac/mac80211_if.c
+++ b/trunk/drivers/staging/brcm80211/brcmsmac/mac80211_if.c
@@ -133,19 +133,16 @@ static int brcms_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
bool set);
static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw);
static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw);
-static void brcms_ops_set_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u64 tsf);
+static void brcms_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf);
static int brcms_ops_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats);
static void brcms_ops_sta_notify(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
enum sta_notify_cmd cmd,
struct ieee80211_sta *sta);
-static int brcms_ops_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
- const struct ieee80211_tx_queue_params *params);
-static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif);
+static int brcms_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *params);
+static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw);
static int brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
static int brcms_ops_sta_remove(struct ieee80211_hw *hw,
@@ -519,8 +516,7 @@ static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw)
return;
}
-static void brcms_ops_set_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u64 tsf)
+static void brcms_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf)
{
wiphy_err(hw->wiphy, "%s: Enter\n", __func__);
return;
@@ -557,7 +553,7 @@ brcms_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}
static int
-brcms_ops_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
+brcms_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct brcms_info *wl = hw->priv;
@@ -569,8 +565,7 @@ brcms_ops_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
return 0;
}
-static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw)
{
wiphy_err(hw->wiphy, "%s: Enter\n", __func__);
return 0;
diff --git a/trunk/drivers/staging/winbond/wbusb.c b/trunk/drivers/staging/winbond/wbusb.c
index a2e8bd452ed9..3724e1e67ec2 100644
--- a/trunk/drivers/staging/winbond/wbusb.c
+++ b/trunk/drivers/staging/winbond/wbusb.c
@@ -277,7 +277,7 @@ static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
return 0;
}
-static u64 wbsoft_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif)
+static u64 wbsoft_get_tsf(struct ieee80211_hw *dev)
{
printk("wbsoft_get_tsf called\n");
return 0;
diff --git a/trunk/include/linux/ieee80211.h b/trunk/include/linux/ieee80211.h
index 48363c3c40f8..b5e0a5c344fd 100644
--- a/trunk/include/linux/ieee80211.h
+++ b/trunk/include/linux/ieee80211.h
@@ -759,12 +759,6 @@ struct ieee80211_mgmt {
u8 action;
u8 smps_control;
} __attribute__ ((packed)) ht_smps;
- struct {
- u8 action_code;
- u8 dialog_token;
- __le16 capability;
- u8 variable[0];
- } __packed tdls_discover_resp;
} u;
} __attribute__ ((packed)) action;
} u;
@@ -811,52 +805,6 @@ struct ieee80211_pspoll {
u8 ta[6];
} __attribute__ ((packed));
-/* TDLS */
-
-/* Link-id information element */
-struct ieee80211_tdls_lnkie {
- u8 ie_type; /* Link Identifier IE */
- u8 ie_len;
- u8 bssid[6];
- u8 init_sta[6];
- u8 resp_sta[6];
-} __packed;
-
-struct ieee80211_tdls_data {
- u8 da[6];
- u8 sa[6];
- __be16 ether_type;
- u8 payload_type;
- u8 category;
- u8 action_code;
- union {
- struct {
- u8 dialog_token;
- __le16 capability;
- u8 variable[0];
- } __packed setup_req;
- struct {
- __le16 status_code;
- u8 dialog_token;
- __le16 capability;
- u8 variable[0];
- } __packed setup_resp;
- struct {
- __le16 status_code;
- u8 dialog_token;
- u8 variable[0];
- } __packed setup_cfm;
- struct {
- __le16 reason_code;
- u8 variable[0];
- } __packed teardown;
- struct {
- u8 dialog_token;
- u8 variable[0];
- } __packed discover_req;
- } u;
-} __packed;
-
/**
* struct ieee80211_bar - HT Block Ack Request
*
@@ -1248,8 +1196,6 @@ enum ieee80211_eid {
WLAN_EID_TS_DELAY = 43,
WLAN_EID_TCLAS_PROCESSING = 44,
WLAN_EID_QOS_CAPA = 46,
- /* 802.11z */
- WLAN_EID_LINK_ID = 101,
/* 802.11s */
WLAN_EID_MESH_CONFIG = 113,
WLAN_EID_MESH_ID = 114,
@@ -1333,7 +1279,6 @@ enum ieee80211_category {
WLAN_CATEGORY_HT = 7,
WLAN_CATEGORY_SA_QUERY = 8,
WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9,
- WLAN_CATEGORY_TDLS = 12,
WLAN_CATEGORY_MESH_ACTION = 13,
WLAN_CATEGORY_MULTIHOP_ACTION = 14,
WLAN_CATEGORY_SELF_PROTECTED = 15,
@@ -1397,36 +1342,6 @@ enum ieee80211_key_len {
WLAN_KEY_LEN_AES_CMAC = 16,
};
-/* Public action codes */
-enum ieee80211_pub_actioncode {
- WLAN_PUB_ACTION_TDLS_DISCOVER_RES = 14,
-};
-
-/* TDLS action codes */
-enum ieee80211_tdls_actioncode {
- WLAN_TDLS_SETUP_REQUEST = 0,
- WLAN_TDLS_SETUP_RESPONSE = 1,
- WLAN_TDLS_SETUP_CONFIRM = 2,
- WLAN_TDLS_TEARDOWN = 3,
- WLAN_TDLS_PEER_TRAFFIC_INDICATION = 4,
- WLAN_TDLS_CHANNEL_SWITCH_REQUEST = 5,
- WLAN_TDLS_CHANNEL_SWITCH_RESPONSE = 6,
- WLAN_TDLS_PEER_PSM_REQUEST = 7,
- WLAN_TDLS_PEER_PSM_RESPONSE = 8,
- WLAN_TDLS_PEER_TRAFFIC_RESPONSE = 9,
- WLAN_TDLS_DISCOVERY_REQUEST = 10,
-};
-
-/*
- * TDLS capabililites to be enabled in the 5th byte of the
- * @WLAN_EID_EXT_CAPABILITY information element
- */
-#define WLAN_EXT_CAPA5_TDLS_ENABLED BIT(5)
-#define WLAN_EXT_CAPA5_TDLS_PROHIBITED BIT(6)
-
-/* TDLS specific payload type in the LLC/SNAP header */
-#define WLAN_TDLS_SNAP_RFTYPE 0x2
-
/**
* enum - mesh path selection protocol identifier
*
diff --git a/trunk/include/linux/if_ether.h b/trunk/include/linux/if_ether.h
index 49c38fc8dbc3..a3d99ff6e3b5 100644
--- a/trunk/include/linux/if_ether.h
+++ b/trunk/include/linux/if_ether.h
@@ -83,7 +83,6 @@
#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */
#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
-#define ETH_P_TDLS 0x890D /* TDLS */
#define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */
#define ETH_P_QINQ1 0x9100 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_QINQ2 0x9200 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
diff --git a/trunk/include/linux/nl80211.h b/trunk/include/linux/nl80211.h
index 9d797f253d8e..460b12a8ef66 100644
--- a/trunk/include/linux/nl80211.h
+++ b/trunk/include/linux/nl80211.h
@@ -238,8 +238,6 @@
*
* @NL80211_CMD_GET_SCAN: get scan results
* @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters
- * %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the
- * probe requests at CCK rate or not.
* @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to
* NL80211_CMD_GET_SCAN and on the "scan" multicast group)
* @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
@@ -434,8 +432,6 @@
* specified using %NL80211_ATTR_DURATION. When called, this operation
* returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the
* TX status event pertaining to the TX request.
- * %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the
- * management frames at CCK rate or not in 2GHz band.
* @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this
* command may be used with the corresponding cookie to cancel the wait
* time if it is known that it is no longer necessary.
@@ -506,9 +502,6 @@
* @NL80211_CMD_PMKSA_CANDIDATE: This is used as an event to inform userspace
* of PMKSA caching dandidates.
*
- * @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup).
- * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame.
- *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -635,9 +628,6 @@ enum nl80211_commands {
NL80211_CMD_PMKSA_CANDIDATE,
- NL80211_CMD_TDLS_OPER,
- NL80211_CMD_TDLS_MGMT,
-
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -1088,27 +1078,6 @@ enum nl80211_commands {
* @NL80211_ATTR_PMKSA_CANDIDATE: Nested attribute containing the PMKSA caching
* candidate information, see &enum nl80211_pmksa_candidate_attr.
*
- * @NL80211_ATTR_TX_NO_CCK_RATE: Indicates whether to use CCK rate or not
- * for management frames transmission. In order to avoid p2p probe/action
- * frames are being transmitted at CCK rate in 2GHz band, the user space
- * applications use this attribute.
- * This attribute is used with %NL80211_CMD_TRIGGER_SCAN and
- * %NL80211_CMD_FRAME commands.
- *
- * @NL80211_ATTR_TDLS_ACTION: Low level TDLS action code (e.g. link setup
- * request, link setup confirm, link teardown, etc.). Values are
- * described in the TDLS (802.11z) specification.
- * @NL80211_ATTR_TDLS_DIALOG_TOKEN: Non-zero token for uniquely identifying a
- * TDLS conversation between two devices.
- * @NL80211_ATTR_TDLS_OPERATION: High level TDLS operation; see
- * &enum nl80211_tdls_operation, represented as a u8.
- * @NL80211_ATTR_TDLS_SUPPORT: A flag indicating the device can operate
- * as a TDLS peer sta.
- * @NL80211_ATTR_TDLS_EXTERNAL_SETUP: The TDLS discovery/setup and teardown
- * procedures should be performed by sending TDLS packets via
- * %NL80211_CMD_TDLS_MGMT. Otherwise %NL80211_CMD_TDLS_OPER should be
- * used for asking the driver to perform a TDLS operation.
- *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1329,14 +1298,6 @@ enum nl80211_attrs {
NL80211_ATTR_PMKSA_CANDIDATE,
- NL80211_ATTR_TX_NO_CCK_RATE,
-
- NL80211_ATTR_TDLS_ACTION,
- NL80211_ATTR_TDLS_DIALOG_TOKEN,
- NL80211_ATTR_TDLS_OPERATION,
- NL80211_ATTR_TDLS_SUPPORT,
- NL80211_ATTR_TDLS_EXTERNAL_SETUP,
-
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -1434,7 +1395,6 @@ enum nl80211_iftype {
* @NL80211_STA_FLAG_WME: station is WME/QoS capable
* @NL80211_STA_FLAG_MFP: station uses management frame protection
* @NL80211_STA_FLAG_AUTHENTICATED: station is authenticated
- * @NL80211_STA_FLAG_TDLS_PEER: station is a TDLS peer
* @NL80211_STA_FLAG_MAX: highest station flag number currently defined
* @__NL80211_STA_FLAG_AFTER_LAST: internal use
*/
@@ -1445,7 +1405,6 @@ enum nl80211_sta_flags {
NL80211_STA_FLAG_WME,
NL80211_STA_FLAG_MFP,
NL80211_STA_FLAG_AUTHENTICATED,
- NL80211_STA_FLAG_TDLS_PEER,
/* keep last */
__NL80211_STA_FLAG_AFTER_LAST,
@@ -2632,20 +2591,4 @@ enum nl80211_pmksa_candidate_attr {
MAX_NL80211_PMKSA_CANDIDATE = NUM_NL80211_PMKSA_CANDIDATE - 1
};
-/**
- * enum nl80211_tdls_operation - values for %NL80211_ATTR_TDLS_OPERATION
- * @NL80211_TDLS_DISCOVERY_REQ: Send a TDLS discovery request
- * @NL80211_TDLS_SETUP: Setup TDLS link
- * @NL80211_TDLS_TEARDOWN: Teardown a TDLS link which is already established
- * @NL80211_TDLS_ENABLE_LINK: Enable TDLS link
- * @NL80211_TDLS_DISABLE_LINK: Disable TDLS link
- */
-enum nl80211_tdls_operation {
- NL80211_TDLS_DISCOVERY_REQ,
- NL80211_TDLS_SETUP,
- NL80211_TDLS_TEARDOWN,
- NL80211_TDLS_ENABLE_LINK,
- NL80211_TDLS_DISABLE_LINK,
-};
-
#endif /* __LINUX_NL80211_H */
diff --git a/trunk/include/linux/rfkill-gpio.h b/trunk/include/linux/rfkill-gpio.h
index 4d09f6eab359..a175d0598033 100644
--- a/trunk/include/linux/rfkill-gpio.h
+++ b/trunk/include/linux/rfkill-gpio.h
@@ -30,8 +30,6 @@
* @reset_gpio: GPIO which is used for reseting rfkill switch
* @shutdown_gpio: GPIO which is used for shutdown of rfkill switch
* @power_clk_name: [optional] name of clk to turn off while blocked
- * @gpio_runtime_close: clean up platform specific gpio configuration
- * @gpio_runtime_setup: set up platform specific gpio configuration
*/
struct rfkill_gpio_platform_data {
@@ -40,8 +38,6 @@ struct rfkill_gpio_platform_data {
int shutdown_gpio;
const char *power_clk_name;
enum rfkill_type type;
- void (*gpio_runtime_close)(struct platform_device *);
- int (*gpio_runtime_setup)(struct platform_device *);
};
#endif /* __RFKILL_GPIO_H */
diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h
index 74f4f85be32f..ccfdf3f63ce5 100644
--- a/trunk/include/net/cfg80211.h
+++ b/trunk/include/net/cfg80211.h
@@ -423,17 +423,6 @@ enum plink_actions {
PLINK_ACTION_BLOCK,
};
-/**
- * enum station_parameters_apply_mask - station parameter values to apply
- * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp)
- *
- * Not all station parameters have in-band "no change" signalling,
- * for those that don't these flags will are used.
- */
-enum station_parameters_apply_mask {
- STATION_PARAM_APPLY_UAPSD = BIT(0),
-};
-
/**
* struct station_parameters - station parameters
*
@@ -461,7 +450,6 @@ struct station_parameters {
u8 *supported_rates;
struct net_device *vlan;
u32 sta_flags_mask, sta_flags_set;
- u32 sta_modify_mask;
int listen_interval;
u16 aid;
u8 supported_rates_len;
@@ -872,7 +860,6 @@ struct cfg80211_ssid {
* @wiphy: the wiphy this was for
* @dev: the interface
* @aborted: (internal) scan request was notified as aborted
- * @no_cck: used to send probe requests at non CCK rate in 2GHz band
*/
struct cfg80211_scan_request {
struct cfg80211_ssid *ssids;
@@ -887,7 +874,6 @@ struct cfg80211_scan_request {
struct wiphy *wiphy;
struct net_device *dev;
bool aborted;
- bool no_cck;
/* keep last */
struct ieee80211_channel *channels[0];
@@ -1422,9 +1408,6 @@ struct cfg80211_gtk_rekey_data {
* @set_ringparam: Set tx and rx ring sizes.
*
* @get_ringparam: Get tx and rx ring current and maximum sizes.
- *
- * @tdls_mgmt: Transmit a TDLS management frame.
- * @tdls_oper: Perform a high-level TDLS operation (e.g. TDLS link setup).
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -1501,7 +1484,7 @@ struct cfg80211_ops {
int (*change_bss)(struct wiphy *wiphy, struct net_device *dev,
struct bss_parameters *params);
- int (*set_txq_params)(struct wiphy *wiphy, struct net_device *dev,
+ int (*set_txq_params)(struct wiphy *wiphy,
struct ieee80211_txq_params *params);
int (*set_channel)(struct wiphy *wiphy, struct net_device *dev,
@@ -1577,8 +1560,7 @@ struct cfg80211_ops {
struct ieee80211_channel *chan, bool offchan,
enum nl80211_channel_type channel_type,
bool channel_type_valid, unsigned int wait,
- const u8 *buf, size_t len, bool no_cck,
- u64 *cookie);
+ const u8 *buf, size_t len, u64 *cookie);
int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
struct net_device *dev,
u64 cookie);
@@ -1608,12 +1590,6 @@ struct cfg80211_ops {
int (*set_rekey_data)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_gtk_rekey_data *data);
-
- int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev,
- u8 *peer, u8 action_code, u8 dialog_token,
- u16 status_code, const u8 *buf, size_t len);
- int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev,
- u8 *peer, enum nl80211_tdls_operation oper);
};
/*
@@ -1666,12 +1642,6 @@ struct cfg80211_ops {
* @WIPHY_FLAG_SUPPORTS_FW_ROAM: The device supports roaming feature in the
* firmware.
* @WIPHY_FLAG_AP_UAPSD: The device supports uapsd on AP.
- * @WIPHY_FLAG_SUPPORTS_TDLS: The device supports TDLS (802.11z) operation.
- * @WIPHY_FLAG_TDLS_EXTERNAL_SETUP: The device does not handle TDLS (802.11z)
- * link setup/discovery operations internally. Setup, discovery and
- * teardown packets should be sent through the @NL80211_CMD_TDLS_MGMT
- * command. When this flag is not set, @NL80211_CMD_TDLS_OPER should be
- * used for asking the driver/firmware to perform a TDLS operation.
*/
enum wiphy_flags {
WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -1688,8 +1658,6 @@ enum wiphy_flags {
WIPHY_FLAG_ENFORCE_COMBINATIONS = BIT(12),
WIPHY_FLAG_SUPPORTS_FW_ROAM = BIT(13),
WIPHY_FLAG_AP_UAPSD = BIT(14),
- WIPHY_FLAG_SUPPORTS_TDLS = BIT(15),
- WIPHY_FLAG_TDLS_EXTERNAL_SETUP = BIT(16),
};
/**
diff --git a/trunk/include/net/ieee80211_radiotap.h b/trunk/include/net/ieee80211_radiotap.h
index 7e2c4d483ad0..b0be5fb9de19 100644
--- a/trunk/include/net/ieee80211_radiotap.h
+++ b/trunk/include/net/ieee80211_radiotap.h
@@ -251,7 +251,6 @@ enum ieee80211_radiotap_type {
* retries */
#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */
#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */
-#define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008 /* don't expect an ack */
/* For IEEE80211_RADIOTAP_MCS */
diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h
index cd108dfa1952..c0f63fd0c52b 100644
--- a/trunk/include/net/mac80211.h
+++ b/trunk/include/net/mac80211.h
@@ -109,7 +109,6 @@ enum ieee80211_ac_numbers {
IEEE80211_AC_BE = 2,
IEEE80211_AC_BK = 3,
};
-#define IEEE80211_NUM_ACS 4
/**
* struct ieee80211_tx_queue_params - transmit queue configuration
@@ -339,9 +338,9 @@ struct ieee80211_bss_conf {
* used to indicate that a frame was already retried due to PS
* @IEEE80211_TX_INTFL_DONT_ENCRYPT: completely internal to mac80211,
* used to indicate frame should not be encrypted
- * @IEEE80211_TX_CTL_POLL_RESPONSE: This frame is a response to a poll
- * frame (PS-Poll or uAPSD) and should be sent although the station
- * is in powersave mode.
+ * @IEEE80211_TX_CTL_PSPOLL_RESPONSE: (internal?)
+ * This frame is a response to a PS-poll frame and should be sent
+ * although the station is in powersave mode.
* @IEEE80211_TX_CTL_MORE_FRAMES: More frames will be passed to the
* transmit function after the current frame, this can be used
* by drivers to kick the DMA queue only if unset or when the
@@ -364,17 +363,6 @@ struct ieee80211_bss_conf {
* @IEEE80211_TX_INTFL_TKIP_MIC_FAILURE: Marks this packet to be used for TKIP
* testing. It will be sent out with incorrect Michael MIC key to allow
* TKIP countermeasures to be tested.
- * @IEEE80211_TX_CTL_NO_CCK_RATE: This frame will be sent at non CCK rate.
- * This flag is actually used for management frame especially for P2P
- * frames not being sent at CCK rate in 2GHz band.
- * @IEEE80211_TX_STATUS_EOSP: This packet marks the end of service period,
- * when its status is reported the service period ends. For frames in
- * an SP that mac80211 transmits, it is already set; for driver frames
- * the driver may set this flag. It is also used to do the same for
- * PS-Poll responses.
- * @IEEE80211_TX_CTL_USE_MINRATE: This frame will be sent at lowest rate.
- * This flag is used to send nullfunc frame at minimum rate when
- * the nullfunc is used for connection monitoring purpose.
*
* Note: If you have to add new flags to the enumeration, then don't
* forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary.
@@ -396,7 +384,7 @@ enum mac80211_tx_control_flags {
IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14),
IEEE80211_TX_INTFL_RETRIED = BIT(15),
IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16),
- IEEE80211_TX_CTL_POLL_RESPONSE = BIT(17),
+ IEEE80211_TX_CTL_PSPOLL_RESPONSE = BIT(17),
IEEE80211_TX_CTL_MORE_FRAMES = BIT(18),
IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19),
IEEE80211_TX_INTFL_HAS_RADIOTAP = BIT(20),
@@ -405,9 +393,6 @@ enum mac80211_tx_control_flags {
IEEE80211_TX_CTL_STBC = BIT(23) | BIT(24),
IEEE80211_TX_CTL_TX_OFFCHAN = BIT(25),
IEEE80211_TX_INTFL_TKIP_MIC_FAILURE = BIT(26),
- IEEE80211_TX_CTL_NO_CCK_RATE = BIT(27),
- IEEE80211_TX_STATUS_EOSP = BIT(28),
- IEEE80211_TX_CTL_USE_MINRATE = BIT(29),
};
#define IEEE80211_TX_CTL_STBC_SHIFT 23
@@ -421,9 +406,9 @@ enum mac80211_tx_control_flags {
IEEE80211_TX_CTL_SEND_AFTER_DTIM | IEEE80211_TX_CTL_AMPDU | \
IEEE80211_TX_STAT_TX_FILTERED | IEEE80211_TX_STAT_ACK | \
IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_STAT_AMPDU_NO_BACK | \
- IEEE80211_TX_CTL_RATE_CTRL_PROBE | IEEE80211_TX_CTL_POLL_RESPONSE | \
+ IEEE80211_TX_CTL_RATE_CTRL_PROBE | IEEE80211_TX_CTL_PSPOLL_RESPONSE | \
IEEE80211_TX_CTL_MORE_FRAMES | IEEE80211_TX_CTL_LDPC | \
- IEEE80211_TX_CTL_STBC | IEEE80211_TX_STATUS_EOSP)
+ IEEE80211_TX_CTL_STBC)
/**
* enum mac80211_rate_control_flags - per-rate flags set by the
@@ -1542,95 +1527,6 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
* This rule applies to all other FIF flags as well.
*/
-/**
- * DOC: AP support for powersaving clients
- *
- * In order to implement AP and P2P GO modes, mac80211 has support for
- * client powersaving, both "legacy" PS (PS-Poll/null data) and uAPSD.
- * There currently is no support for sAPSD.
- *
- * There is one assumption that mac80211 makes, namely that a client
- * will not poll with PS-Poll and trigger with uAPSD at the same time.
- * Both are supported, and both can be used by the same client, but
- * they can't be used concurrently by the same client. This simplifies
- * the driver code.
- *
- * The first thing to keep in mind is that there is a flag for complete
- * driver implementation: %IEEE80211_HW_AP_LINK_PS. If this flag is set,
- * mac80211 expects the driver to handle most of the state machine for
- * powersaving clients and will ignore the PM bit in incoming frames.
- * Drivers then use ieee80211_sta_ps_transition() to inform mac80211 of
- * stations' powersave transitions. In this mode, mac80211 also doesn't
- * handle PS-Poll/uAPSD.
- *
- * In the mode without %IEEE80211_HW_AP_LINK_PS, mac80211 will check the
- * PM bit in incoming frames for client powersave transitions. When a
- * station goes to sleep, we will stop transmitting to it. There is,
- * however, a race condition: a station might go to sleep while there is
- * data buffered on hardware queues. If the device has support for this
- * it will reject frames, and the driver should give the frames back to
- * mac80211 with the %IEEE80211_TX_STAT_TX_FILTERED flag set which will
- * cause mac80211 to retry the frame when the station wakes up. The
- * driver is also notified of powersave transitions by calling its
- * @sta_notify callback.
- *
- * When the station is asleep, it has three choices: it can wake up,
- * it can PS-Poll, or it can possibly start a uAPSD service period.
- * Waking up is implemented by simply transmitting all buffered (and
- * filtered) frames to the station. This is the easiest case. When
- * the station sends a PS-Poll or a uAPSD trigger frame, mac80211
- * will inform the driver of this with the @allow_buffered_frames
- * callback; this callback is optional. mac80211 will then transmit
- * the frames as usual and set the %IEEE80211_TX_CTL_POLL_RESPONSE
- * on each frame. The last frame in the service period (or the only
- * response to a PS-Poll) also has %IEEE80211_TX_STATUS_EOSP set to
- * indicate that it ends the service period; as this frame must have
- * TX status report it also sets %IEEE80211_TX_CTL_REQ_TX_STATUS.
- * When TX status is reported for this frame, the service period is
- * marked has having ended and a new one can be started by the peer.
- *
- * Another race condition can happen on some devices like iwlwifi
- * when there are frames queued for the station and it wakes up
- * or polls; the frames that are already queued could end up being
- * transmitted first instead, causing reordering and/or wrong
- * processing of the EOSP. The cause is that allowing frames to be
- * transmitted to a certain station is out-of-band communication to
- * the device. To allow this problem to be solved, the driver can
- * call ieee80211_sta_block_awake() if frames are buffered when it
- * is notified that the station went to sleep. When all these frames
- * have been filtered (see above), it must call the function again
- * to indicate that the station is no longer blocked.
- *
- * If the driver buffers frames in the driver for aggregation in any
- * way, it must use the ieee80211_sta_set_buffered() call when it is
- * notified of the station going to sleep to inform mac80211 of any
- * TIDs that have frames buffered. Note that when a station wakes up
- * this information is reset (hence the requirement to call it when
- * informed of the station going to sleep). Then, when a service
- * period starts for any reason, @release_buffered_frames is called
- * with the number of frames to be released and which TIDs they are
- * to come from. In this case, the driver is responsible for setting
- * the EOSP (for uAPSD) and MORE_DATA bits in the released frames,
- * to help the @more_data paramter is passed to tell the driver if
- * there is more data on other TIDs -- the TIDs to release frames
- * from are ignored since mac80211 doesn't know how many frames the
- * buffers for those TIDs contain.
- *
- * If the driver also implement GO mode, where absence periods may
- * shorten service periods (or abort PS-Poll responses), it must
- * filter those response frames except in the case of frames that
- * are buffered in the driver -- those must remain buffered to avoid
- * reordering. Because it is possible that no frames are released
- * in this case, the driver must call ieee80211_sta_eosp_irqsafe()
- * to indicate to mac80211 that the service period ended anyway.
- *
- * Finally, if frames from multiple TIDs are released from mac80211
- * but the driver might reorder them, it must clear & set the flags
- * appropriately (only the last frame may have %IEEE80211_TX_STATUS_EOSP)
- * and also take care of the EOSP and MORE_DATA bits in the frame.
- * The driver may also use ieee80211_sta_eosp_irqsafe() in this case.
- */
-
/**
* enum ieee80211_filter_flags - hardware filter flags
*
@@ -1720,17 +1616,6 @@ enum ieee80211_tx_sync_type {
IEEE80211_TX_SYNC_ACTION,
};
-/**
- * enum ieee80211_frame_release_type - frame release reason
- * @IEEE80211_FRAME_RELEASE_PSPOLL: frame released for PS-Poll
- * @IEEE80211_FRAME_RELEASE_UAPSD: frame(s) released due to
- * frame received on trigger-enabled AC
- */
-enum ieee80211_frame_release_type {
- IEEE80211_FRAME_RELEASE_PSPOLL,
- IEEE80211_FRAME_RELEASE_UAPSD,
-};
-
/**
* struct ieee80211_ops - callbacks from mac80211 to the driver
*
@@ -2041,45 +1926,6 @@ enum ieee80211_frame_release_type {
* The callback can sleep.
* @rssi_callback: Notify driver when the average RSSI goes above/below
* thresholds that were registered previously. The callback can sleep.
- *
- * @release_buffered_frames: Release buffered frames according to the given
- * parameters. In the case where the driver buffers some frames for
- * sleeping stations mac80211 will use this callback to tell the driver
- * to release some frames, either for PS-poll or uAPSD.
- * Note that if the @more_data paramter is %false the driver must check
- * if there are more frames on the given TIDs, and if there are more than
- * the frames being released then it must still set the more-data bit in
- * the frame. If the @more_data parameter is %true, then of course the
- * more-data bit must always be set.
- * The @tids parameter tells the driver which TIDs to release frames
- * from, for PS-poll it will always have only a single bit set.
- * In the case this is used for a PS-poll initiated release, the
- * @num_frames parameter will always be 1 so code can be shared. In
- * this case the driver must also set %IEEE80211_TX_STATUS_EOSP flag
- * on the TX status (and must report TX status) so that the PS-poll
- * period is properly ended. This is used to avoid sending multiple
- * responses for a retried PS-poll frame.
- * In the case this is used for uAPSD, the @num_frames parameter may be
- * bigger than one, but the driver may send fewer frames (it must send
- * at least one, however). In this case it is also responsible for
- * setting the EOSP flag in the QoS header of the frames. Also, when the
- * service period ends, the driver must set %IEEE80211_TX_STATUS_EOSP
- * on the last frame in the SP. Alternatively, it may call the function
- * ieee80211_sta_eosp_irqsafe() to inform mac80211 of the end of the SP.
- * This callback must be atomic.
- * @allow_buffered_frames: Prepare device to allow the given number of frames
- * to go out to the given station. The frames will be sent by mac80211
- * via the usual TX path after this call. The TX information for frames
- * released will also have the %IEEE80211_TX_CTL_POLL_RESPONSE flag set
- * and the last one will also have %IEEE80211_TX_STATUS_EOSP set. In case
- * frames from multiple TIDs are released and the driver might reorder
- * them between the TIDs, it must set the %IEEE80211_TX_STATUS_EOSP flag
- * on the last frame and clear it on all others and also handle the EOSP
- * bit in the QoS header correctly. Alternatively, it can also call the
- * ieee80211_sta_eosp_irqsafe() function.
- * The @tids parameter is a bitmap and tells the driver which TIDs the
- * frames will be on; it will at most have two bits set.
- * This callback must be atomic.
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -2152,13 +1998,11 @@ struct ieee80211_ops {
struct ieee80211_sta *sta);
void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum sta_notify_cmd, struct ieee80211_sta *sta);
- int (*conf_tx)(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
+ int (*conf_tx)(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
- u64 (*get_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
- void (*set_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- u64 tsf);
- void (*reset_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
+ u64 (*get_tsf)(struct ieee80211_hw *hw);
+ void (*set_tsf)(struct ieee80211_hw *hw, u64 tsf);
+ void (*reset_tsf)(struct ieee80211_hw *hw);
int (*tx_last_beacon)(struct ieee80211_hw *hw);
int (*ampdu_action)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
@@ -2195,17 +2039,6 @@ struct ieee80211_ops {
const struct cfg80211_bitrate_mask *mask);
void (*rssi_callback)(struct ieee80211_hw *hw,
enum ieee80211_rssi_event rssi_event);
-
- void (*allow_buffered_frames)(struct ieee80211_hw *hw,
- struct ieee80211_sta *sta,
- u16 tids, int num_frames,
- enum ieee80211_frame_release_type reason,
- bool more_data);
- void (*release_buffered_frames)(struct ieee80211_hw *hw,
- struct ieee80211_sta *sta,
- u16 tids, int num_frames,
- enum ieee80211_frame_release_type reason,
- bool more_data);
};
/**
@@ -2523,35 +2356,17 @@ static inline int ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta,
#define IEEE80211_TX_STATUS_HEADROOM 13
/**
- * ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames
+ * ieee80211_sta_set_tim - set the TIM bit for a sleeping station
* @sta: &struct ieee80211_sta pointer for the sleeping station
- * @tid: the TID that has buffered frames
- * @buffered: indicates whether or not frames are buffered for this TID
*
* If a driver buffers frames for a powersave station instead of passing
- * them back to mac80211 for retransmission, the station may still need
- * to be told that there are buffered frames via the TIM bit.
+ * them back to mac80211 for retransmission, the station needs to be told
+ * to wake up using the TIM bitmap in the beacon.
*
- * This function informs mac80211 whether or not there are frames that are
- * buffered in the driver for a given TID; mac80211 can then use this data
- * to set the TIM bit (NOTE: This may call back into the driver's set_tim
- * call! Beware of the locking!)
- *
- * If all frames are released to the station (due to PS-poll or uAPSD)
- * then the driver needs to inform mac80211 that there no longer are
- * frames buffered. However, when the station wakes up mac80211 assumes
- * that all buffered frames will be transmitted and clears this data,
- * drivers need to make sure they inform mac80211 about all buffered
- * frames on the sleep transition (sta_notify() with %STA_NOTIFY_SLEEP).
- *
- * Note that technically mac80211 only needs to know this per AC, not per
- * TID, but since driver buffering will inevitably happen per TID (since
- * it is related to aggregation) it is easier to make mac80211 map the
- * TID to the AC as required instead of keeping track in all drivers that
- * use this API.
+ * This function sets the station's TIM bit - it will be cleared when the
+ * station wakes up.
*/
-void ieee80211_sta_set_buffered(struct ieee80211_sta *sta,
- u8 tid, bool buffered);
+void ieee80211_sta_set_tim(struct ieee80211_sta *sta);
/**
* ieee80211_tx_status - transmit status callback
@@ -3208,24 +3023,6 @@ struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw,
void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
struct ieee80211_sta *pubsta, bool block);
-/**
- * ieee80211_sta_eosp - notify mac80211 about end of SP
- * @pubsta: the station
- *
- * When a device transmits frames in a way that it can't tell
- * mac80211 in the TX status about the EOSP, it must clear the
- * %IEEE80211_TX_STATUS_EOSP bit and call this function instead.
- * This applies for PS-Poll as well as uAPSD.
- *
- * Note that there is no non-_irqsafe version right now as
- * it wasn't needed, but just like _tx_status() and _rx()
- * must not be mixed in irqsafe/non-irqsafe versions, this
- * function must not be mixed with those either. Use the
- * all irqsafe, or all non-irqsafe, don't mix! If you need
- * the non-irqsafe version of this, you need to add it.
- */
-void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta);
-
/**
* ieee80211_iter_keys - iterate keys programmed into the device
* @hw: pointer obtained from ieee80211_alloc_hw()
@@ -3642,9 +3439,4 @@ void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif,
int rssi_max_thold);
void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif);
-
-int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb);
-
-int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif,
- struct sk_buff *skb);
#endif /* MAC80211_H */
diff --git a/trunk/include/net/nfc/nci_core.h b/trunk/include/net/nfc/nci_core.h
index b8b4bbd7e0fc..2563f3a95e67 100644
--- a/trunk/include/net/nfc/nci_core.h
+++ b/trunk/include/net/nfc/nci_core.h
@@ -40,7 +40,6 @@ enum {
NCI_UP,
NCI_DISCOVERY,
NCI_POLL_ACTIVE,
- NCI_DATA_EXCHANGE,
};
/* NCI timeouts */
diff --git a/trunk/net/mac80211/Kconfig b/trunk/net/mac80211/Kconfig
index 7d3b438755f0..d1886b59bec4 100644
--- a/trunk/net/mac80211/Kconfig
+++ b/trunk/net/mac80211/Kconfig
@@ -225,18 +225,6 @@ config MAC80211_VERBOSE_MHWMP_DEBUG
Do not select this option.
-config MAC80211_VERBOSE_TDLS_DEBUG
- bool "Verbose TDLS debugging"
- depends on MAC80211_DEBUG_MENU
- ---help---
- Selecting this option causes mac80211 to print out very
- verbose TDLS selection debugging messages (when mac80211
- is a TDLS STA).
- It should not be selected on production systems as those
- messages are remotely triggerable.
-
- Do not select this option.
-
config MAC80211_DEBUG_COUNTERS
bool "Extra statistics for TX/RX debugging"
depends on MAC80211_DEBUG_MENU
diff --git a/trunk/net/mac80211/agg-rx.c b/trunk/net/mac80211/agg-rx.c
index 0cde8df6828d..e6cab51dceb0 100644
--- a/trunk/net/mac80211/agg-rx.c
+++ b/trunk/net/mac80211/agg-rx.c
@@ -223,7 +223,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
status = WLAN_STATUS_REQUEST_DECLINED;
- if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
+ if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "Suspend in progress. "
"Denying ADDBA request\n");
diff --git a/trunk/net/mac80211/agg-tx.c b/trunk/net/mac80211/agg-tx.c
index 2ac033989e01..3cef5a7281cb 100644
--- a/trunk/net/mac80211/agg-tx.c
+++ b/trunk/net/mac80211/agg-tx.c
@@ -382,7 +382,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
sdata->vif.type != NL80211_IFTYPE_AP)
return -EINVAL;
- if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
+ if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "BA sessions blocked. "
"Denying BA session request\n");
diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c
index 1309bb9c97be..b57ddf941e59 100644
--- a/trunk/net/mac80211/cfg.c
+++ b/trunk/net/mac80211/cfg.c
@@ -12,7 +12,6 @@
#include
#include
#include
-#include
#include
#include "ieee80211_i.h"
#include "driver-ops.h"
@@ -668,6 +667,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
struct sta_info *sta,
struct station_parameters *params)
{
+ unsigned long flags;
u32 rates;
int i, j;
struct ieee80211_supported_band *sband;
@@ -676,58 +676,46 @@ static void sta_apply_parameters(struct ieee80211_local *local,
sband = local->hw.wiphy->bands[local->oper_channel->band];
+ spin_lock_irqsave(&sta->flaglock, flags);
mask = params->sta_flags_mask;
set = params->sta_flags_set;
if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
+ sta->flags &= ~WLAN_STA_AUTHORIZED;
if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))
- set_sta_flag(sta, WLAN_STA_AUTHORIZED);
- else
- clear_sta_flag(sta, WLAN_STA_AUTHORIZED);
+ sta->flags |= WLAN_STA_AUTHORIZED;
}
if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) {
+ sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
- set_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE);
- else
- clear_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE);
+ sta->flags |= WLAN_STA_SHORT_PREAMBLE;
}
if (mask & BIT(NL80211_STA_FLAG_WME)) {
+ sta->flags &= ~WLAN_STA_WME;
+ sta->sta.wme = false;
if (set & BIT(NL80211_STA_FLAG_WME)) {
- set_sta_flag(sta, WLAN_STA_WME);
+ sta->flags |= WLAN_STA_WME;
sta->sta.wme = true;
- } else {
- clear_sta_flag(sta, WLAN_STA_WME);
- sta->sta.wme = false;
}
}
if (mask & BIT(NL80211_STA_FLAG_MFP)) {
+ sta->flags &= ~WLAN_STA_MFP;
if (set & BIT(NL80211_STA_FLAG_MFP))
- set_sta_flag(sta, WLAN_STA_MFP);
- else
- clear_sta_flag(sta, WLAN_STA_MFP);
+ sta->flags |= WLAN_STA_MFP;
}
if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) {
+ sta->flags &= ~WLAN_STA_AUTH;
if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED))
- set_sta_flag(sta, WLAN_STA_AUTH);
- else
- clear_sta_flag(sta, WLAN_STA_AUTH);
+ sta->flags |= WLAN_STA_AUTH;
}
+ spin_unlock_irqrestore(&sta->flaglock, flags);
- if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
- if (set & BIT(NL80211_STA_FLAG_TDLS_PEER))
- set_sta_flag(sta, WLAN_STA_TDLS_PEER);
- else
- clear_sta_flag(sta, WLAN_STA_TDLS_PEER);
- }
-
- if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD) {
- sta->sta.uapsd_queues = params->uapsd_queues;
- sta->sta.max_sp = params->max_sp;
- }
+ sta->sta.uapsd_queues = params->uapsd_queues;
+ sta->sta.max_sp = params->max_sp;
/*
* cfg80211 validates this (1-2007) and allows setting the AID
@@ -818,17 +806,10 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
if (!sta)
return -ENOMEM;
- set_sta_flag(sta, WLAN_STA_AUTH);
- set_sta_flag(sta, WLAN_STA_ASSOC);
+ sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
sta_apply_parameters(local, sta, params);
- /* Only TDLS-supporting stations can add TDLS peers */
- if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
- !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
- sdata->vif.type == NL80211_IFTYPE_STATION))
- return -ENOTSUPP;
-
rate_control_rate_init(sta);
layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
@@ -881,14 +862,6 @@ static int ieee80211_change_station(struct wiphy *wiphy,
return -ENOENT;
}
- /* The TDLS bit cannot be toggled after the STA was added */
- if ((params->sta_flags_mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
- !!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) !=
- !!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
- rcu_read_unlock();
- return -EINVAL;
- }
-
if (params->vlan && params->vlan != sta->sdata->dev) {
vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
@@ -1298,11 +1271,9 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
}
static int ieee80211_set_txq_params(struct wiphy *wiphy,
- struct net_device *dev,
struct ieee80211_txq_params *params)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_tx_queue_params p;
if (!local->ops->conf_tx)
@@ -1323,8 +1294,8 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
if (params->queue >= local->hw.queues)
return -EINVAL;
- sdata->tx_conf[params->queue] = p;
- if (drv_conf_tx(local, sdata, params->queue, &p)) {
+ local->tx_conf[params->queue] = p;
+ if (drv_conf_tx(local, params->queue, &p)) {
wiphy_debug(local->hw.wiphy,
"failed to set TX queue parameters for queue %d\n",
params->queue);
@@ -1898,8 +1869,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_channel *chan, bool offchan,
enum nl80211_channel_type channel_type,
bool channel_type_valid, unsigned int wait,
- const u8 *buf, size_t len, bool no_cck,
- u64 *cookie)
+ const u8 *buf, size_t len, u64 *cookie)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
@@ -1926,9 +1896,6 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
flags |= IEEE80211_TX_CTL_TX_OFFCHAN;
}
- if (no_cck)
- flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
-
if (is_offchan && !offchan)
return -EBUSY;
@@ -2153,323 +2120,6 @@ static int ieee80211_set_rekey_data(struct wiphy *wiphy,
return 0;
}
-static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb)
-{
- u8 *pos = (void *)skb_put(skb, 7);
-
- *pos++ = WLAN_EID_EXT_CAPABILITY;
- *pos++ = 5; /* len */
- *pos++ = 0x0;
- *pos++ = 0x0;
- *pos++ = 0x0;
- *pos++ = 0x0;
- *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED;
-}
-
-static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata)
-{
- struct ieee80211_local *local = sdata->local;
- u16 capab;
-
- capab = 0;
- if (local->oper_channel->band != IEEE80211_BAND_2GHZ)
- return capab;
-
- if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
- capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
- if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
- capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
-
- return capab;
-}
-
-static void ieee80211_tdls_add_link_ie(struct sk_buff *skb, u8 *src_addr,
- u8 *peer, u8 *bssid)
-{
- struct ieee80211_tdls_lnkie *lnkid;
-
- lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
-
- lnkid->ie_type = WLAN_EID_LINK_ID;
- lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2;
-
- memcpy(lnkid->bssid, bssid, ETH_ALEN);
- memcpy(lnkid->init_sta, src_addr, ETH_ALEN);
- memcpy(lnkid->resp_sta, peer, ETH_ALEN);
-}
-
-static int
-ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
- u8 *peer, u8 action_code, u8 dialog_token,
- u16 status_code, struct sk_buff *skb)
-{
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- struct ieee80211_tdls_data *tf;
-
- tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
-
- memcpy(tf->da, peer, ETH_ALEN);
- memcpy(tf->sa, sdata->vif.addr, ETH_ALEN);
- tf->ether_type = cpu_to_be16(ETH_P_TDLS);
- tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
-
- switch (action_code) {
- case WLAN_TDLS_SETUP_REQUEST:
- tf->category = WLAN_CATEGORY_TDLS;
- tf->action_code = WLAN_TDLS_SETUP_REQUEST;
-
- skb_put(skb, sizeof(tf->u.setup_req));
- tf->u.setup_req.dialog_token = dialog_token;
- tf->u.setup_req.capability =
- cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
-
- ieee80211_add_srates_ie(&sdata->vif, skb);
- ieee80211_add_ext_srates_ie(&sdata->vif, skb);
- ieee80211_tdls_add_ext_capab(skb);
- break;
- case WLAN_TDLS_SETUP_RESPONSE:
- tf->category = WLAN_CATEGORY_TDLS;
- tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
-
- skb_put(skb, sizeof(tf->u.setup_resp));
- tf->u.setup_resp.status_code = cpu_to_le16(status_code);
- tf->u.setup_resp.dialog_token = dialog_token;
- tf->u.setup_resp.capability =
- cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
-
- ieee80211_add_srates_ie(&sdata->vif, skb);
- ieee80211_add_ext_srates_ie(&sdata->vif, skb);
- ieee80211_tdls_add_ext_capab(skb);
- break;
- case WLAN_TDLS_SETUP_CONFIRM:
- tf->category = WLAN_CATEGORY_TDLS;
- tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
-
- skb_put(skb, sizeof(tf->u.setup_cfm));
- tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
- tf->u.setup_cfm.dialog_token = dialog_token;
- break;
- case WLAN_TDLS_TEARDOWN:
- tf->category = WLAN_CATEGORY_TDLS;
- tf->action_code = WLAN_TDLS_TEARDOWN;
-
- skb_put(skb, sizeof(tf->u.teardown));
- tf->u.teardown.reason_code = cpu_to_le16(status_code);
- break;
- case WLAN_TDLS_DISCOVERY_REQUEST:
- tf->category = WLAN_CATEGORY_TDLS;
- tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
-
- skb_put(skb, sizeof(tf->u.discover_req));
- tf->u.discover_req.dialog_token = dialog_token;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int
-ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
- u8 *peer, u8 action_code, u8 dialog_token,
- u16 status_code, struct sk_buff *skb)
-{
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- struct ieee80211_mgmt *mgmt;
-
- mgmt = (void *)skb_put(skb, 24);
- memset(mgmt, 0, 24);
- memcpy(mgmt->da, peer, ETH_ALEN);
- memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
- memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
-
- mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_ACTION);
-
- switch (action_code) {
- case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
- skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp));
- mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
- mgmt->u.action.u.tdls_discover_resp.action_code =
- WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
- mgmt->u.action.u.tdls_discover_resp.dialog_token =
- dialog_token;
- mgmt->u.action.u.tdls_discover_resp.capability =
- cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
-
- ieee80211_add_srates_ie(&sdata->vif, skb);
- ieee80211_add_ext_srates_ie(&sdata->vif, skb);
- ieee80211_tdls_add_ext_capab(skb);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
- u8 *peer, u8 action_code, u8 dialog_token,
- u16 status_code, const u8 *extra_ies,
- size_t extra_ies_len)
-{
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- struct ieee80211_local *local = sdata->local;
- struct ieee80211_tx_info *info;
- struct sk_buff *skb = NULL;
- bool send_direct;
- int ret;
-
- if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
- return -ENOTSUPP;
-
- /* make sure we are in managed mode, and associated */
- if (sdata->vif.type != NL80211_IFTYPE_STATION ||
- !sdata->u.mgd.associated)
- return -EINVAL;
-
-#ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG
- printk(KERN_DEBUG "TDLS mgmt action %d peer %pM\n", action_code, peer);
-#endif
-
- skb = dev_alloc_skb(local->hw.extra_tx_headroom +
- max(sizeof(struct ieee80211_mgmt),
- sizeof(struct ieee80211_tdls_data)) +
- 50 + /* supported rates */
- 7 + /* ext capab */
- extra_ies_len +
- sizeof(struct ieee80211_tdls_lnkie));
- if (!skb)
- return -ENOMEM;
-
- info = IEEE80211_SKB_CB(skb);
- skb_reserve(skb, local->hw.extra_tx_headroom);
-
- switch (action_code) {
- case WLAN_TDLS_SETUP_REQUEST:
- case WLAN_TDLS_SETUP_RESPONSE:
- case WLAN_TDLS_SETUP_CONFIRM:
- case WLAN_TDLS_TEARDOWN:
- case WLAN_TDLS_DISCOVERY_REQUEST:
- ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer,
- action_code, dialog_token,
- status_code, skb);
- send_direct = false;
- break;
- case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
- ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code,
- dialog_token, status_code,
- skb);
- send_direct = true;
- break;
- default:
- ret = -ENOTSUPP;
- break;
- }
-
- if (ret < 0)
- goto fail;
-
- if (extra_ies_len)
- memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len);
-
- /* the TDLS link IE is always added last */
- switch (action_code) {
- case WLAN_TDLS_SETUP_REQUEST:
- case WLAN_TDLS_SETUP_CONFIRM:
- case WLAN_TDLS_TEARDOWN:
- case WLAN_TDLS_DISCOVERY_REQUEST:
- /* we are the initiator */
- ieee80211_tdls_add_link_ie(skb, sdata->vif.addr, peer,
- sdata->u.mgd.bssid);
- break;
- case WLAN_TDLS_SETUP_RESPONSE:
- case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
- /* we are the responder */
- ieee80211_tdls_add_link_ie(skb, peer, sdata->vif.addr,
- sdata->u.mgd.bssid);
- break;
- default:
- ret = -ENOTSUPP;
- goto fail;
- }
-
- if (send_direct) {
- ieee80211_tx_skb(sdata, skb);
- return 0;
- }
-
- /*
- * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise
- * we should default to AC_VI.
- */
- switch (action_code) {
- case WLAN_TDLS_SETUP_REQUEST:
- case WLAN_TDLS_SETUP_RESPONSE:
- skb_set_queue_mapping(skb, IEEE80211_AC_BK);
- skb->priority = 2;
- break;
- default:
- skb_set_queue_mapping(skb, IEEE80211_AC_VI);
- skb->priority = 5;
- break;
- }
-
- /* disable bottom halves when entering the Tx path */
- local_bh_disable();
- ret = ieee80211_subif_start_xmit(skb, dev);
- local_bh_enable();
-
- return ret;
-
-fail:
- dev_kfree_skb(skb);
- return ret;
-}
-
-static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
- u8 *peer, enum nl80211_tdls_operation oper)
-{
- struct sta_info *sta;
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
- if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
- return -ENOTSUPP;
-
- if (sdata->vif.type != NL80211_IFTYPE_STATION)
- return -EINVAL;
-
-#ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG
- printk(KERN_DEBUG "TDLS oper %d peer %pM\n", oper, peer);
-#endif
-
- switch (oper) {
- case NL80211_TDLS_ENABLE_LINK:
- rcu_read_lock();
- sta = sta_info_get(sdata, peer);
- if (!sta) {
- rcu_read_unlock();
- return -ENOLINK;
- }
-
- set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
- rcu_read_unlock();
- break;
- case NL80211_TDLS_DISABLE_LINK:
- return sta_info_destroy_addr(sdata, peer);
- case NL80211_TDLS_TEARDOWN:
- case NL80211_TDLS_SETUP:
- case NL80211_TDLS_DISCOVERY_REQ:
- /* We don't support in-driver setup/teardown/discovery */
- return -ENOTSUPP;
- default:
- return -ENOTSUPP;
- }
-
- return 0;
-}
-
struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
@@ -2533,6 +2183,4 @@ struct cfg80211_ops mac80211_config_ops = {
.set_ringparam = ieee80211_set_ringparam,
.get_ringparam = ieee80211_get_ringparam,
.set_rekey_data = ieee80211_set_rekey_data,
- .tdls_oper = ieee80211_tdls_oper,
- .tdls_mgmt = ieee80211_tdls_mgmt,
};
diff --git a/trunk/net/mac80211/debugfs.c b/trunk/net/mac80211/debugfs.c
index 883996b2f99f..c9141168fd43 100644
--- a/trunk/net/mac80211/debugfs.c
+++ b/trunk/net/mac80211/debugfs.c
@@ -78,6 +78,57 @@ DEBUGFS_READONLY_FILE(wep_iv, "%#08x",
DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s",
local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver");
+static ssize_t tsf_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ieee80211_local *local = file->private_data;
+ u64 tsf;
+
+ tsf = drv_get_tsf(local);
+
+ return mac80211_format_buffer(user_buf, count, ppos, "0x%016llx\n",
+ (unsigned long long) tsf);
+}
+
+static ssize_t tsf_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ieee80211_local *local = file->private_data;
+ unsigned long long tsf;
+ char buf[100];
+ size_t len;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+ buf[len] = '\0';
+
+ if (strncmp(buf, "reset", 5) == 0) {
+ if (local->ops->reset_tsf) {
+ drv_reset_tsf(local);
+ wiphy_info(local->hw.wiphy, "debugfs reset TSF\n");
+ }
+ } else {
+ tsf = simple_strtoul(buf, NULL, 0);
+ if (local->ops->set_tsf) {
+ drv_set_tsf(local, tsf);
+ wiphy_info(local->hw.wiphy,
+ "debugfs set TSF to %#018llx\n", tsf);
+
+ }
+ }
+
+ return count;
+}
+
+static const struct file_operations tsf_ops = {
+ .read = tsf_read,
+ .write = tsf_write,
+ .open = mac80211_open_file_generic,
+ .llseek = default_llseek,
+};
+
static ssize_t reset_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -396,6 +447,7 @@ void debugfs_hw_add(struct ieee80211_local *local)
DEBUGFS_ADD(frequency);
DEBUGFS_ADD(total_ps_buffered);
DEBUGFS_ADD(wep_iv);
+ DEBUGFS_ADD(tsf);
DEBUGFS_ADD(queues);
DEBUGFS_ADD_MODE(reset, 0200);
DEBUGFS_ADD(noack);
diff --git a/trunk/net/mac80211/debugfs_netdev.c b/trunk/net/mac80211/debugfs_netdev.c
index 9352819a986b..dd0462917518 100644
--- a/trunk/net/mac80211/debugfs_netdev.c
+++ b/trunk/net/mac80211/debugfs_netdev.c
@@ -21,7 +21,6 @@
#include "rate.h"
#include "debugfs.h"
#include "debugfs_netdev.h"
-#include "driver-ops.h"
static ssize_t ieee80211_if_read(
struct ieee80211_sub_if_data *sdata,
@@ -332,46 +331,6 @@ static ssize_t ieee80211_if_fmt_num_buffered_multicast(
}
__IEEE80211_IF_FILE(num_buffered_multicast, NULL);
-/* IBSS attributes */
-static ssize_t ieee80211_if_fmt_tsf(
- const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
-{
- struct ieee80211_local *local = sdata->local;
- u64 tsf;
-
- tsf = drv_get_tsf(local, (struct ieee80211_sub_if_data *)sdata);
-
- return scnprintf(buf, buflen, "0x%016llx\n", (unsigned long long) tsf);
-}
-
-static ssize_t ieee80211_if_parse_tsf(
- struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
-{
- struct ieee80211_local *local = sdata->local;
- unsigned long long tsf;
- int ret;
-
- if (strncmp(buf, "reset", 5) == 0) {
- if (local->ops->reset_tsf) {
- drv_reset_tsf(local, sdata);
- wiphy_info(local->hw.wiphy, "debugfs reset TSF\n");
- }
- } else {
- ret = kstrtoull(buf, 10, &tsf);
- if (ret < 0)
- return -EINVAL;
- if (local->ops->set_tsf) {
- drv_set_tsf(local, sdata, tsf);
- wiphy_info(local->hw.wiphy,
- "debugfs set TSF to %#018llx\n", tsf);
- }
- }
-
- return buflen;
-}
-__IEEE80211_IF_FILE_W(tsf);
-
-
/* WDS attributes */
IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
@@ -462,11 +421,6 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata)
DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
}
-static void add_ibss_files(struct ieee80211_sub_if_data *sdata)
-{
- DEBUGFS_ADD_MODE(tsf, 0600);
-}
-
static void add_wds_files(struct ieee80211_sub_if_data *sdata)
{
DEBUGFS_ADD(drop_unencrypted);
@@ -561,7 +515,7 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
add_sta_files(sdata);
break;
case NL80211_IFTYPE_ADHOC:
- add_ibss_files(sdata);
+ /* XXX */
break;
case NL80211_IFTYPE_AP:
add_ap_files(sdata);
diff --git a/trunk/net/mac80211/debugfs_sta.c b/trunk/net/mac80211/debugfs_sta.c
index c5f341798c16..a01d2137fddc 100644
--- a/trunk/net/mac80211/debugfs_sta.c
+++ b/trunk/net/mac80211/debugfs_sta.c
@@ -56,22 +56,19 @@ STA_FILE(last_signal, last_signal, D);
static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
- char buf[121];
+ char buf[100];
struct sta_info *sta = file->private_data;
-
-#define TEST(flg) \
- test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
-
- int res = scnprintf(buf, sizeof(buf),
- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
- TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
- TEST(PS_DRIVER), TEST(AUTHORIZED),
- TEST(SHORT_PREAMBLE), TEST(ASSOC_AP),
- TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
- TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
- TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
- TEST(TDLS_PEER_AUTH));
-#undef TEST
+ u32 staflags = get_sta_flags(sta);
+ int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s",
+ staflags & WLAN_STA_AUTH ? "AUTH\n" : "",
+ staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
+ staflags & WLAN_STA_PS_STA ? "PS (sta)\n" : "",
+ staflags & WLAN_STA_PS_DRIVER ? "PS (driver)\n" : "",
+ staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
+ staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
+ staflags & WLAN_STA_WME ? "WME\n" : "",
+ staflags & WLAN_STA_WDS ? "WDS\n" : "",
+ staflags & WLAN_STA_MFP ? "MFP\n" : "");
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
}
STA_OPS(flags);
@@ -81,14 +78,8 @@ static ssize_t sta_num_ps_buf_frames_read(struct file *file,
size_t count, loff_t *ppos)
{
struct sta_info *sta = file->private_data;
- char buf[17*IEEE80211_NUM_ACS], *p = buf;
- int ac;
-
- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
- p += scnprintf(p, sizeof(buf)+buf-p, "AC%d: %d\n", ac,
- skb_queue_len(&sta->ps_tx_buf[ac]) +
- skb_queue_len(&sta->tx_filtered[ac]));
- return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
+ return mac80211_format_buffer(userbuf, count, ppos, "%u\n",
+ skb_queue_len(&sta->ps_tx_buf));
}
STA_OPS(num_ps_buf_frames);
diff --git a/trunk/net/mac80211/driver-ops.h b/trunk/net/mac80211/driver-ops.h
index 5f165d7eb2db..9001ff331f0a 100644
--- a/trunk/net/mac80211/driver-ops.h
+++ b/trunk/net/mac80211/driver-ops.h
@@ -413,56 +413,50 @@ static inline void drv_sta_remove(struct ieee80211_local *local,
trace_drv_return_void(local);
}
-static inline int drv_conf_tx(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata, u16 queue,
+static inline int drv_conf_tx(struct ieee80211_local *local, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
int ret = -EOPNOTSUPP;
might_sleep();
- trace_drv_conf_tx(local, sdata, queue, params);
+ trace_drv_conf_tx(local, queue, params);
if (local->ops->conf_tx)
- ret = local->ops->conf_tx(&local->hw, &sdata->vif,
- queue, params);
+ ret = local->ops->conf_tx(&local->hw, queue, params);
trace_drv_return_int(local, ret);
return ret;
}
-static inline u64 drv_get_tsf(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata)
+static inline u64 drv_get_tsf(struct ieee80211_local *local)
{
u64 ret = -1ULL;
might_sleep();
- trace_drv_get_tsf(local, sdata);
+ trace_drv_get_tsf(local);
if (local->ops->get_tsf)
- ret = local->ops->get_tsf(&local->hw, &sdata->vif);
+ ret = local->ops->get_tsf(&local->hw);
trace_drv_return_u64(local, ret);
return ret;
}
-static inline void drv_set_tsf(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata,
- u64 tsf)
+static inline void drv_set_tsf(struct ieee80211_local *local, u64 tsf)
{
might_sleep();
- trace_drv_set_tsf(local, sdata, tsf);
+ trace_drv_set_tsf(local, tsf);
if (local->ops->set_tsf)
- local->ops->set_tsf(&local->hw, &sdata->vif, tsf);
+ local->ops->set_tsf(&local->hw, tsf);
trace_drv_return_void(local);
}
-static inline void drv_reset_tsf(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata)
+static inline void drv_reset_tsf(struct ieee80211_local *local)
{
might_sleep();
- trace_drv_reset_tsf(local, sdata);
+ trace_drv_reset_tsf(local);
if (local->ops->reset_tsf)
- local->ops->reset_tsf(&local->hw, &sdata->vif);
+ local->ops->reset_tsf(&local->hw);
trace_drv_return_void(local);
}
@@ -671,34 +665,4 @@ static inline void drv_rssi_callback(struct ieee80211_local *local,
local->ops->rssi_callback(&local->hw, event);
trace_drv_return_void(local);
}
-
-static inline void
-drv_release_buffered_frames(struct ieee80211_local *local,
- struct sta_info *sta, u16 tids, int num_frames,
- enum ieee80211_frame_release_type reason,
- bool more_data)
-{
- trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
- reason, more_data);
- if (local->ops->release_buffered_frames)
- local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
- num_frames, reason,
- more_data);
- trace_drv_return_void(local);
-}
-
-static inline void
-drv_allow_buffered_frames(struct ieee80211_local *local,
- struct sta_info *sta, u16 tids, int num_frames,
- enum ieee80211_frame_release_type reason,
- bool more_data)
-{
- trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
- reason, more_data);
- if (local->ops->allow_buffered_frames)
- local->ops->allow_buffered_frames(&local->hw, &sta->sta,
- tids, num_frames, reason,
- more_data);
- trace_drv_return_void(local);
-}
#endif /* __MAC80211_DRIVER_OPS */
diff --git a/trunk/net/mac80211/driver-trace.h b/trunk/net/mac80211/driver-trace.h
index 2af4fca55337..f47b00dc7afd 100644
--- a/trunk/net/mac80211/driver-trace.h
+++ b/trunk/net/mac80211/driver-trace.h
@@ -697,76 +697,64 @@ TRACE_EVENT(drv_sta_remove,
);
TRACE_EVENT(drv_conf_tx,
- TP_PROTO(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata,
- u16 queue,
+ TP_PROTO(struct ieee80211_local *local, u16 queue,
const struct ieee80211_tx_queue_params *params),
- TP_ARGS(local, sdata, queue, params),
+ TP_ARGS(local, queue, params),
TP_STRUCT__entry(
LOCAL_ENTRY
- VIF_ENTRY
__field(u16, queue)
__field(u16, txop)
__field(u16, cw_min)
__field(u16, cw_max)
__field(u8, aifs)
- __field(bool, uapsd)
),
TP_fast_assign(
LOCAL_ASSIGN;
- VIF_ASSIGN;
__entry->queue = queue;
__entry->txop = params->txop;
__entry->cw_max = params->cw_max;
__entry->cw_min = params->cw_min;
__entry->aifs = params->aifs;
- __entry->uapsd = params->uapsd;
),
TP_printk(
- LOCAL_PR_FMT VIF_PR_FMT " queue:%d",
- LOCAL_PR_ARG, VIF_PR_ARG, __entry->queue
+ LOCAL_PR_FMT " queue:%d",
+ LOCAL_PR_ARG, __entry->queue
)
);
-DEFINE_EVENT(local_sdata_evt, drv_get_tsf,
- TP_PROTO(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata),
- TP_ARGS(local, sdata)
+DEFINE_EVENT(local_only_evt, drv_get_tsf,
+ TP_PROTO(struct ieee80211_local *local),
+ TP_ARGS(local)
);
TRACE_EVENT(drv_set_tsf,
- TP_PROTO(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata,
- u64 tsf),
+ TP_PROTO(struct ieee80211_local *local, u64 tsf),
- TP_ARGS(local, sdata, tsf),
+ TP_ARGS(local, tsf),
TP_STRUCT__entry(
LOCAL_ENTRY
- VIF_ENTRY
__field(u64, tsf)
),
TP_fast_assign(
LOCAL_ASSIGN;
- VIF_ASSIGN;
__entry->tsf = tsf;
),
TP_printk(
- LOCAL_PR_FMT VIF_PR_FMT " tsf:%llu",
- LOCAL_PR_ARG, VIF_PR_ARG, (unsigned long long)__entry->tsf
+ LOCAL_PR_FMT " tsf:%llu",
+ LOCAL_PR_ARG, (unsigned long long)__entry->tsf
)
);
-DEFINE_EVENT(local_sdata_evt, drv_reset_tsf,
- TP_PROTO(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata),
- TP_ARGS(local, sdata)
+DEFINE_EVENT(local_only_evt, drv_reset_tsf,
+ TP_PROTO(struct ieee80211_local *local),
+ TP_ARGS(local)
);
DEFINE_EVENT(local_only_evt, drv_tx_last_beacon,
@@ -1129,61 +1117,6 @@ TRACE_EVENT(drv_rssi_callback,
)
);
-DECLARE_EVENT_CLASS(release_evt,
- TP_PROTO(struct ieee80211_local *local,
- struct ieee80211_sta *sta,
- u16 tids, int num_frames,
- enum ieee80211_frame_release_type reason,
- bool more_data),
-
- TP_ARGS(local, sta, tids, num_frames, reason, more_data),
-
- TP_STRUCT__entry(
- LOCAL_ENTRY
- STA_ENTRY
- __field(u16, tids)
- __field(int, num_frames)
- __field(int, reason)
- __field(bool, more_data)
- ),
-
- TP_fast_assign(
- LOCAL_ASSIGN;
- STA_ASSIGN;
- __entry->tids = tids;
- __entry->num_frames = num_frames;
- __entry->reason = reason;
- __entry->more_data = more_data;
- ),
-
- TP_printk(
- LOCAL_PR_FMT STA_PR_FMT
- " TIDs:0x%.4x frames:%d reason:%d more:%d",
- LOCAL_PR_ARG, STA_PR_ARG, __entry->tids, __entry->num_frames,
- __entry->reason, __entry->more_data
- )
-);
-
-DEFINE_EVENT(release_evt, drv_release_buffered_frames,
- TP_PROTO(struct ieee80211_local *local,
- struct ieee80211_sta *sta,
- u16 tids, int num_frames,
- enum ieee80211_frame_release_type reason,
- bool more_data),
-
- TP_ARGS(local, sta, tids, num_frames, reason, more_data)
-);
-
-DEFINE_EVENT(release_evt, drv_allow_buffered_frames,
- TP_PROTO(struct ieee80211_local *local,
- struct ieee80211_sta *sta,
- u16 tids, int num_frames,
- enum ieee80211_frame_release_type reason,
- bool more_data),
-
- TP_ARGS(local, sta, tids, num_frames, reason, more_data)
-);
-
/*
* Tracing for API calls that drivers call.
*/
@@ -1498,28 +1431,6 @@ TRACE_EVENT(api_enable_rssi_reports,
)
);
-TRACE_EVENT(api_eosp,
- TP_PROTO(struct ieee80211_local *local,
- struct ieee80211_sta *sta),
-
- TP_ARGS(local, sta),
-
- TP_STRUCT__entry(
- LOCAL_ENTRY
- STA_ENTRY
- ),
-
- TP_fast_assign(
- LOCAL_ASSIGN;
- STA_ASSIGN;
- ),
-
- TP_printk(
- LOCAL_PR_FMT STA_PR_FMT,
- LOCAL_PR_ARG, STA_PR_FMT
- )
-);
-
/*
* Tracing for internal functions
* (which may also be called in response to driver calls)
diff --git a/trunk/net/mac80211/ht.c b/trunk/net/mac80211/ht.c
index f80a35c0d000..2b9b52c69569 100644
--- a/trunk/net/mac80211/ht.c
+++ b/trunk/net/mac80211/ht.c
@@ -130,7 +130,7 @@ void ieee80211_ba_session_work(struct work_struct *work)
* down by the code that set the flag, so this
* need not run.
*/
- if (test_sta_flag(sta, WLAN_STA_BLOCK_BA))
+ if (test_sta_flags(sta, WLAN_STA_BLOCK_BA))
return;
mutex_lock(&sta->ampdu_mlme.mtx);
diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c
index 2da3040787a7..836b2752ecd6 100644
--- a/trunk/net/mac80211/ibss.c
+++ b/trunk/net/mac80211/ibss.c
@@ -81,7 +81,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
lockdep_assert_held(&ifibss->mtx);
/* Reset own TSF to allow time synchronization work. */
- drv_reset_tsf(local, sdata);
+ drv_reset_tsf(local);
skb = ifibss->skb;
rcu_assign_pointer(ifibss->presp, NULL);
@@ -314,7 +314,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
}
if (sta && elems->wmm_info)
- set_sta_flag(sta, WLAN_STA_WME);
+ set_sta_flags(sta, WLAN_STA_WME);
rcu_read_unlock();
}
@@ -382,7 +382,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
* second best option: get current TSF
* (will return -1 if not supported)
*/
- rx_timestamp = drv_get_tsf(local, sdata);
+ rx_timestamp = drv_get_tsf(local);
}
#ifdef CONFIG_MAC80211_IBSS_DEBUG
@@ -452,7 +452,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
return NULL;
sta->last_rx = jiffies;
- set_sta_flag(sta, WLAN_STA_AUTHORIZED);
+ set_sta_flags(sta, WLAN_STA_AUTHORIZED);
/* make sure mandatory rates are always added */
sta->sta.supp_rates[band] = supp_rates |
diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h
index 9fa5f8a674bc..21186e280ceb 100644
--- a/trunk/net/mac80211/ieee80211_i.h
+++ b/trunk/net/mac80211/ieee80211_i.h
@@ -609,8 +609,6 @@ struct ieee80211_sub_if_data {
__be16 control_port_protocol;
bool control_port_no_encrypt;
- struct ieee80211_tx_queue_params tx_conf[IEEE80211_MAX_QUEUES];
-
struct work_struct work;
struct sk_buff_head skb_queue;
@@ -664,11 +662,6 @@ enum sdata_queue_type {
enum {
IEEE80211_RX_MSG = 1,
IEEE80211_TX_STATUS_MSG = 2,
- IEEE80211_EOSP_MSG = 3,
-};
-
-struct skb_eosp_msg_data {
- u8 sta[ETH_ALEN], iface[ETH_ALEN];
};
enum queue_stop_reason {
@@ -758,6 +751,7 @@ struct ieee80211_local {
struct workqueue_struct *workqueue;
unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES];
+ struct ieee80211_tx_queue_params tx_conf[IEEE80211_MAX_QUEUES];
/* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
spinlock_t queue_stop_reason_lock;
@@ -1277,7 +1271,6 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke
struct ieee80211_hdr *hdr, const u8 *tsc,
gfp_t gfp);
void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata);
-void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
void ieee802_11_parse_elems(u8 *start, size_t len,
struct ieee802_11_elems *elems);
@@ -1309,11 +1302,11 @@ void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
enum queue_stop_reason reason);
void ieee80211_add_pending_skb(struct ieee80211_local *local,
struct sk_buff *skb);
-void ieee80211_add_pending_skbs(struct ieee80211_local *local,
- struct sk_buff_head *skbs);
-void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
- struct sk_buff_head *skbs,
- void (*fn)(void *data), void *data);
+int ieee80211_add_pending_skbs(struct ieee80211_local *local,
+ struct sk_buff_head *skbs);
+int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
+ struct sk_buff_head *skbs,
+ void (*fn)(void *data), void *data);
void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
u16 transaction, u16 auth_alg,
@@ -1331,7 +1324,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
const u8 *ssid, size_t ssid_len,
const u8 *ie, size_t ie_len,
- u32 ratemask, bool directed, bool no_cck);
+ u32 ratemask, bool directed);
void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
const size_t supp_rates_len,
diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c
index ef741e8dbedb..eaa80a3d412b 100644
--- a/trunk/net/mac80211/iface.c
+++ b/trunk/net/mac80211/iface.c
@@ -299,8 +299,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
goto err_del_interface;
}
- /* no atomic bitop required since STA is not live yet */
- set_sta_flag(sta, WLAN_STA_AUTHORIZED);
+ /* no locking required since STA is not live yet */
+ sta->flags |= WLAN_STA_AUTHORIZED;
res = sta_info_insert(sta);
if (res) {
@@ -460,15 +460,17 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
synchronize_rcu();
kfree(old_beacon);
+ /* free all potentially still buffered bcast frames */
+ while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
+ local->total_ps_buffered--;
+ dev_kfree_skb(skb);
+ }
+
/* down all dependent devices, that is VLANs */
list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
u.vlan.list)
dev_close(vlan->dev);
WARN_ON(!list_empty(&sdata->u.ap.vlans));
-
- /* free all potentially still buffered bcast frames */
- local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps_bc_buf);
- skb_queue_purge(&sdata->u.ap.ps_bc_buf);
}
if (going_down)
diff --git a/trunk/net/mac80211/key.c b/trunk/net/mac80211/key.c
index 756b157c2edd..5150c6d11b57 100644
--- a/trunk/net/mac80211/key.c
+++ b/trunk/net/mac80211/key.c
@@ -464,7 +464,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
* some hardware cannot handle TKIP with QoS, so
* we indicate whether QoS could be in use.
*/
- if (test_sta_flag(sta, WLAN_STA_WME))
+ if (test_sta_flags(sta, WLAN_STA_WME))
key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
} else {
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
@@ -478,7 +478,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
/* same here, the AP could be using QoS */
ap = sta_info_get(key->sdata, key->sdata->u.mgd.bssid);
if (ap) {
- if (test_sta_flag(ap, WLAN_STA_WME))
+ if (test_sta_flags(ap, WLAN_STA_WME))
key->conf.flags |=
IEEE80211_KEY_FLAG_WMM_STA;
}
diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c
index 17b038aeac9b..a5809a1a6239 100644
--- a/trunk/net/mac80211/main.c
+++ b/trunk/net/mac80211/main.c
@@ -325,8 +325,6 @@ u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
static void ieee80211_tasklet_handler(unsigned long data)
{
struct ieee80211_local *local = (struct ieee80211_local *) data;
- struct sta_info *sta, *tmp;
- struct skb_eosp_msg_data *eosp_data;
struct sk_buff *skb;
while ((skb = skb_dequeue(&local->skb_queue)) ||
@@ -342,18 +340,6 @@ static void ieee80211_tasklet_handler(unsigned long data)
skb->pkt_type = 0;
ieee80211_tx_status(local_to_hw(local), skb);
break;
- case IEEE80211_EOSP_MSG:
- eosp_data = (void *)skb->cb;
- for_each_sta_info(local, eosp_data->sta, sta, tmp) {
- /* skip wrong virtual interface */
- if (memcmp(eosp_data->iface,
- sta->sdata->vif.addr, ETH_ALEN))
- continue;
- clear_sta_flag(sta, WLAN_STA_SP);
- break;
- }
- dev_kfree_skb(skb);
- break;
default:
WARN(1, "mac80211: Packet is of unknown type %d\n",
skb->pkt_type);
@@ -877,10 +863,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if (local->ops->sched_scan_start)
local->hw.wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
- /* mac80211 based drivers don't support internal TDLS setup */
- if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)
- local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
-
result = wiphy_register(local->hw.wiphy);
if (result < 0)
goto fail_wiphy_register;
diff --git a/trunk/net/mac80211/mesh.c b/trunk/net/mac80211/mesh.c
index a7078fdba8ca..a4225ae69681 100644
--- a/trunk/net/mac80211/mesh.c
+++ b/trunk/net/mac80211/mesh.c
@@ -320,6 +320,64 @@ mesh_add_rsn_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
return 0;
}
+int
+mesh_add_srates_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_supported_band *sband;
+ int rate;
+ u8 i, rates, *pos;
+
+ sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ rates = sband->n_bitrates;
+ if (rates > 8)
+ rates = 8;
+
+ if (skb_tailroom(skb) < rates + 2)
+ return -ENOMEM;
+
+ pos = skb_put(skb, rates + 2);
+ *pos++ = WLAN_EID_SUPP_RATES;
+ *pos++ = rates;
+ for (i = 0; i < rates; i++) {
+ rate = sband->bitrates[i].bitrate;
+ *pos++ = (u8) (rate / 5);
+ }
+
+ return 0;
+}
+
+int
+mesh_add_ext_srates_ie(struct sk_buff *skb,
+ struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_supported_band *sband;
+ int rate;
+ u8 i, exrates, *pos;
+
+ sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ exrates = sband->n_bitrates;
+ if (exrates > 8)
+ exrates -= 8;
+ else
+ exrates = 0;
+
+ if (skb_tailroom(skb) < exrates + 2)
+ return -ENOMEM;
+
+ if (exrates) {
+ pos = skb_put(skb, exrates + 2);
+ *pos++ = WLAN_EID_EXT_SUPP_RATES;
+ *pos++ = exrates;
+ for (i = 8; i < sband->n_bitrates; i++) {
+ rate = sband->bitrates[i].bitrate;
+ *pos++ = (u8) (rate / 5);
+ }
+ }
+ return 0;
+}
+
int mesh_add_ds_params_ie(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata)
{
diff --git a/trunk/net/mac80211/mesh.h b/trunk/net/mac80211/mesh.h
index 8c00e2d1d636..7118e8e8855c 100644
--- a/trunk/net/mac80211/mesh.h
+++ b/trunk/net/mac80211/mesh.h
@@ -210,6 +210,10 @@ int mesh_add_rsn_ie(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata);
int mesh_add_vendor_ies(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata);
+int mesh_add_srates_ie(struct sk_buff *skb,
+ struct ieee80211_sub_if_data *sdata);
+int mesh_add_ext_srates_ie(struct sk_buff *skb,
+ struct ieee80211_sub_if_data *sdata);
int mesh_add_ds_params_ie(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata);
void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
diff --git a/trunk/net/mac80211/mesh_plink.c b/trunk/net/mac80211/mesh_plink.c
index 7e57f5d07f66..4396906175ae 100644
--- a/trunk/net/mac80211/mesh_plink.c
+++ b/trunk/net/mac80211/mesh_plink.c
@@ -43,10 +43,6 @@ enum plink_event {
CLS_IGNR
};
-static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
- enum ieee80211_self_protected_actioncode action,
- u8 *da, __le16 llid, __le16 plid, __le16 reason);
-
static inline
void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
{
@@ -92,9 +88,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
if (!sta)
return NULL;
- set_sta_flag(sta, WLAN_STA_AUTH);
- set_sta_flag(sta, WLAN_STA_AUTHORIZED);
- set_sta_flag(sta, WLAN_STA_WME);
+ sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH | WLAN_STA_WME;
sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
rate_control_rate_init(sta);
@@ -139,10 +133,6 @@ void mesh_plink_deactivate(struct sta_info *sta)
spin_lock_bh(&sta->lock);
deactivated = __mesh_plink_deactivate(sta);
- sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED);
- mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
- sta->sta.addr, sta->llid, sta->plid,
- sta->reason);
spin_unlock_bh(&sta->lock);
if (deactivated)
@@ -187,8 +177,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
pos = skb_put(skb, 2);
memcpy(pos + 2, &plid, 2);
}
- if (ieee80211_add_srates_ie(&sdata->vif, skb) ||
- ieee80211_add_ext_srates_ie(&sdata->vif, skb) ||
+ if (mesh_add_srates_ie(skb, sdata) ||
+ mesh_add_ext_srates_ie(skb, sdata) ||
mesh_add_rsn_ie(skb, sdata) ||
mesh_add_meshid_ie(skb, sdata) ||
mesh_add_meshconf_ie(skb, sdata))
@@ -385,7 +375,7 @@ int mesh_plink_open(struct sta_info *sta)
__le16 llid;
struct ieee80211_sub_if_data *sdata = sta->sdata;
- if (!test_sta_flag(sta, WLAN_STA_AUTH))
+ if (!test_sta_flags(sta, WLAN_STA_AUTH))
return -EPERM;
spin_lock_bh(&sta->lock);
@@ -505,7 +495,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
return;
}
- if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) {
+ if (sta && !test_sta_flags(sta, WLAN_STA_AUTH)) {
mpl_dbg("Mesh plink: Action frame from non-authed peer\n");
rcu_read_unlock();
return;
diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c
index 0e5d8daba1ee..1a59fb6630d4 100644
--- a/trunk/net/mac80211/mlme.c
+++ b/trunk/net/mac80211/mlme.c
@@ -348,7 +348,6 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
{
struct sk_buff *skb;
struct ieee80211_hdr_3addr *nullfunc;
- struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif);
if (!skb)
@@ -359,10 +358,6 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
- if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
- IEEE80211_STA_CONNECTION_POLL))
- IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE;
-
ieee80211_tx_skb(sdata, skb);
}
@@ -632,7 +627,7 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_managed *mgd = &sdata->u.mgd;
struct sta_info *sta = NULL;
- bool authorized = false;
+ u32 sta_flags = 0;
if (!mgd->powersave)
return false;
@@ -650,10 +645,13 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
rcu_read_lock();
sta = sta_info_get(sdata, mgd->bssid);
if (sta)
- authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
+ sta_flags = get_sta_flags(sta);
rcu_read_unlock();
- return authorized;
+ if (!(sta_flags & WLAN_STA_AUTHORIZED))
+ return false;
+
+ return true;
}
/* need to hold RTNL or interface lock */
@@ -938,8 +936,8 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
params.aifs, params.cw_min, params.cw_max,
params.txop, params.uapsd);
#endif
- sdata->tx_conf[queue] = params;
- if (drv_conf_tx(local, sdata, queue, ¶ms))
+ local->tx_conf[queue] = params;
+ if (drv_conf_tx(local, queue, ¶ms))
wiphy_debug(local->hw.wiphy,
"failed to set TX queue parameters for queue %d\n",
queue);
@@ -1097,7 +1095,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
mutex_lock(&local->sta_mtx);
sta = sta_info_get(sdata, bssid);
if (sta) {
- set_sta_flag(sta, WLAN_STA_BLOCK_BA);
+ set_sta_flags(sta, WLAN_STA_BLOCK_BA);
ieee80211_sta_tear_down_BA_sessions(sta, tx);
}
mutex_unlock(&local->sta_mtx);
@@ -1139,9 +1137,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
ieee80211_bss_info_change_notify(sdata, changed);
- /* remove AP and TDLS peers */
if (remove_sta)
- sta_info_flush(local, sdata);
+ sta_info_destroy_addr(sdata, bssid);
del_timer_sync(&sdata->u.mgd.conn_mon_timer);
del_timer_sync(&sdata->u.mgd.bcn_mon_timer);
@@ -1242,7 +1239,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
} else {
ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0,
- (u32) -1, true, false);
+ (u32) -1, true);
}
ifmgd->probe_send_count++;
@@ -1515,11 +1512,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
return false;
}
- set_sta_flag(sta, WLAN_STA_AUTH);
- set_sta_flag(sta, WLAN_STA_ASSOC);
- set_sta_flag(sta, WLAN_STA_ASSOC_AP);
+ set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC |
+ WLAN_STA_ASSOC_AP);
if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
- set_sta_flag(sta, WLAN_STA_AUTHORIZED);
+ set_sta_flags(sta, WLAN_STA_AUTHORIZED);
rates = 0;
basic_rates = 0;
@@ -1578,10 +1574,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
rate_control_rate_init(sta);
if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED)
- set_sta_flag(sta, WLAN_STA_MFP);
+ set_sta_flags(sta, WLAN_STA_MFP);
if (elems.wmm_param)
- set_sta_flag(sta, WLAN_STA_WME);
+ set_sta_flags(sta, WLAN_STA_WME);
/* sta_info_reinsert will also unlock the mutex lock */
err = sta_info_reinsert(sta);
@@ -2742,7 +2738,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
req->reason_code, cookie,
!req->local_state_change);
if (assoc_bss)
- sta_info_flush(sdata->local, sdata);
+ sta_info_destroy_addr(sdata, bssid);
mutex_lock(&sdata->local->mtx);
ieee80211_recalc_idle(sdata->local);
@@ -2782,7 +2778,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
ieee80211_send_deauth_disassoc(sdata, req->bss->bssid,
IEEE80211_STYPE_DISASSOC, req->reason_code,
cookie, !req->local_state_change);
- sta_info_flush(sdata->local, sdata);
+ sta_info_destroy_addr(sdata, bssid);
mutex_lock(&sdata->local->mtx);
ieee80211_recalc_idle(sdata->local);
diff --git a/trunk/net/mac80211/pm.c b/trunk/net/mac80211/pm.c
index 9ee7164b207c..6326d3439861 100644
--- a/trunk/net/mac80211/pm.c
+++ b/trunk/net/mac80211/pm.c
@@ -42,7 +42,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
mutex_lock(&local->sta_mtx);
list_for_each_entry(sta, &local->sta_list, list) {
- set_sta_flag(sta, WLAN_STA_BLOCK_BA);
+ set_sta_flags(sta, WLAN_STA_BLOCK_BA);
ieee80211_sta_tear_down_BA_sessions(sta, true);
}
mutex_unlock(&local->sta_mtx);
diff --git a/trunk/net/mac80211/rate.c b/trunk/net/mac80211/rate.c
index ff5c3aa48a15..3d5a2cb835c4 100644
--- a/trunk/net/mac80211/rate.c
+++ b/trunk/net/mac80211/rate.c
@@ -199,7 +199,7 @@ static void rate_control_release(struct kref *kref)
kfree(ctrl_ref);
}
-static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc)
+static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc)
{
struct sk_buff *skb = txrc->skb;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -208,9 +208,7 @@ static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc)
fc = hdr->frame_control;
- return (info->flags & (IEEE80211_TX_CTL_NO_ACK |
- IEEE80211_TX_CTL_USE_MINRATE)) ||
- !ieee80211_is_data(fc);
+ return (info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc);
}
static void rc_send_low_broadcast(s8 *idx, u32 basic_rates,
@@ -235,27 +233,6 @@ static void rc_send_low_broadcast(s8 *idx, u32 basic_rates,
/* could not find a basic rate; use original selection */
}
-static inline s8
-rate_lowest_non_cck_index(struct ieee80211_supported_band *sband,
- struct ieee80211_sta *sta)
-{
- int i;
-
- for (i = 0; i < sband->n_bitrates; i++) {
- struct ieee80211_rate *srate = &sband->bitrates[i];
- if ((srate->bitrate == 10) || (srate->bitrate == 20) ||
- (srate->bitrate == 55) || (srate->bitrate == 110))
- continue;
-
- if (rate_supported(sta, sband->band, i))
- return i;
- }
-
- /* No matching rate found */
- return 0;
-}
-
-
bool rate_control_send_low(struct ieee80211_sta *sta,
void *priv_sta,
struct ieee80211_tx_rate_control *txrc)
@@ -264,14 +241,8 @@ bool rate_control_send_low(struct ieee80211_sta *sta,
struct ieee80211_supported_band *sband = txrc->sband;
int mcast_rate;
- if (!sta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) {
- if ((sband->band != IEEE80211_BAND_2GHZ) ||
- !(info->flags & IEEE80211_TX_CTL_NO_CCK_RATE))
- info->control.rates[0].idx =
- rate_lowest_index(txrc->sband, sta);
- else
- info->control.rates[0].idx =
- rate_lowest_non_cck_index(txrc->sband, sta);
+ if (!sta || !priv_sta || rc_no_data_or_no_ack(txrc)) {
+ info->control.rates[0].idx = rate_lowest_index(txrc->sband, sta);
info->control.rates[0].count =
(info->flags & IEEE80211_TX_CTL_NO_ACK) ?
1 : txrc->hw->max_rate_tries;
diff --git a/trunk/net/mac80211/rc80211_minstrel_ht.c b/trunk/net/mac80211/rc80211_minstrel_ht.c
index cdb28535716b..e19249b0f971 100644
--- a/trunk/net/mac80211/rc80211_minstrel_ht.c
+++ b/trunk/net/mac80211/rc80211_minstrel_ht.c
@@ -281,8 +281,6 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
mr = minstrel_get_ratestats(mi, mg->max_tp_rate);
if (cur_tp < mr->cur_tp) {
- mi->max_tp_rate2 = mi->max_tp_rate;
- cur_tp2 = cur_tp;
mi->max_tp_rate = mg->max_tp_rate;
cur_tp = mr->cur_tp;
}
diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c
index b867bd55de7a..db46601e50bf 100644
--- a/trunk/net/mac80211/rx.c
+++ b/trunk/net/mac80211/rx.c
@@ -841,7 +841,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
ieee80211_is_pspoll(hdr->frame_control)) &&
rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
- (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) {
+ (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) {
if (rx->sta && rx->sta->dummy &&
ieee80211_is_data_present(hdr->frame_control)) {
u16 ethertype;
@@ -1110,7 +1110,7 @@ static void ap_sta_ps_start(struct sta_info *sta)
struct ieee80211_local *local = sdata->local;
atomic_inc(&sdata->bss->num_sta_ps);
- set_sta_flag(sta, WLAN_STA_PS_STA);
+ set_sta_flags(sta, WLAN_STA_PS_STA);
if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta);
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
@@ -1130,7 +1130,7 @@ static void ap_sta_ps_end(struct sta_info *sta)
sdata->name, sta->sta.addr, sta->sta.aid);
#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
- if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
+ if (test_sta_flags(sta, WLAN_STA_PS_DRIVER)) {
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n",
sdata->name, sta->sta.addr, sta->sta.aid);
@@ -1149,7 +1149,7 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start)
WARN_ON(!(sta_inf->local->hw.flags & IEEE80211_HW_AP_LINK_PS));
/* Don't let the same PS state be set twice */
- in_ps = test_sta_flag(sta_inf, WLAN_STA_PS_STA);
+ in_ps = test_sta_flags(sta_inf, WLAN_STA_PS_STA);
if ((start && in_ps) || (!start && !in_ps))
return -EINVAL;
@@ -1162,81 +1162,6 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start)
}
EXPORT_SYMBOL(ieee80211_sta_ps_transition);
-static ieee80211_rx_result debug_noinline
-ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx)
-{
- struct ieee80211_sub_if_data *sdata = rx->sdata;
- struct ieee80211_hdr *hdr = (void *)rx->skb->data;
- struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
- int tid, ac;
-
- if (!rx->sta || !(status->rx_flags & IEEE80211_RX_RA_MATCH))
- return RX_CONTINUE;
-
- if (sdata->vif.type != NL80211_IFTYPE_AP &&
- sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
- return RX_CONTINUE;
-
- /*
- * The device handles station powersave, so don't do anything about
- * uAPSD and PS-Poll frames (the latter shouldn't even come up from
- * it to mac80211 since they're handled.)
- */
- if (sdata->local->hw.flags & IEEE80211_HW_AP_LINK_PS)
- return RX_CONTINUE;
-
- /*
- * Don't do anything if the station isn't already asleep. In
- * the uAPSD case, the station will probably be marked asleep,
- * in the PS-Poll case the station must be confused ...
- */
- if (!test_sta_flag(rx->sta, WLAN_STA_PS_STA))
- return RX_CONTINUE;
-
- if (unlikely(ieee80211_is_pspoll(hdr->frame_control))) {
- if (!test_sta_flag(rx->sta, WLAN_STA_SP)) {
- if (!test_sta_flag(rx->sta, WLAN_STA_PS_DRIVER))
- ieee80211_sta_ps_deliver_poll_response(rx->sta);
- else
- set_sta_flag(rx->sta, WLAN_STA_PSPOLL);
- }
-
- /* Free PS Poll skb here instead of returning RX_DROP that would
- * count as an dropped frame. */
- dev_kfree_skb(rx->skb);
-
- return RX_QUEUED;
- } else if (!ieee80211_has_morefrags(hdr->frame_control) &&
- !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
- ieee80211_has_pm(hdr->frame_control) &&
- (ieee80211_is_data_qos(hdr->frame_control) ||
- ieee80211_is_qos_nullfunc(hdr->frame_control))) {
- tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
- ac = ieee802_1d_to_ac[tid & 7];
-
- /*
- * If this AC is not trigger-enabled do nothing.
- *
- * NB: This could/should check a separate bitmap of trigger-
- * enabled queues, but for now we only implement uAPSD w/o
- * TSPEC changes to the ACs, so they're always the same.
- */
- if (!(rx->sta->sta.uapsd_queues & BIT(ac)))
- return RX_CONTINUE;
-
- /* if we are in a service period, do nothing */
- if (test_sta_flag(rx->sta, WLAN_STA_SP))
- return RX_CONTINUE;
-
- if (!test_sta_flag(rx->sta, WLAN_STA_PS_DRIVER))
- ieee80211_sta_ps_deliver_uapsd(rx->sta);
- else
- set_sta_flag(rx->sta, WLAN_STA_UAPSD);
- }
-
- return RX_CONTINUE;
-}
-
static ieee80211_rx_result debug_noinline
ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
{
@@ -1295,7 +1220,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
!(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
(rx->sdata->vif.type == NL80211_IFTYPE_AP ||
rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) {
- if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
+ if (test_sta_flags(sta, WLAN_STA_PS_STA)) {
/*
* Ignore doze->wake transitions that are
* indicated by non-data frames, the standard
@@ -1547,6 +1472,33 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
return RX_CONTINUE;
}
+static ieee80211_rx_result debug_noinline
+ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
+{
+ struct ieee80211_sub_if_data *sdata = rx->sdata;
+ __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
+
+ if (likely(!rx->sta || !ieee80211_is_pspoll(fc) ||
+ !(status->rx_flags & IEEE80211_RX_RA_MATCH)))
+ return RX_CONTINUE;
+
+ if ((sdata->vif.type != NL80211_IFTYPE_AP) &&
+ (sdata->vif.type != NL80211_IFTYPE_AP_VLAN))
+ return RX_DROP_UNUSABLE;
+
+ if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER))
+ ieee80211_sta_ps_deliver_poll_response(rx->sta);
+ else
+ set_sta_flags(rx->sta, WLAN_STA_PSPOLL);
+
+ /* Free PS Poll skb here instead of returning RX_DROP that would
+ * count as an dropped frame. */
+ dev_kfree_skb(rx->skb);
+
+ return RX_QUEUED;
+}
+
static ieee80211_rx_result debug_noinline
ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx)
{
@@ -1570,7 +1522,7 @@ static int
ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx)
{
if (unlikely(!rx->sta ||
- !test_sta_flag(rx->sta, WLAN_STA_AUTHORIZED)))
+ !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED)))
return -EACCES;
return 0;
@@ -1613,7 +1565,7 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
if (status->flag & RX_FLAG_DECRYPTED)
return 0;
- if (rx->sta && test_sta_flag(rx->sta, WLAN_STA_MFP)) {
+ if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {
if (unlikely(!ieee80211_has_protected(fc) &&
ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
rx->key)) {
@@ -2615,9 +2567,9 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx)
CALL_RXH(ieee80211_rx_h_decrypt)
CALL_RXH(ieee80211_rx_h_check_more_data)
- CALL_RXH(ieee80211_rx_h_uapsd_and_pspoll)
CALL_RXH(ieee80211_rx_h_sta_process)
CALL_RXH(ieee80211_rx_h_defragment)
+ CALL_RXH(ieee80211_rx_h_ps_poll)
CALL_RXH(ieee80211_rx_h_michael_mic_verify)
/* must be after MMIC verify so header is counted in MPDU mic */
#ifdef CONFIG_MAC80211_MESH
diff --git a/trunk/net/mac80211/scan.c b/trunk/net/mac80211/scan.c
index 830e60f65779..6f09eca01112 100644
--- a/trunk/net/mac80211/scan.c
+++ b/trunk/net/mac80211/scan.c
@@ -660,8 +660,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
local->scan_req->ssids[i].ssid,
local->scan_req->ssids[i].ssid_len,
local->scan_req->ie, local->scan_req->ie_len,
- local->scan_req->rates[band], false,
- local->scan_req->no_cck);
+ local->scan_req->rates[band], false);
/*
* After sending probe requests, wait for probe responses
diff --git a/trunk/net/mac80211/sta_info.c b/trunk/net/mac80211/sta_info.c
index 076593bffbcf..c52e58c0a979 100644
--- a/trunk/net/mac80211/sta_info.c
+++ b/trunk/net/mac80211/sta_info.c
@@ -24,7 +24,6 @@
#include "sta_info.h"
#include "debugfs_sta.h"
#include "mesh.h"
-#include "wme.h"
/**
* DOC: STA information lifetime rules
@@ -244,22 +243,13 @@ static void sta_unblock(struct work_struct *wk)
if (sta->dead)
return;
- if (!test_sta_flag(sta, WLAN_STA_PS_STA))
+ if (!test_sta_flags(sta, WLAN_STA_PS_STA))
ieee80211_sta_ps_deliver_wakeup(sta);
- else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL)) {
- clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-
- local_bh_disable();
+ else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) {
+ clear_sta_flags(sta, WLAN_STA_PS_DRIVER);
ieee80211_sta_ps_deliver_poll_response(sta);
- local_bh_enable();
- } else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD)) {
- clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-
- local_bh_disable();
- ieee80211_sta_ps_deliver_uapsd(sta);
- local_bh_enable();
} else
- clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
+ clear_sta_flags(sta, WLAN_STA_PS_DRIVER);
}
static int sta_prepare_rate_control(struct ieee80211_local *local,
@@ -292,6 +282,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
return NULL;
spin_lock_init(&sta->lock);
+ spin_lock_init(&sta->flaglock);
INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
mutex_init(&sta->ampdu_mlme.mtx);
@@ -318,10 +309,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
*/
sta->timer_to_tid[i] = i;
}
- for (i = 0; i < IEEE80211_NUM_ACS; i++) {
- skb_queue_head_init(&sta->ps_tx_buf[i]);
- skb_queue_head_init(&sta->tx_filtered[i]);
- }
+ skb_queue_head_init(&sta->ps_tx_buf);
+ skb_queue_head_init(&sta->tx_filtered);
for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX);
@@ -652,84 +641,54 @@ static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid)
bss->tim[aid / 8] &= ~(1 << (aid % 8));
}
-static unsigned long ieee80211_tids_for_ac(int ac)
+static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss,
+ struct sta_info *sta)
{
- /* If we ever support TIDs > 7, this obviously needs to be adjusted */
- switch (ac) {
- case IEEE80211_AC_VO:
- return BIT(6) | BIT(7);
- case IEEE80211_AC_VI:
- return BIT(4) | BIT(5);
- case IEEE80211_AC_BE:
- return BIT(0) | BIT(3);
- case IEEE80211_AC_BK:
- return BIT(1) | BIT(2);
- default:
- WARN_ON(1);
- return 0;
+ BUG_ON(!bss);
+
+ __bss_tim_set(bss, sta->sta.aid);
+
+ if (sta->local->ops->set_tim) {
+ sta->local->tim_in_locked_section = true;
+ drv_set_tim(sta->local, &sta->sta, true);
+ sta->local->tim_in_locked_section = false;
}
}
-void sta_info_recalc_tim(struct sta_info *sta)
+void sta_info_set_tim_bit(struct sta_info *sta)
{
- struct ieee80211_local *local = sta->local;
- struct ieee80211_if_ap *bss = sta->sdata->bss;
unsigned long flags;
- bool indicate_tim = false;
- u8 ignore_for_tim = sta->sta.uapsd_queues;
- int ac;
- if (WARN_ON_ONCE(!sta->sdata->bss))
- return;
+ BUG_ON(!sta->sdata->bss);
- /* No need to do anything if the driver does all */
- if (local->hw.flags & IEEE80211_HW_AP_LINK_PS)
- return;
-
- if (sta->dead)
- goto done;
-
- /*
- * If all ACs are delivery-enabled then we should build
- * the TIM bit for all ACs anyway; if only some are then
- * we ignore those and build the TIM bit using only the
- * non-enabled ones.
- */
- if (ignore_for_tim == BIT(IEEE80211_NUM_ACS) - 1)
- ignore_for_tim = 0;
-
- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
- unsigned long tids;
-
- if (ignore_for_tim & BIT(ac))
- continue;
+ spin_lock_irqsave(&sta->local->sta_lock, flags);
+ __sta_info_set_tim_bit(sta->sdata->bss, sta);
+ spin_unlock_irqrestore(&sta->local->sta_lock, flags);
+}
- indicate_tim |= !skb_queue_empty(&sta->tx_filtered[ac]) ||
- !skb_queue_empty(&sta->ps_tx_buf[ac]);
- if (indicate_tim)
- break;
+static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss,
+ struct sta_info *sta)
+{
+ BUG_ON(!bss);
- tids = ieee80211_tids_for_ac(ac);
+ __bss_tim_clear(bss, sta->sta.aid);
- indicate_tim |=
- sta->driver_buffered_tids & tids;
+ if (sta->local->ops->set_tim) {
+ sta->local->tim_in_locked_section = true;
+ drv_set_tim(sta->local, &sta->sta, false);
+ sta->local->tim_in_locked_section = false;
}
+}
- done:
- spin_lock_irqsave(&local->sta_lock, flags);
-
- if (indicate_tim)
- __bss_tim_set(bss, sta->sta.aid);
- else
- __bss_tim_clear(bss, sta->sta.aid);
+void sta_info_clear_tim_bit(struct sta_info *sta)
+{
+ unsigned long flags;
- if (local->ops->set_tim) {
- local->tim_in_locked_section = true;
- drv_set_tim(local, &sta->sta, indicate_tim);
- local->tim_in_locked_section = false;
- }
+ BUG_ON(!sta->sdata->bss);
- spin_unlock_irqrestore(&local->sta_lock, flags);
+ spin_lock_irqsave(&sta->local->sta_lock, flags);
+ __sta_info_clear_tim_bit(sta->sdata->bss, sta);
+ spin_unlock_irqrestore(&sta->local->sta_lock, flags);
}
static bool sta_info_buffer_expired(struct sta_info *sta, struct sk_buff *skb)
@@ -752,59 +711,21 @@ static bool sta_info_buffer_expired(struct sta_info *sta, struct sk_buff *skb)
}
-static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local,
- struct sta_info *sta, int ac)
+static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
+ struct sta_info *sta)
{
unsigned long flags;
struct sk_buff *skb;
- /*
- * First check for frames that should expire on the filtered
- * queue. Frames here were rejected by the driver and are on
- * a separate queue to avoid reordering with normal PS-buffered
- * frames. They also aren't accounted for right now in the
- * total_ps_buffered counter.
- */
- for (;;) {
- spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags);
- skb = skb_peek(&sta->tx_filtered[ac]);
- if (sta_info_buffer_expired(sta, skb))
- skb = __skb_dequeue(&sta->tx_filtered[ac]);
- else
- skb = NULL;
- spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags);
-
- /*
- * Frames are queued in order, so if this one
- * hasn't expired yet we can stop testing. If
- * we actually reached the end of the queue we
- * also need to stop, of course.
- */
- if (!skb)
- break;
- dev_kfree_skb(skb);
- }
-
- /*
- * Now also check the normal PS-buffered queue, this will
- * only find something if the filtered queue was emptied
- * since the filtered frames are all before the normal PS
- * buffered frames.
- */
for (;;) {
- spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags);
- skb = skb_peek(&sta->ps_tx_buf[ac]);
+ spin_lock_irqsave(&sta->ps_tx_buf.lock, flags);
+ skb = skb_peek(&sta->ps_tx_buf);
if (sta_info_buffer_expired(sta, skb))
- skb = __skb_dequeue(&sta->ps_tx_buf[ac]);
+ skb = __skb_dequeue(&sta->ps_tx_buf);
else
skb = NULL;
- spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags);
+ spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags);
- /*
- * frames are queued in order, so if this one
- * hasn't expired yet (or we reached the end of
- * the queue) we can stop testing
- */
if (!skb)
break;
@@ -814,47 +735,22 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local,
sta->sta.addr);
#endif
dev_kfree_skb(skb);
- }
- /*
- * Finally, recalculate the TIM bit for this station -- it might
- * now be clear because the station was too slow to retrieve its
- * frames.
- */
- sta_info_recalc_tim(sta);
-
- /*
- * Return whether there are any frames still buffered, this is
- * used to check whether the cleanup timer still needs to run,
- * if there are no frames we don't need to rearm the timer.
- */
- return !(skb_queue_empty(&sta->ps_tx_buf[ac]) &&
- skb_queue_empty(&sta->tx_filtered[ac]));
-}
-
-static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
- struct sta_info *sta)
-{
- bool have_buffered = false;
- int ac;
-
- /* This is only necessary for stations on BSS interfaces */
- if (!sta->sdata->bss)
- return false;
-
- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
- have_buffered |=
- sta_info_cleanup_expire_buffered_ac(local, sta, ac);
+ if (skb_queue_empty(&sta->ps_tx_buf) &&
+ !test_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF))
+ sta_info_clear_tim_bit(sta);
+ }
- return have_buffered;
+ return !skb_queue_empty(&sta->ps_tx_buf);
}
static int __must_check __sta_info_destroy(struct sta_info *sta)
{
struct ieee80211_local *local;
struct ieee80211_sub_if_data *sdata;
+ struct sk_buff *skb;
unsigned long flags;
- int ret, i, ac;
+ int ret, i;
might_sleep();
@@ -870,7 +766,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
* sessions -- block that to make sure the tear-down
* will be sufficient.
*/
- set_sta_flag(sta, WLAN_STA_BLOCK_BA);
+ set_sta_flags(sta, WLAN_STA_BLOCK_BA);
ieee80211_sta_tear_down_BA_sessions(sta, true);
spin_lock_irqsave(&local->sta_lock, flags);
@@ -891,15 +787,12 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
sta->dead = true;
- if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
- test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
+ if (test_and_clear_sta_flags(sta,
+ WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) {
BUG_ON(!sdata->bss);
- clear_sta_flag(sta, WLAN_STA_PS_STA);
- clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-
atomic_dec(&sdata->bss->num_sta_ps);
- sta_info_recalc_tim(sta);
+ sta_info_clear_tim_bit(sta);
}
local->num_sta--;
@@ -925,12 +818,6 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
*/
synchronize_rcu();
- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
- local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
- __skb_queue_purge(&sta->ps_tx_buf[ac]);
- __skb_queue_purge(&sta->tx_filtered[ac]);
- }
-
#ifdef CONFIG_MAC80211_MESH
if (ieee80211_vif_is_mesh(&sdata->vif))
mesh_accept_plinks_update(sdata);
@@ -953,6 +840,14 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
}
#endif
+ while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) {
+ local->total_ps_buffered--;
+ dev_kfree_skb_any(skb);
+ }
+
+ while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL)
+ dev_kfree_skb_any(skb);
+
__sta_info_free(local, sta);
return 0;
@@ -1118,8 +1013,7 @@ static void clear_sta_ps_flags(void *_sta)
{
struct sta_info *sta = _sta;
- clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
- clear_sta_flag(sta, WLAN_STA_PS_STA);
+ clear_sta_flags(sta, WLAN_STA_PS_DRIVER | WLAN_STA_PS_STA);
}
/* powersave support code */
@@ -1127,341 +1021,86 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
struct ieee80211_local *local = sdata->local;
- struct sk_buff_head pending;
- int filtered = 0, buffered = 0, ac;
-
- clear_sta_flag(sta, WLAN_STA_SP);
-
- BUILD_BUG_ON(BITS_TO_LONGS(STA_TID_NUM) > 1);
- sta->driver_buffered_tids = 0;
+ int sent, buffered;
+ clear_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF);
if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta);
- skb_queue_head_init(&pending);
+ if (!skb_queue_empty(&sta->ps_tx_buf))
+ sta_info_clear_tim_bit(sta);
/* Send all buffered frames to the station */
- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
- int count = skb_queue_len(&pending), tmp;
-
- skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending);
- tmp = skb_queue_len(&pending);
- filtered += tmp - count;
- count = tmp;
-
- skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending);
- tmp = skb_queue_len(&pending);
- buffered += tmp - count;
- }
-
- ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta);
-
+ sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered);
+ buffered = ieee80211_add_pending_skbs_fn(local, &sta->ps_tx_buf,
+ clear_sta_ps_flags, sta);
+ sent += buffered;
local->total_ps_buffered -= buffered;
- sta_info_recalc_tim(sta);
-
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames "
"since STA not sleeping anymore\n", sdata->name,
- sta->sta.addr, sta->sta.aid, filtered, buffered);
+ sta->sta.addr, sta->sta.aid, sent - buffered, buffered);
#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
}
-static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata,
- struct sta_info *sta, int tid,
- enum ieee80211_frame_release_type reason)
-{
- struct ieee80211_local *local = sdata->local;
- struct ieee80211_qos_hdr *nullfunc;
- struct sk_buff *skb;
- int size = sizeof(*nullfunc);
- __le16 fc;
- bool qos = test_sta_flag(sta, WLAN_STA_WME);
- struct ieee80211_tx_info *info;
-
- if (qos) {
- fc = cpu_to_le16(IEEE80211_FTYPE_DATA |
- IEEE80211_STYPE_QOS_NULLFUNC |
- IEEE80211_FCTL_FROMDS);
- } else {
- size -= 2;
- fc = cpu_to_le16(IEEE80211_FTYPE_DATA |
- IEEE80211_STYPE_NULLFUNC |
- IEEE80211_FCTL_FROMDS);
- }
-
- skb = dev_alloc_skb(local->hw.extra_tx_headroom + size);
- if (!skb)
- return;
-
- skb_reserve(skb, local->hw.extra_tx_headroom);
-
- nullfunc = (void *) skb_put(skb, size);
- nullfunc->frame_control = fc;
- nullfunc->duration_id = 0;
- memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN);
- memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
- memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN);
-
- if (qos) {
- skb->priority = tid;
-
- skb_set_queue_mapping(skb, ieee802_1d_to_ac[tid]);
-
- nullfunc->qos_ctrl = cpu_to_le16(tid);
-
- if (reason == IEEE80211_FRAME_RELEASE_UAPSD)
- nullfunc->qos_ctrl |=
- cpu_to_le16(IEEE80211_QOS_CTL_EOSP);
- }
-
- info = IEEE80211_SKB_CB(skb);
-
- /*
- * Tell TX path to send this frame even though the
- * STA may still remain is PS mode after this frame
- * exchange. Also set EOSP to indicate this packet
- * ends the poll/service period.
- */
- info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE |
- IEEE80211_TX_STATUS_EOSP |
- IEEE80211_TX_CTL_REQ_TX_STATUS;
-
- drv_allow_buffered_frames(local, sta, BIT(tid), 1, reason, false);
-
- ieee80211_xmit(sdata, skb);
-}
-
-static void
-ieee80211_sta_ps_deliver_response(struct sta_info *sta,
- int n_frames, u8 ignored_acs,
- enum ieee80211_frame_release_type reason)
+void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
struct ieee80211_local *local = sdata->local;
- bool found = false;
- bool more_data = false;
- int ac;
- unsigned long driver_release_tids = 0;
- struct sk_buff_head frames;
-
- /* Service or PS-Poll period starts */
- set_sta_flag(sta, WLAN_STA_SP);
-
- __skb_queue_head_init(&frames);
-
- /*
- * Get response frame(s) and more data bit for it.
- */
- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
- unsigned long tids;
-
- if (ignored_acs & BIT(ac))
- continue;
-
- tids = ieee80211_tids_for_ac(ac);
-
- if (!found) {
- driver_release_tids = sta->driver_buffered_tids & tids;
- if (driver_release_tids) {
- found = true;
- } else {
- struct sk_buff *skb;
-
- while (n_frames > 0) {
- skb = skb_dequeue(&sta->tx_filtered[ac]);
- if (!skb) {
- skb = skb_dequeue(
- &sta->ps_tx_buf[ac]);
- if (skb)
- local->total_ps_buffered--;
- }
- if (!skb)
- break;
- n_frames--;
- found = true;
- __skb_queue_tail(&frames, skb);
- }
- }
-
- /*
- * If the driver has data on more than one TID then
- * certainly there's more data if we release just a
- * single frame now (from a single TID).
- */
- if (reason == IEEE80211_FRAME_RELEASE_PSPOLL &&
- hweight16(driver_release_tids) > 1) {
- more_data = true;
- driver_release_tids =
- BIT(ffs(driver_release_tids) - 1);
- break;
- }
- }
+ struct sk_buff *skb;
+ int no_pending_pkts;
- if (!skb_queue_empty(&sta->tx_filtered[ac]) ||
- !skb_queue_empty(&sta->ps_tx_buf[ac])) {
- more_data = true;
- break;
- }
+ skb = skb_dequeue(&sta->tx_filtered);
+ if (!skb) {
+ skb = skb_dequeue(&sta->ps_tx_buf);
+ if (skb)
+ local->total_ps_buffered--;
}
+ no_pending_pkts = skb_queue_empty(&sta->tx_filtered) &&
+ skb_queue_empty(&sta->ps_tx_buf);
- if (!found) {
- int tid;
+ if (skb) {
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr =
+ (struct ieee80211_hdr *) skb->data;
/*
- * For PS-Poll, this can only happen due to a race condition
- * when we set the TIM bit and the station notices it, but
- * before it can poll for the frame we expire it.
- *
- * For uAPSD, this is said in the standard (11.2.1.5 h):
- * At each unscheduled SP for a non-AP STA, the AP shall
- * attempt to transmit at least one MSDU or MMPDU, but no
- * more than the value specified in the Max SP Length field
- * in the QoS Capability element from delivery-enabled ACs,
- * that are destined for the non-AP STA.
- *
- * Since we have no other MSDU/MMPDU, transmit a QoS null frame.
+ * Tell TX path to send this frame even though the STA may
+ * still remain is PS mode after this frame exchange.
*/
+ info->flags |= IEEE80211_TX_CTL_PSPOLL_RESPONSE;
- /* This will evaluate to 1, 3, 5 or 7. */
- tid = 7 - ((ffs(~ignored_acs) - 1) << 1);
-
- ieee80211_send_null_response(sdata, sta, tid, reason);
- return;
- }
-
- if (!driver_release_tids) {
- struct sk_buff_head pending;
- struct sk_buff *skb;
- int num = 0;
- u16 tids = 0;
-
- skb_queue_head_init(&pending);
-
- while ((skb = __skb_dequeue(&frames))) {
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr *hdr = (void *) skb->data;
- u8 *qoshdr = NULL;
-
- num++;
-
- /*
- * Tell TX path to send this frame even though the
- * STA may still remain is PS mode after this frame
- * exchange.
- */
- info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE;
-
- /*
- * Use MoreData flag to indicate whether there are
- * more buffered frames for this STA
- */
- if (!more_data)
- hdr->frame_control &=
- cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
- else
- hdr->frame_control |=
- cpu_to_le16(IEEE80211_FCTL_MOREDATA);
-
- if (ieee80211_is_data_qos(hdr->frame_control) ||
- ieee80211_is_qos_nullfunc(hdr->frame_control))
- qoshdr = ieee80211_get_qos_ctl(hdr);
-
- /* set EOSP for the frame */
- if (reason == IEEE80211_FRAME_RELEASE_UAPSD &&
- qoshdr && skb_queue_empty(&frames))
- *qoshdr |= IEEE80211_QOS_CTL_EOSP;
-
- info->flags |= IEEE80211_TX_STATUS_EOSP |
- IEEE80211_TX_CTL_REQ_TX_STATUS;
-
- if (qoshdr)
- tids |= BIT(*qoshdr & IEEE80211_QOS_CTL_TID_MASK);
- else
- tids |= BIT(0);
-
- __skb_queue_tail(&pending, skb);
- }
+#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
+ printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n",
+ sta->sta.addr, sta->sta.aid,
+ skb_queue_len(&sta->ps_tx_buf));
+#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
- drv_allow_buffered_frames(local, sta, tids, num,
- reason, more_data);
+ /* Use MoreData flag to indicate whether there are more
+ * buffered frames for this STA */
+ if (no_pending_pkts)
+ hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
+ else
+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
- ieee80211_add_pending_skbs(local, &pending);
+ ieee80211_add_pending_skb(local, skb);
- sta_info_recalc_tim(sta);
+ if (no_pending_pkts)
+ sta_info_clear_tim_bit(sta);
+#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
} else {
/*
- * We need to release a frame that is buffered somewhere in the
- * driver ... it'll have to handle that.
- * Note that, as per the comment above, it'll also have to see
- * if there is more than just one frame on the specific TID that
- * we're releasing from, and it needs to set the more-data bit
- * accordingly if we tell it that there's no more data. If we do
- * tell it there's more data, then of course the more-data bit
- * needs to be set anyway.
+ * FIXME: This can be the result of a race condition between
+ * us expiring a frame and the station polling for it.
+ * Should we send it a null-func frame indicating we
+ * have nothing buffered for it?
*/
- drv_release_buffered_frames(local, sta, driver_release_tids,
- n_frames, reason, more_data);
-
- /*
- * Note that we don't recalculate the TIM bit here as it would
- * most likely have no effect at all unless the driver told us
- * that the TID became empty before returning here from the
- * release function.
- * Either way, however, when the driver tells us that the TID
- * became empty we'll do the TIM recalculation.
- */
- }
-}
-
-void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
-{
- u8 ignore_for_response = sta->sta.uapsd_queues;
-
- /*
- * If all ACs are delivery-enabled then we should reply
- * from any of them, if only some are enabled we reply
- * only from the non-enabled ones.
- */
- if (ignore_for_response == BIT(IEEE80211_NUM_ACS) - 1)
- ignore_for_response = 0;
-
- ieee80211_sta_ps_deliver_response(sta, 1, ignore_for_response,
- IEEE80211_FRAME_RELEASE_PSPOLL);
-}
-
-void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta)
-{
- int n_frames = sta->sta.max_sp;
- u8 delivery_enabled = sta->sta.uapsd_queues;
-
- /*
- * If we ever grow support for TSPEC this might happen if
- * the TSPEC update from hostapd comes in between a trigger
- * frame setting WLAN_STA_UAPSD in the RX path and this
- * actually getting called.
- */
- if (!delivery_enabled)
- return;
-
- switch (sta->sta.max_sp) {
- case 1:
- n_frames = 2;
- break;
- case 2:
- n_frames = 4;
- break;
- case 3:
- n_frames = 6;
- break;
- case 0:
- /* XXX: what is a good value? */
- n_frames = 8;
- break;
+ printk(KERN_DEBUG "%s: STA %pM sent PS Poll even "
+ "though there are no buffered frames for it\n",
+ sdata->name, sta->sta.addr);
+#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
}
-
- ieee80211_sta_ps_deliver_response(sta, n_frames, ~delivery_enabled,
- IEEE80211_FRAME_RELEASE_UAPSD);
}
void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
@@ -1472,50 +1111,17 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
trace_api_sta_block_awake(sta->local, pubsta, block);
if (block)
- set_sta_flag(sta, WLAN_STA_PS_DRIVER);
- else if (test_sta_flag(sta, WLAN_STA_PS_DRIVER))
+ set_sta_flags(sta, WLAN_STA_PS_DRIVER);
+ else if (test_sta_flags(sta, WLAN_STA_PS_DRIVER))
ieee80211_queue_work(hw, &sta->drv_unblock_wk);
}
EXPORT_SYMBOL(ieee80211_sta_block_awake);
-void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta)
-{
- struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
- struct ieee80211_local *local = sta->local;
- struct sk_buff *skb;
- struct skb_eosp_msg_data *data;
-
- trace_api_eosp(local, pubsta);
-
- skb = alloc_skb(0, GFP_ATOMIC);
- if (!skb) {
- /* too bad ... but race is better than loss */
- clear_sta_flag(sta, WLAN_STA_SP);
- return;
- }
-
- data = (void *)skb->cb;
- memcpy(data->sta, pubsta->addr, ETH_ALEN);
- memcpy(data->iface, sta->sdata->vif.addr, ETH_ALEN);
- skb->pkt_type = IEEE80211_EOSP_MSG;
- skb_queue_tail(&local->skb_queue, skb);
- tasklet_schedule(&local->tasklet);
-}
-EXPORT_SYMBOL(ieee80211_sta_eosp_irqsafe);
-
-void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
- u8 tid, bool buffered)
+void ieee80211_sta_set_tim(struct ieee80211_sta *pubsta)
{
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
- if (WARN_ON(tid >= STA_TID_NUM))
- return;
-
- if (buffered)
- set_bit(tid, &sta->driver_buffered_tids);
- else
- clear_bit(tid, &sta->driver_buffered_tids);
-
- sta_info_recalc_tim(sta);
+ set_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF);
+ sta_info_set_tim_bit(sta);
}
-EXPORT_SYMBOL(ieee80211_sta_set_buffered);
+EXPORT_SYMBOL(ieee80211_sta_set_tim);
diff --git a/trunk/net/mac80211/sta_info.h b/trunk/net/mac80211/sta_info.h
index 8c8ce05ad26f..56a3d38a2cd1 100644
--- a/trunk/net/mac80211/sta_info.h
+++ b/trunk/net/mac80211/sta_info.h
@@ -19,8 +19,7 @@
/**
* enum ieee80211_sta_info_flags - Stations flags
*
- * These flags are used with &struct sta_info's @flags member, but
- * only indirectly with set_sta_flag() and friends.
+ * These flags are used with &struct sta_info's @flags member.
*
* @WLAN_STA_AUTH: Station is authenticated.
* @WLAN_STA_ASSOC: Station is associated.
@@ -44,33 +43,24 @@
* be in the queues
* @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping
* station in power-save mode, reply when the driver unblocks.
- * @WLAN_STA_TDLS_PEER: Station is a TDLS peer.
- * @WLAN_STA_TDLS_PEER_AUTH: This TDLS peer is authorized to send direct
- * packets. This means the link is enabled.
- * @WLAN_STA_UAPSD: Station requested unscheduled SP while driver was
- * keeping station in power-save mode, reply when the driver
- * unblocks the station.
- * @WLAN_STA_SP: Station is in a service period, so don't try to
- * reply to other uAPSD trigger frames or PS-Poll.
+ * @WLAN_STA_PS_DRIVER_BUF: Station has frames pending in driver internal
+ * buffers. Automatically cleared on station wake-up.
*/
enum ieee80211_sta_info_flags {
- WLAN_STA_AUTH,
- WLAN_STA_ASSOC,
- WLAN_STA_PS_STA,
- WLAN_STA_AUTHORIZED,
- WLAN_STA_SHORT_PREAMBLE,
- WLAN_STA_ASSOC_AP,
- WLAN_STA_WME,
- WLAN_STA_WDS,
- WLAN_STA_CLEAR_PS_FILT,
- WLAN_STA_MFP,
- WLAN_STA_BLOCK_BA,
- WLAN_STA_PS_DRIVER,
- WLAN_STA_PSPOLL,
- WLAN_STA_TDLS_PEER,
- WLAN_STA_TDLS_PEER_AUTH,
- WLAN_STA_UAPSD,
- WLAN_STA_SP,
+ WLAN_STA_AUTH = 1<<0,
+ WLAN_STA_ASSOC = 1<<1,
+ WLAN_STA_PS_STA = 1<<2,
+ WLAN_STA_AUTHORIZED = 1<<3,
+ WLAN_STA_SHORT_PREAMBLE = 1<<4,
+ WLAN_STA_ASSOC_AP = 1<<5,
+ WLAN_STA_WME = 1<<6,
+ WLAN_STA_WDS = 1<<7,
+ WLAN_STA_CLEAR_PS_FILT = 1<<9,
+ WLAN_STA_MFP = 1<<10,
+ WLAN_STA_BLOCK_BA = 1<<11,
+ WLAN_STA_PS_DRIVER = 1<<12,
+ WLAN_STA_PSPOLL = 1<<13,
+ WLAN_STA_PS_DRIVER_BUF = 1<<14,
};
#define STA_TID_NUM 16
@@ -213,16 +203,15 @@ struct sta_ampdu_mlme {
* @last_rx_rate_flag: rx status flag of the last data packet
* @lock: used for locking all fields that require locking, see comments
* in the header file.
+ * @flaglock: spinlock for flags accesses
* @drv_unblock_wk: used for driver PS unblocking
* @listen_interval: listen interval of this station, when we're acting as AP
- * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly
- * @ps_tx_buf: buffers (per AC) of frames to transmit to this station
- * when it leaves power saving state or polls
- * @tx_filtered: buffers (per AC) of frames we already tried to
- * transmit but were filtered by hardware due to STA having
- * entered power saving state, these are also delivered to
- * the station when it leaves powersave or polls for frames
- * @driver_buffered_tids: bitmap of TIDs the driver has data buffered on
+ * @flags: STA flags, see &enum ieee80211_sta_info_flags
+ * @ps_tx_buf: buffer of frames to transmit to this station
+ * when it leaves power saving state
+ * @tx_filtered: buffer of frames we already tried to transmit
+ * but were filtered by hardware due to STA having entered
+ * power saving state
* @rx_packets: Number of MSDUs received from this STA
* @rx_bytes: Number of bytes received from this STA
* @wep_weak_iv_count: number of weak WEP IVs received from this station
@@ -272,6 +261,7 @@ struct sta_info {
struct rate_control_ref *rate_ctrl;
void *rate_ctrl_priv;
spinlock_t lock;
+ spinlock_t flaglock;
struct work_struct drv_unblock_wk;
@@ -281,16 +271,18 @@ struct sta_info {
bool uploaded;
- /* use the accessors defined below */
- unsigned long _flags;
+ /*
+ * frequently updated, locked with own spinlock (flaglock),
+ * use the accessors defined below
+ */
+ u32 flags;
/*
* STA powersave frame queues, no more than the internal
* locking required.
*/
- struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS];
- struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS];
- unsigned long driver_buffered_tids;
+ struct sk_buff_head ps_tx_buf;
+ struct sk_buff_head tx_filtered;
/* Updated from RX path only, no locking requirements */
unsigned long rx_packets, rx_bytes;
@@ -366,28 +358,60 @@ static inline enum nl80211_plink_state sta_plink_state(struct sta_info *sta)
return NL80211_PLINK_LISTEN;
}
-static inline void set_sta_flag(struct sta_info *sta,
- enum ieee80211_sta_info_flags flag)
+static inline void set_sta_flags(struct sta_info *sta, const u32 flags)
{
- set_bit(flag, &sta->_flags);
+ unsigned long irqfl;
+
+ spin_lock_irqsave(&sta->flaglock, irqfl);
+ sta->flags |= flags;
+ spin_unlock_irqrestore(&sta->flaglock, irqfl);
}
-static inline void clear_sta_flag(struct sta_info *sta,
- enum ieee80211_sta_info_flags flag)
+static inline void clear_sta_flags(struct sta_info *sta, const u32 flags)
{
- clear_bit(flag, &sta->_flags);
+ unsigned long irqfl;
+
+ spin_lock_irqsave(&sta->flaglock, irqfl);
+ sta->flags &= ~flags;
+ spin_unlock_irqrestore(&sta->flaglock, irqfl);
}
-static inline int test_sta_flag(struct sta_info *sta,
- enum ieee80211_sta_info_flags flag)
+static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags)
{
- return test_bit(flag, &sta->_flags);
+ u32 ret;
+ unsigned long irqfl;
+
+ spin_lock_irqsave(&sta->flaglock, irqfl);
+ ret = sta->flags & flags;
+ spin_unlock_irqrestore(&sta->flaglock, irqfl);
+
+ return ret;
}
-static inline int test_and_clear_sta_flag(struct sta_info *sta,
- enum ieee80211_sta_info_flags flag)
+static inline u32 test_and_clear_sta_flags(struct sta_info *sta,
+ const u32 flags)
{
- return test_and_clear_bit(flag, &sta->_flags);
+ u32 ret;
+ unsigned long irqfl;
+
+ spin_lock_irqsave(&sta->flaglock, irqfl);
+ ret = sta->flags & flags;
+ sta->flags &= ~flags;
+ spin_unlock_irqrestore(&sta->flaglock, irqfl);
+
+ return ret;
+}
+
+static inline u32 get_sta_flags(struct sta_info *sta)
+{
+ u32 ret;
+ unsigned long irqfl;
+
+ spin_lock_irqsave(&sta->flaglock, irqfl);
+ ret = sta->flags;
+ spin_unlock_irqrestore(&sta->flaglock, irqfl);
+
+ return ret;
}
void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
@@ -405,8 +429,8 @@ rcu_dereference_protected_tid_tx(struct sta_info *sta, int tid)
#define STA_HASH(sta) (sta[5])
-/* Maximum number of frames to buffer per power saving station per AC */
-#define STA_MAX_TX_BUFFER 64
+/* Maximum number of frames to buffer per power saving station */
+#define STA_MAX_TX_BUFFER 128
/* Minimum buffered frame expiry time. If STA uses listen interval that is
* smaller than this value, the minimum value here is used instead. */
@@ -499,7 +523,8 @@ int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata,
int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata,
const u8 *addr);
-void sta_info_recalc_tim(struct sta_info *sta);
+void sta_info_set_tim_bit(struct sta_info *sta);
+void sta_info_clear_tim_bit(struct sta_info *sta);
void sta_info_init(struct ieee80211_local *local);
void sta_info_stop(struct ieee80211_local *local);
@@ -510,6 +535,5 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta);
void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta);
-void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta);
#endif /* STA_INFO_H */
diff --git a/trunk/net/mac80211/status.c b/trunk/net/mac80211/status.c
index 864a9c3bcf46..d50358c45ab0 100644
--- a/trunk/net/mac80211/status.c
+++ b/trunk/net/mac80211/status.c
@@ -14,7 +14,6 @@
#include "rate.h"
#include "mesh.h"
#include "led.h"
-#include "wme.h"
void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
@@ -44,8 +43,6 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
struct sk_buff *skb)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr *hdr = (void *)skb->data;
- int ac;
/*
* This skb 'survived' a round-trip through the driver, and
@@ -65,38 +62,12 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
sta->tx_filtered_count++;
- /*
- * Clear more-data bit on filtered frames, it might be set
- * but later frames might time out so it might have to be
- * clear again ... It's all rather unlikely (this frame
- * should time out first, right?) but let's not confuse
- * peers unnecessarily.
- */
- if (hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_MOREDATA))
- hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA);
-
- if (ieee80211_is_data_qos(hdr->frame_control)) {
- u8 *p = ieee80211_get_qos_ctl(hdr);
- int tid = *p & IEEE80211_QOS_CTL_TID_MASK;
-
- /*
- * Clear EOSP if set, this could happen e.g.
- * if an absence period (us being a P2P GO)
- * shortens the SP.
- */
- if (*p & IEEE80211_QOS_CTL_EOSP)
- *p &= ~IEEE80211_QOS_CTL_EOSP;
- ac = ieee802_1d_to_ac[tid & 7];
- } else {
- ac = IEEE80211_AC_BE;
- }
-
/*
* Clear the TX filter mask for this STA when sending the next
* packet. If the STA went to power save mode, this will happen
* when it wakes up for the next time.
*/
- set_sta_flag(sta, WLAN_STA_CLEAR_PS_FILT);
+ set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT);
/*
* This code races in the following way:
@@ -132,19 +103,13 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
* changes before calling TX status events if ordering can be
* unknown.
*/
- if (test_sta_flag(sta, WLAN_STA_PS_STA) &&
- skb_queue_len(&sta->tx_filtered[ac]) < STA_MAX_TX_BUFFER) {
- skb_queue_tail(&sta->tx_filtered[ac], skb);
- sta_info_recalc_tim(sta);
-
- if (!timer_pending(&local->sta_cleanup))
- mod_timer(&local->sta_cleanup,
- round_jiffies(jiffies +
- STA_INFO_CLEANUP_INTERVAL));
+ if (test_sta_flags(sta, WLAN_STA_PS_STA) &&
+ skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) {
+ skb_queue_tail(&sta->tx_filtered, skb);
return;
}
- if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
+ if (!test_sta_flags(sta, WLAN_STA_PS_STA) &&
!(info->flags & IEEE80211_TX_INTFL_RETRIED)) {
/* Software retry the packet once */
info->flags |= IEEE80211_TX_INTFL_RETRIED;
@@ -156,8 +121,8 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
if (net_ratelimit())
wiphy_debug(local->hw.wiphy,
"dropped TX filtered frame, queue_len=%d PS=%d @%lu\n",
- skb_queue_len(&sta->tx_filtered[ac]),
- !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies);
+ skb_queue_len(&sta->tx_filtered),
+ !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies);
#endif
dev_kfree_skb(skb);
}
@@ -284,11 +249,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN))
continue;
- if (info->flags & IEEE80211_TX_STATUS_EOSP)
- clear_sta_flag(sta, WLAN_STA_SP);
-
acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
- if (!acked && test_sta_flag(sta, WLAN_STA_PS_STA)) {
+ if (!acked && test_sta_flags(sta, WLAN_STA_PS_STA)) {
/*
* The STA is in power save mode, so assume
* that this TX packet failed because of that.
diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c
index ad2ee4a90ec4..7cd6c28968b2 100644
--- a/trunk/net/mac80211/tx.c
+++ b/trunk/net/mac80211/tx.c
@@ -253,7 +253,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
- bool assoc = false;
+ u32 sta_flags;
if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
return TX_CONTINUE;
@@ -284,11 +284,10 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
if (tx->flags & IEEE80211_TX_PS_BUFFERED)
return TX_CONTINUE;
- if (tx->sta)
- assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC);
+ sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0;
if (likely(tx->flags & IEEE80211_TX_UNICAST)) {
- if (unlikely(!assoc &&
+ if (unlikely(!(sta_flags & WLAN_STA_ASSOC) &&
tx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
ieee80211_is_data(hdr->frame_control))) {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -344,22 +343,13 @@ static void purge_old_ps_buffers(struct ieee80211_local *local)
total += skb_queue_len(&ap->ps_bc_buf);
}
- /*
- * Drop one frame from each station from the lowest-priority
- * AC that has frames at all.
- */
list_for_each_entry_rcu(sta, &local->sta_list, list) {
- int ac;
-
- for (ac = IEEE80211_AC_BK; ac >= IEEE80211_AC_VO; ac--) {
- skb = skb_dequeue(&sta->ps_tx_buf[ac]);
- total += skb_queue_len(&sta->ps_tx_buf[ac]);
- if (skb) {
- purged++;
- dev_kfree_skb(skb);
- break;
- }
+ skb = skb_dequeue(&sta->ps_tx_buf);
+ if (skb) {
+ purged++;
+ dev_kfree_skb(skb);
}
+ total += skb_queue_len(&sta->ps_tx_buf);
}
rcu_read_unlock();
@@ -428,7 +418,7 @@ static int ieee80211_use_mfp(__le16 fc, struct sta_info *sta,
if (!ieee80211_is_mgmt(fc))
return 0;
- if (sta == NULL || !test_sta_flag(sta, WLAN_STA_MFP))
+ if (sta == NULL || !test_sta_flags(sta, WLAN_STA_MFP))
return 0;
if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *)
@@ -445,6 +435,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
struct ieee80211_local *local = tx->local;
+ u32 staflags;
if (unlikely(!sta ||
ieee80211_is_probe_resp(hdr->frame_control) ||
@@ -453,52 +444,57 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
ieee80211_is_reassoc_resp(hdr->frame_control)))
return TX_CONTINUE;
- if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) ||
- test_sta_flag(sta, WLAN_STA_PS_DRIVER)) &&
- !(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE))) {
- int ac = skb_get_queue_mapping(tx->skb);
+ staflags = get_sta_flags(sta);
+ if (unlikely((staflags & (WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) &&
+ !(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE))) {
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
- printk(KERN_DEBUG "STA %pM aid %d: PS buffer for AC %d\n",
- sta->sta.addr, sta->sta.aid, ac);
+ printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries "
+ "before %d)\n",
+ sta->sta.addr, sta->sta.aid,
+ skb_queue_len(&sta->ps_tx_buf));
#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
purge_old_ps_buffers(tx->local);
- if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) {
- struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]);
+ if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) {
+ struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf);
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
- if (net_ratelimit())
- printk(KERN_DEBUG "%s: STA %pM TX buffer for "
- "AC %d full - dropping oldest frame\n",
- tx->sdata->name, sta->sta.addr, ac);
+ if (net_ratelimit()) {
+ printk(KERN_DEBUG "%s: STA %pM TX "
+ "buffer full - dropping oldest frame\n",
+ tx->sdata->name, sta->sta.addr);
+ }
#endif
dev_kfree_skb(old);
} else
tx->local->total_ps_buffered++;
+ /*
+ * Queue frame to be sent after STA wakes up/polls,
+ * but don't set the TIM bit if the driver is blocking
+ * wakeup or poll response transmissions anyway.
+ */
+ if (skb_queue_empty(&sta->ps_tx_buf) &&
+ !(staflags & WLAN_STA_PS_DRIVER))
+ sta_info_set_tim_bit(sta);
+
info->control.jiffies = jiffies;
info->control.vif = &tx->sdata->vif;
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
- skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb);
+ skb_queue_tail(&sta->ps_tx_buf, tx->skb);
if (!timer_pending(&local->sta_cleanup))
mod_timer(&local->sta_cleanup,
round_jiffies(jiffies +
STA_INFO_CLEANUP_INTERVAL));
- /*
- * We queued up some frames, so the TIM bit might
- * need to be set, recalculate it.
- */
- sta_info_recalc_tim(sta);
-
return TX_QUEUED;
}
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
- else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) {
- printk(KERN_DEBUG
- "%s: STA %pM in PS mode, but polling/in SP -> send frame\n",
- tx->sdata->name, sta->sta.addr);
+ else if (unlikely(staflags & WLAN_STA_PS_STA)) {
+ printk(KERN_DEBUG "%s: STA %pM in PS mode, but pspoll "
+ "set -> send frame\n", tx->sdata->name,
+ sta->sta.addr);
}
#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
@@ -556,7 +552,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
!(info->flags & IEEE80211_TX_CTL_INJECTED) &&
(!ieee80211_is_robust_mgmt_frame(hdr) ||
(ieee80211_is_action(hdr->frame_control) &&
- tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP)))) {
+ tx->sta && test_sta_flags(tx->sta, WLAN_STA_MFP)))) {
I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
return TX_DROP;
} else
@@ -615,7 +611,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
u32 len;
bool inval = false, rts = false, short_preamble = false;
struct ieee80211_tx_rate_control txrc;
- bool assoc = false;
+ u32 sta_flags;
memset(&txrc, 0, sizeof(txrc));
@@ -651,17 +647,17 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
*/
if (tx->sdata->vif.bss_conf.use_short_preamble &&
(ieee80211_is_data(hdr->frame_control) ||
- (tx->sta && test_sta_flag(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
+ (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
txrc.short_preamble = short_preamble = true;
- if (tx->sta)
- assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC);
+ sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0;
/*
* Lets not bother rate control if we're associated and cannot
* talk to the sta. This should not happen.
*/
- if (WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) && assoc &&
+ if (WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) &&
+ (sta_flags & WLAN_STA_ASSOC) &&
!rate_usable_index_exists(sband, &tx->sta->sta),
"%s: Dropped data frame as no usable bitrate found while "
"scanning and associated. Target station: "
@@ -804,9 +800,6 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
if (ieee80211_hdrlen(hdr->frame_control) < 24)
return TX_CONTINUE;
- if (ieee80211_is_qos_nullfunc(hdr->frame_control))
- return TX_CONTINUE;
-
/*
* Anything but QoS data that has a sequence number field
* (is long enough) gets a sequence number from the global
@@ -1054,7 +1047,6 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len,
NULL);
- u16 txflags;
info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
tx->flags &= ~IEEE80211_TX_FRAGMENTED;
@@ -1103,13 +1095,6 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
tx->flags |= IEEE80211_TX_FRAGMENTED;
break;
- case IEEE80211_RADIOTAP_TX_FLAGS:
- txflags = le16_to_cpu(get_unaligned((__le16*)
- iterator.this_arg));
- if (txflags & IEEE80211_RADIOTAP_F_TX_NOACK)
- info->flags |= IEEE80211_TX_CTL_NO_ACK;
- break;
-
/*
* Please update the file
* Documentation/networking/mac80211-injection.txt
@@ -1247,7 +1232,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
tx->sta = sta_info_get(sdata, hdr->addr1);
if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
- !ieee80211_is_qos_nullfunc(hdr->frame_control) &&
(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) &&
!(local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)) {
struct tid_ampdu_tx *tid_tx;
@@ -1274,11 +1258,8 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
tx->flags |= IEEE80211_TX_UNICAST;
if (unlikely(local->wifi_wme_noack_test))
info->flags |= IEEE80211_TX_CTL_NO_ACK;
- /*
- * Flags are initialized to 0. Hence, no need to
- * explicitly unset IEEE80211_TX_CTL_NO_ACK since
- * it might already be set for injected frames.
- */
+ else
+ info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
}
if (tx->flags & IEEE80211_TX_FRAGMENTED) {
@@ -1292,7 +1273,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
if (!tx->sta)
info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
- else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT))
+ else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT))
info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -1534,7 +1515,8 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
return 0;
}
-void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
+static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb)
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -1742,9 +1724,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
int encaps_len, skip_header_bytes;
int nh_pos, h_pos;
struct sta_info *sta = NULL;
- bool wme_sta = false, authorized = false, tdls_auth = false;
+ u32 sta_flags = 0;
struct sk_buff *tmp_skb;
- bool tdls_direct = false;
if (unlikely(skb->len < ETH_HLEN)) {
ret = NETDEV_TX_OK;
@@ -1768,8 +1749,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
memcpy(hdr.addr3, skb->data, ETH_ALEN);
memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
hdrlen = 30;
- authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
- wme_sta = test_sta_flag(sta, WLAN_STA_WME);
+ sta_flags = get_sta_flags(sta);
}
rcu_read_unlock();
if (sta)
@@ -1857,50 +1837,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
break;
#endif
case NL80211_IFTYPE_STATION:
- if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
- bool tdls_peer = false;
-
- rcu_read_lock();
- sta = sta_info_get(sdata, skb->data);
- if (sta) {
- authorized = test_sta_flag(sta,
- WLAN_STA_AUTHORIZED);
- wme_sta = test_sta_flag(sta, WLAN_STA_WME);
- tdls_peer = test_sta_flag(sta,
- WLAN_STA_TDLS_PEER);
- tdls_auth = test_sta_flag(sta,
- WLAN_STA_TDLS_PEER_AUTH);
- }
- rcu_read_unlock();
-
- /*
- * If the TDLS link is enabled, send everything
- * directly. Otherwise, allow TDLS setup frames
- * to be transmitted indirectly.
- */
- tdls_direct = tdls_peer && (tdls_auth ||
- !(ethertype == ETH_P_TDLS && skb->len > 14 &&
- skb->data[14] == WLAN_TDLS_SNAP_RFTYPE));
- }
-
- if (tdls_direct) {
- /* link during setup - throw out frames to peer */
- if (!tdls_auth) {
- ret = NETDEV_TX_OK;
- goto fail;
- }
-
- /* DA SA BSSID */
- memcpy(hdr.addr1, skb->data, ETH_ALEN);
- memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
- memcpy(hdr.addr3, sdata->u.mgd.bssid, ETH_ALEN);
- hdrlen = 24;
- } else if (sdata->u.mgd.use_4addr &&
- cpu_to_be16(ethertype) != sdata->control_port_protocol) {
- fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
- IEEE80211_FCTL_TODS);
+ memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN);
+ if (sdata->u.mgd.use_4addr &&
+ cpu_to_be16(ethertype) != sdata->control_port_protocol) {
+ fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
/* RA TA DA SA */
- memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN);
memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
memcpy(hdr.addr3, skb->data, ETH_ALEN);
memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
@@ -1908,7 +1849,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
} else {
fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
/* BSSID SA DA */
- memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN);
memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
memcpy(hdr.addr3, skb->data, ETH_ALEN);
hdrlen = 24;
@@ -1934,19 +1874,17 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
if (!is_multicast_ether_addr(hdr.addr1)) {
rcu_read_lock();
sta = sta_info_get(sdata, hdr.addr1);
- if (sta) {
- authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
- wme_sta = test_sta_flag(sta, WLAN_STA_WME);
- }
+ if (sta)
+ sta_flags = get_sta_flags(sta);
rcu_read_unlock();
}
/* For mesh, the use of the QoS header is mandatory */
if (ieee80211_vif_is_mesh(&sdata->vif))
- wme_sta = true;
+ sta_flags |= WLAN_STA_WME;
/* receiver and we are QoS enabled, use a QoS type frame */
- if (wme_sta && local->hw.queues >= 4) {
+ if ((sta_flags & WLAN_STA_WME) && local->hw.queues >= 4) {
fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
hdrlen += 2;
}
@@ -1956,7 +1894,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
* EAPOL frames from the local station.
*/
if (!ieee80211_vif_is_mesh(&sdata->vif) &&
- unlikely(!is_multicast_ether_addr(hdr.addr1) && !authorized &&
+ unlikely(!is_multicast_ether_addr(hdr.addr1) &&
+ !(sta_flags & WLAN_STA_AUTHORIZED) &&
!(cpu_to_be16(ethertype) == sdata->control_port_protocol &&
compare_ether_addr(sdata->vif.addr,
skb->data + ETH_ALEN) == 0))) {
@@ -2368,9 +2307,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
*pos++ = WLAN_EID_SSID;
*pos++ = 0x0;
- if (ieee80211_add_srates_ie(&sdata->vif, skb) ||
+ if (mesh_add_srates_ie(skb, sdata) ||
mesh_add_ds_params_ie(skb, sdata) ||
- ieee80211_add_ext_srates_ie(&sdata->vif, skb) ||
+ mesh_add_ext_srates_ie(skb, sdata) ||
mesh_add_rsn_ie(skb, sdata) ||
mesh_add_meshid_ie(skb, sdata) ||
mesh_add_meshconf_ie(skb, sdata) ||
diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c
index 7439d26bf5f9..4b1466d5b6a1 100644
--- a/trunk/net/mac80211/util.c
+++ b/trunk/net/mac80211/util.c
@@ -367,14 +367,14 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}
-void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
- struct sk_buff_head *skbs,
- void (*fn)(void *data), void *data)
+int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
+ struct sk_buff_head *skbs,
+ void (*fn)(void *data), void *data)
{
struct ieee80211_hw *hw = &local->hw;
struct sk_buff *skb;
unsigned long flags;
- int queue, i;
+ int queue, ret = 0, i;
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
for (i = 0; i < hw->queues; i++)
@@ -389,6 +389,7 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
continue;
}
+ ret++;
queue = skb_get_queue_mapping(skb);
__skb_queue_tail(&local->pending[queue], skb);
}
@@ -400,12 +401,14 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
__ieee80211_wake_queue(hw, i,
IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+
+ return ret;
}
-void ieee80211_add_pending_skbs(struct ieee80211_local *local,
- struct sk_buff_head *skbs)
+int ieee80211_add_pending_skbs(struct ieee80211_local *local,
+ struct sk_buff_head *skbs)
{
- ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL);
+ return ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL);
}
void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
@@ -629,8 +632,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
qparam.uapsd = false;
- sdata->tx_conf[queue] = qparam;
- drv_conf_tx(local, sdata, queue, &qparam);
+ local->tx_conf[queue] = qparam;
+ drv_conf_tx(local, queue, &qparam);
}
/* after reinitialize QoS TX queues setting to default,
@@ -896,18 +899,14 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
const u8 *ssid, size_t ssid_len,
const u8 *ie, size_t ie_len,
- u32 ratemask, bool directed, bool no_cck)
+ u32 ratemask, bool directed)
{
struct sk_buff *skb;
skb = ieee80211_build_probe_req(sdata, dst, ratemask, ssid, ssid_len,
ie, ie_len, directed);
- if (skb) {
- if (no_cck)
- IEEE80211_SKB_CB(skb)->flags |=
- IEEE80211_TX_CTL_NO_CCK_RATE;
+ if (skb)
ieee80211_tx_skb(sdata, skb);
- }
}
u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
@@ -1041,15 +1040,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
mutex_unlock(&local->sta_mtx);
/* reconfigure tx conf */
- list_for_each_entry(sdata, &local->interfaces, list) {
- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
- sdata->vif.type == NL80211_IFTYPE_MONITOR ||
- !ieee80211_sdata_running(sdata))
- continue;
-
- for (i = 0; i < hw->queues; i++)
- drv_conf_tx(local, sdata, i, &sdata->tx_conf[i]);
- }
+ for (i = 0; i < hw->queues; i++)
+ drv_conf_tx(local, i, &local->tx_conf[i]);
/* reconfigure hardware */
ieee80211_hw_config(local, ~0);
@@ -1122,7 +1114,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
list_for_each_entry(sta, &local->sta_list, list) {
ieee80211_sta_tear_down_BA_sessions(sta, true);
- clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
+ clear_sta_flags(sta, WLAN_STA_BLOCK_BA);
}
mutex_unlock(&local->sta_mtx);
@@ -1361,60 +1353,3 @@ void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif)
_ieee80211_enable_rssi_reports(sdata, 0, 0);
}
EXPORT_SYMBOL(ieee80211_disable_rssi_reports);
-
-int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
-{
- struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
- struct ieee80211_local *local = sdata->local;
- struct ieee80211_supported_band *sband;
- int rate;
- u8 i, rates, *pos;
-
- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
- rates = sband->n_bitrates;
- if (rates > 8)
- rates = 8;
-
- if (skb_tailroom(skb) < rates + 2)
- return -ENOMEM;
-
- pos = skb_put(skb, rates + 2);
- *pos++ = WLAN_EID_SUPP_RATES;
- *pos++ = rates;
- for (i = 0; i < rates; i++) {
- rate = sband->bitrates[i].bitrate;
- *pos++ = (u8) (rate / 5);
- }
-
- return 0;
-}
-
-int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
-{
- struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
- struct ieee80211_local *local = sdata->local;
- struct ieee80211_supported_band *sband;
- int rate;
- u8 i, exrates, *pos;
-
- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
- exrates = sband->n_bitrates;
- if (exrates > 8)
- exrates -= 8;
- else
- exrates = 0;
-
- if (skb_tailroom(skb) < exrates + 2)
- return -ENOMEM;
-
- if (exrates) {
- pos = skb_put(skb, exrates + 2);
- *pos++ = WLAN_EID_EXT_SUPP_RATES;
- *pos++ = exrates;
- for (i = 8; i < sband->n_bitrates; i++) {
- rate = sband->bitrates[i].bitrate;
- *pos++ = (u8) (rate / 5);
- }
- }
- return 0;
-}
diff --git a/trunk/net/mac80211/wme.c b/trunk/net/mac80211/wme.c
index fd52e695c071..971004c9b04f 100644
--- a/trunk/net/mac80211/wme.c
+++ b/trunk/net/mac80211/wme.c
@@ -72,7 +72,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
case NL80211_IFTYPE_AP_VLAN:
sta = rcu_dereference(sdata->u.vlan.sta);
if (sta) {
- qos = test_sta_flag(sta, WLAN_STA_WME);
+ qos = get_sta_flags(sta) & WLAN_STA_WME;
break;
}
case NL80211_IFTYPE_AP:
@@ -99,7 +99,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
if (!sta && ra && !is_multicast_ether_addr(ra)) {
sta = sta_info_get(sdata, ra);
if (sta)
- qos = test_sta_flag(sta, WLAN_STA_WME);
+ qos = get_sta_flags(sta) & WLAN_STA_WME;
}
rcu_read_unlock();
diff --git a/trunk/net/mac80211/work.c b/trunk/net/mac80211/work.c
index af374fab1a12..bac34394c05e 100644
--- a/trunk/net/mac80211/work.c
+++ b/trunk/net/mac80211/work.c
@@ -458,7 +458,7 @@ ieee80211_direct_probe(struct ieee80211_work *wk)
*/
ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid,
wk->probe_auth.ssid_len, NULL, 0,
- (u32) -1, true, false);
+ (u32) -1, true);
wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
run_again(local, wk->timeout);
diff --git a/trunk/net/nfc/nci/core.c b/trunk/net/nfc/nci/core.c
index 4047e29acb3b..895e5fdf464a 100644
--- a/trunk/net/nfc/nci/core.c
+++ b/trunk/net/nfc/nci/core.c
@@ -135,10 +135,8 @@ static void nci_init_req(struct nci_dev *ndev, unsigned long opt)
static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt)
{
- struct nci_core_conn_create_cmd conn_cmd;
struct nci_rf_disc_map_cmd cmd;
- struct disc_map_config *cfg = cmd.mapping_configs;
- __u8 *num = &cmd.num_mapping_configs;
+ struct nci_core_conn_create_cmd conn_cmd;
int i;
/* create static rf connection */
@@ -147,30 +145,36 @@ static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt)
nci_send_cmd(ndev, NCI_OP_CORE_CONN_CREATE_CMD, 2, &conn_cmd);
/* set rf mapping configurations */
- *num = 0;
+ cmd.num_mapping_configs = 0;
/* by default mapping is set to NCI_RF_INTERFACE_FRAME */
for (i = 0; i < ndev->num_supported_rf_interfaces; i++) {
if (ndev->supported_rf_interfaces[i] ==
NCI_RF_INTERFACE_ISO_DEP) {
- cfg[*num].rf_protocol = NCI_RF_PROTOCOL_ISO_DEP;
- cfg[*num].mode = NCI_DISC_MAP_MODE_BOTH;
- cfg[*num].rf_interface_type = NCI_RF_INTERFACE_ISO_DEP;
- (*num)++;
+ cmd.mapping_configs[cmd.num_mapping_configs]
+ .rf_protocol = NCI_RF_PROTOCOL_ISO_DEP;
+ cmd.mapping_configs[cmd.num_mapping_configs]
+ .mode = NCI_DISC_MAP_MODE_BOTH;
+ cmd.mapping_configs[cmd.num_mapping_configs]
+ .rf_interface_type = NCI_RF_INTERFACE_ISO_DEP;
+ cmd.num_mapping_configs++;
} else if (ndev->supported_rf_interfaces[i] ==
NCI_RF_INTERFACE_NFC_DEP) {
- cfg[*num].rf_protocol = NCI_RF_PROTOCOL_NFC_DEP;
- cfg[*num].mode = NCI_DISC_MAP_MODE_BOTH;
- cfg[*num].rf_interface_type = NCI_RF_INTERFACE_NFC_DEP;
- (*num)++;
+ cmd.mapping_configs[cmd.num_mapping_configs]
+ .rf_protocol = NCI_RF_PROTOCOL_NFC_DEP;
+ cmd.mapping_configs[cmd.num_mapping_configs]
+ .mode = NCI_DISC_MAP_MODE_BOTH;
+ cmd.mapping_configs[cmd.num_mapping_configs]
+ .rf_interface_type = NCI_RF_INTERFACE_NFC_DEP;
+ cmd.num_mapping_configs++;
}
- if (*num == NCI_MAX_NUM_MAPPING_CONFIGS)
+ if (cmd.num_mapping_configs == NCI_MAX_NUM_MAPPING_CONFIGS)
break;
}
nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_MAP_CMD,
- (1 + ((*num)*sizeof(struct disc_map_config))),
+ (1 + (cmd.num_mapping_configs*sizeof(struct disc_map_config))),
&cmd);
}
@@ -361,13 +365,8 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols)
return -EBUSY;
}
- if (ndev->target_active_prot) {
- nfc_err("there is an active target");
- return -EBUSY;
- }
-
if (test_bit(NCI_POLL_ACTIVE, &ndev->flags)) {
- nfc_dbg("target is active, implicitly deactivate...");
+ nfc_dbg("target already active, first deactivate...");
rc = nci_request(ndev, nci_rf_deactivate_req, 0,
msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
@@ -453,7 +452,6 @@ static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx,
void *cb_context)
{
struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
- int rc;
nfc_dbg("entry, target_idx %d, len %d", target_idx, skb->len);
@@ -462,18 +460,11 @@ static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx,
return -EINVAL;
}
- if (test_and_set_bit(NCI_DATA_EXCHANGE, &ndev->flags))
- return -EBUSY;
-
/* store cb and context to be used on receiving data */
ndev->data_exchange_cb = cb;
ndev->data_exchange_cb_context = cb_context;
- rc = nci_send_data(ndev, ndev->conn_id, skb);
- if (rc)
- clear_bit(NCI_DATA_EXCHANGE, &ndev->flags);
-
- return rc;
+ return nci_send_data(ndev, ndev->conn_id, skb);
}
static struct nfc_ops nci_nfc_ops = {
@@ -499,19 +490,19 @@ struct nci_dev *nci_allocate_device(struct nci_ops *ops,
int tx_headroom,
int tx_tailroom)
{
- struct nci_dev *ndev;
+ struct nci_dev *ndev = NULL;
nfc_dbg("entry, supported_protocols 0x%x", supported_protocols);
if (!ops->open || !ops->close || !ops->send)
- return NULL;
+ goto exit;
if (!supported_protocols)
- return NULL;
+ goto exit;
ndev = kzalloc(sizeof(struct nci_dev), GFP_KERNEL);
if (!ndev)
- return NULL;
+ goto exit;
ndev->ops = ops;
ndev->tx_headroom = tx_headroom;
@@ -526,11 +517,13 @@ struct nci_dev *nci_allocate_device(struct nci_ops *ops,
nfc_set_drvdata(ndev->nfc_dev, ndev);
- return ndev;
+ goto exit;
free_exit:
kfree(ndev);
- return NULL;
+
+exit:
+ return ndev;
}
EXPORT_SYMBOL(nci_allocate_device);
diff --git a/trunk/net/nfc/nci/data.c b/trunk/net/nfc/nci/data.c
index e5ed90fc1a9c..141790ada4aa 100644
--- a/trunk/net/nfc/nci/data.c
+++ b/trunk/net/nfc/nci/data.c
@@ -54,8 +54,6 @@ void nci_data_exchange_complete(struct nci_dev *ndev,
/* no waiting callback, free skb */
kfree_skb(skb);
}
-
- clear_bit(NCI_DATA_EXCHANGE, &ndev->flags);
}
/* ----------------- NCI TX Data ----------------- */
diff --git a/trunk/net/nfc/nci/ntf.c b/trunk/net/nfc/nci/ntf.c
index 96633f5cda4f..8dd75352ab6c 100644
--- a/trunk/net/nfc/nci/ntf.c
+++ b/trunk/net/nfc/nci/ntf.c
@@ -215,7 +215,7 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
}
/* complete the data exchange transaction, if exists */
- if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
+ if (ndev->data_exchange_cb)
nci_data_exchange_complete(ndev, NULL, -EIO);
}
diff --git a/trunk/net/rfkill/rfkill-gpio.c b/trunk/net/rfkill/rfkill-gpio.c
index 128677d69056..256c5ddd2d72 100644
--- a/trunk/net/rfkill/rfkill-gpio.c
+++ b/trunk/net/rfkill/rfkill-gpio.c
@@ -101,14 +101,6 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
if (!rfkill)
return -ENOMEM;
- if (pdata->gpio_runtime_setup) {
- ret = pdata->gpio_runtime_setup(pdev);
- if (ret) {
- pr_warn("%s: can't set up gpio\n", __func__);
- return ret;
- }
- }
-
rfkill->pdata = pdata;
len = strlen(pdata->name);
@@ -190,10 +182,7 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
static int rfkill_gpio_remove(struct platform_device *pdev)
{
struct rfkill_gpio_data *rfkill = platform_get_drvdata(pdev);
- struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data;
- if (pdata->gpio_runtime_close)
- pdata->gpio_runtime_close(pdev);
rfkill_unregister(rfkill->rfkill_dev);
rfkill_destroy(rfkill->rfkill_dev);
if (gpio_is_valid(rfkill->pdata->shutdown_gpio))
diff --git a/trunk/net/wireless/core.h b/trunk/net/wireless/core.h
index b9ec3061ed72..796a4bdf8b0d 100644
--- a/trunk/net/wireless/core.h
+++ b/trunk/net/wireless/core.h
@@ -375,8 +375,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
struct ieee80211_channel *chan, bool offchan,
enum nl80211_channel_type channel_type,
bool channel_type_valid, unsigned int wait,
- const u8 *buf, size_t len, bool no_cck,
- u64 *cookie);
+ const u8 *buf, size_t len, u64 *cookie);
/* SME */
int __cfg80211_connect(struct cfg80211_registered_device *rdev,
@@ -407,7 +406,6 @@ void cfg80211_sme_failed_assoc(struct wireless_dev *wdev);
bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev);
/* internal helpers */
-bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher);
int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
struct key_params *params, int key_idx,
bool pairwise, const u8 *mac_addr);
diff --git a/trunk/net/wireless/mlme.c b/trunk/net/wireless/mlme.c
index 21fc9702f81c..61adea540e02 100644
--- a/trunk/net/wireless/mlme.c
+++ b/trunk/net/wireless/mlme.c
@@ -900,8 +900,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
struct ieee80211_channel *chan, bool offchan,
enum nl80211_channel_type channel_type,
bool channel_type_valid, unsigned int wait,
- const u8 *buf, size_t len, bool no_cck,
- u64 *cookie)
+ const u8 *buf, size_t len, u64 *cookie)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
const struct ieee80211_mgmt *mgmt;
@@ -992,7 +991,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
/* Transmit the Action frame as requested by user space */
return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan,
channel_type, channel_type_valid,
- wait, buf, len, no_cck, cookie);
+ wait, buf, len, cookie);
}
bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c
index edf655aeea00..3c6427abdf34 100644
--- a/trunk/net/wireless/nl80211.c
+++ b/trunk/net/wireless/nl80211.c
@@ -191,12 +191,6 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
.len = IEEE80211_MAX_DATA_LEN },
[NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
[NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
- [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
- [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
- [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
- [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
- [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
- [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
};
/* policy for the key attributes */
@@ -737,12 +731,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH);
if (dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD)
NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_AP_UAPSD);
+
if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)
NLA_PUT_FLAG(msg, NL80211_ATTR_ROAM_SUPPORT);
- if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS)
- NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_SUPPORT);
- if (dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)
- NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP);
NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
sizeof(u32) * dev->wiphy.n_cipher_suites,
@@ -885,10 +876,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
}
CMD(set_channel, SET_CHANNEL);
CMD(set_wds_peer, SET_WDS_PEER);
- if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
- CMD(tdls_mgmt, TDLS_MGMT);
- CMD(tdls_oper, TDLS_OPER);
- }
if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
CMD(sched_scan_start, START_SCHED_SCAN);
@@ -1248,11 +1235,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
goto bad_res;
}
- if (!netdev) {
- result = -EINVAL;
- goto bad_res;
- }
-
nla_for_each_nested(nl_txq_params,
info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
rem_txq_params) {
@@ -1265,7 +1247,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
goto bad_res;
result = rdev->ops->set_txq_params(&rdev->wiphy,
- netdev,
&txq_params);
if (result)
goto bad_res;
@@ -2530,25 +2511,18 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
break;
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION:
- /* disallow things sta doesn't support */
+ /* disallow everything but AUTHORIZED flag */
if (params.plink_action)
err = -EINVAL;
if (params.vlan)
err = -EINVAL;
- if (params.supported_rates &&
- !(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
+ if (params.supported_rates)
err = -EINVAL;
if (params.ht_capa)
err = -EINVAL;
if (params.listen_interval >= 0)
err = -EINVAL;
- if (params.sta_flags_mask &
- ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
- BIT(NL80211_STA_FLAG_TDLS_PEER)))
- err = -EINVAL;
- /* can't change the TDLS bit */
- if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
- (params.sta_flags_mask & BIT(NL80211_STA_FLAG_TDLS_PEER)))
+ if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
err = -EINVAL;
break;
case NL80211_IFTYPE_MESH_POINT:
@@ -2639,7 +2613,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
/* parse WME attributes if sta is WME capable */
if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
- (params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)) &&
+ (params.sta_flags_set & NL80211_STA_FLAG_WME) &&
info->attrs[NL80211_ATTR_STA_WME]) {
struct nlattr *tb[NL80211_STA_WME_MAX + 1];
struct nlattr *nla;
@@ -2662,25 +2636,12 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
if (params.max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
return -EINVAL;
-
- params.sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
}
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
- dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO &&
- dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION)
- return -EINVAL;
-
- /*
- * Only managed stations can add TDLS peers, and only when the
- * wiphy supports external TDLS setup.
- */
- if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION &&
- !((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
- (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
- (rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)))
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
return -EINVAL;
err = get_vlan(info, rdev, ¶ms.vlan);
@@ -3659,9 +3620,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
}
}
- request->no_cck =
- nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
-
request->dev = dev;
request->wiphy = &rdev->wiphy;
@@ -4168,6 +4126,22 @@ static bool nl80211_valid_wpa_versions(u32 wpa_versions)
NL80211_WPA_VERSION_2));
}
+static bool nl80211_valid_akm_suite(u32 akm)
+{
+ return akm == WLAN_AKM_SUITE_8021X ||
+ akm == WLAN_AKM_SUITE_PSK;
+}
+
+static bool nl80211_valid_cipher_suite(u32 cipher)
+{
+ return cipher == WLAN_CIPHER_SUITE_WEP40 ||
+ cipher == WLAN_CIPHER_SUITE_WEP104 ||
+ cipher == WLAN_CIPHER_SUITE_TKIP ||
+ cipher == WLAN_CIPHER_SUITE_CCMP ||
+ cipher == WLAN_CIPHER_SUITE_AES_CMAC;
+}
+
+
static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -4300,8 +4274,7 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
memcpy(settings->ciphers_pairwise, data, len);
for (i = 0; i < settings->n_ciphers_pairwise; i++)
- if (!cfg80211_supported_cipher_suite(
- &rdev->wiphy,
+ if (!nl80211_valid_cipher_suite(
settings->ciphers_pairwise[i]))
return -EINVAL;
}
@@ -4309,8 +4282,7 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
settings->cipher_group =
nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
- if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
- settings->cipher_group))
+ if (!nl80211_valid_cipher_suite(settings->cipher_group))
return -EINVAL;
}
@@ -4323,7 +4295,7 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
void *data;
- int len;
+ int len, i;
data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
@@ -4332,10 +4304,11 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
if (len % sizeof(u32))
return -EINVAL;
- if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
- return -EINVAL;
-
memcpy(settings->akm_suites, data, len);
+
+ for (i = 0; i < settings->n_ciphers_pairwise; i++)
+ if (!nl80211_valid_akm_suite(settings->akm_suites[i]))
+ return -EINVAL;
}
return 0;
@@ -4996,57 +4969,6 @@ static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
return rdev->ops->flush_pmksa(&rdev->wiphy, dev);
}
-static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
-{
- struct cfg80211_registered_device *rdev = info->user_ptr[0];
- struct net_device *dev = info->user_ptr[1];
- u8 action_code, dialog_token;
- u16 status_code;
- u8 *peer;
-
- if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
- !rdev->ops->tdls_mgmt)
- return -EOPNOTSUPP;
-
- if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
- !info->attrs[NL80211_ATTR_STATUS_CODE] ||
- !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
- !info->attrs[NL80211_ATTR_IE] ||
- !info->attrs[NL80211_ATTR_MAC])
- return -EINVAL;
-
- peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
- action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
- status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
- dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
-
- return rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
- dialog_token, status_code,
- nla_data(info->attrs[NL80211_ATTR_IE]),
- nla_len(info->attrs[NL80211_ATTR_IE]));
-}
-
-static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
-{
- struct cfg80211_registered_device *rdev = info->user_ptr[0];
- struct net_device *dev = info->user_ptr[1];
- enum nl80211_tdls_operation operation;
- u8 *peer;
-
- if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
- !rdev->ops->tdls_oper)
- return -EOPNOTSUPP;
-
- if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
- !info->attrs[NL80211_ATTR_MAC])
- return -EINVAL;
-
- operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
- peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
-
- return rdev->ops->tdls_oper(&rdev->wiphy, dev, peer, operation);
-}
-
static int nl80211_remain_on_channel(struct sk_buff *skb,
struct genl_info *info)
{
@@ -5267,7 +5189,6 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
struct sk_buff *msg;
unsigned int wait = 0;
bool offchan;
- bool no_cck;
if (!info->attrs[NL80211_ATTR_FRAME] ||
!info->attrs[NL80211_ATTR_WIPHY_FREQ])
@@ -5304,8 +5225,6 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
- no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
-
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
chan = rdev_freq_to_chan(rdev, freq, channel_type);
if (chan == NULL)
@@ -5326,7 +5245,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
channel_type_valid, wait,
nla_data(info->attrs[NL80211_ATTR_FRAME]),
nla_len(info->attrs[NL80211_ATTR_FRAME]),
- no_cck, &cookie);
+ &cookie);
if (err)
goto free_msg;
@@ -6362,22 +6281,6 @@ static struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
- {
- .cmd = NL80211_CMD_TDLS_MGMT,
- .doit = nl80211_tdls_mgmt,
- .policy = nl80211_policy,
- .flags = GENL_ADMIN_PERM,
- .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
- NL80211_FLAG_NEED_RTNL,
- },
- {
- .cmd = NL80211_CMD_TDLS_OPER,
- .doit = nl80211_tdls_oper,
- .policy = nl80211_policy,
- .flags = GENL_ADMIN_PERM,
- .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
- NL80211_FLAG_NEED_RTNL,
- },
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
diff --git a/trunk/net/wireless/util.c b/trunk/net/wireless/util.c
index 2f178f73943f..39dbf4ad7ca1 100644
--- a/trunk/net/wireless/util.c
+++ b/trunk/net/wireless/util.c
@@ -151,19 +151,12 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
set_mandatory_flags_band(wiphy->bands[band], band);
}
-bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher)
-{
- int i;
- for (i = 0; i < wiphy->n_cipher_suites; i++)
- if (cipher == wiphy->cipher_suites[i])
- return true;
- return false;
-}
-
int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
struct key_params *params, int key_idx,
bool pairwise, const u8 *mac_addr)
{
+ int i;
+
if (key_idx > 5)
return -EINVAL;
@@ -233,7 +226,10 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
}
}
- if (!cfg80211_supported_cipher_suite(&rdev->wiphy, params->cipher))
+ for (i = 0; i < rdev->wiphy.n_cipher_suites; i++)
+ if (params->cipher == rdev->wiphy.cipher_suites[i])
+ break;
+ if (i == rdev->wiphy.n_cipher_suites)
return -EINVAL;
return 0;
@@ -396,9 +392,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
}
break;
case cpu_to_le16(0):
- if (iftype != NL80211_IFTYPE_ADHOC &&
- iftype != NL80211_IFTYPE_STATION)
- return -1;
+ if (iftype != NL80211_IFTYPE_ADHOC)
+ return -1;
break;
}