summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2013-03-09 10:58:13 +0100
committerJiri Kosina <jkosina@suse.cz>2013-03-09 11:01:06 +0100
commit83a44ac8bf4a8e6cbbf0c00ff281a482778f708a (patch)
tree325be1e4d52372db888396549908f25c5370caee /drivers/net/wireless
parent4ba25d3f87fe3ed6634f61da2a6904e2dfd09192 (diff)
parentd381f45c890a3fb136afb0dc1cbe025e066cb981 (diff)
HID: Merge branch 'master' into for-3.10/hid-driver-transport-cleanups
Sync with Linus' tree. This is necessary to resolve build conflict caused by dcd9006b1b053c7b ("HID: logitech-dj: do not directly call hid_output_raw_report() during probe") which issues direct call to usbhid_submit_report(), but that is gone in this branch and hid_hw_request() has to be used instead. Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c18
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c4
-rw-r--r--drivers/net/wireless/b43/main.c3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.c16
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c104
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c19
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h4
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h9
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c75
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c6
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c23
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c9
-rw-r--r--drivers/net/wireless/ray_cs.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c8
-rw-r--r--drivers/net/wireless/zd1201.c7
19 files changed, 205 insertions, 119 deletions
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 5f845beeb18..050ca4a4850 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -27,7 +27,7 @@
#define WME_MAX_BA WME_BA_BMP_SIZE
#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
-#define ATH_RSSI_DUMMY_MARKER 0x127
+#define ATH_RSSI_DUMMY_MARKER 127
#define ATH_RSSI_LPF_LEN 10
#define RSSI_LPF_THRESHOLD -20
#define ATH_RSSI_EP_MULTIPLIER (1<<7)
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 96bfb18078f..d3b099d7898 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -22,6 +22,7 @@
#include <linux/firmware.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <linux/leds.h>
#include <linux/slab.h>
#include <net/mac80211.h>
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 3ad1fd05c5e..bd8251c1c74 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -1067,15 +1067,19 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
last_rssi = priv->rx.last_rssi;
- if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
- rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
- ATH_RSSI_EP_MULTIPLIER);
+ if (ieee80211_is_beacon(hdr->frame_control) &&
+ !is_zero_ether_addr(common->curbssid) &&
+ ether_addr_equal(hdr->addr3, common->curbssid)) {
+ s8 rssi = rxbuf->rxstatus.rs_rssi;
- if (rxbuf->rxstatus.rs_rssi < 0)
- rxbuf->rxstatus.rs_rssi = 0;
+ if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
+ rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER);
- if (ieee80211_is_beacon(fc))
- priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
+ if (rssi < 0)
+ rssi = 0;
+
+ priv->ah->stats.avgbrssi = rssi;
+ }
rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
rx_status->band = hw->conf.channel->band;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 2a2ae403e0e..07e25260c31 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1463,7 +1463,9 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
reset_type = ATH9K_RESET_POWER_ON;
else
reset_type = ATH9K_RESET_COLD;
- }
+ } else if (ah->chip_fullsleep || REG_READ(ah, AR_Q_TXE) ||
+ (REG_READ(ah, AR_CR) & AR_CR_RXE))
+ reset_type = ATH9K_RESET_COLD;
if (!ath9k_hw_set_reset_reg(ah, reset_type))
return false;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 806e34c1928..05682736e46 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4214,7 +4214,6 @@ redo:
mutex_unlock(&wl->mutex);
cancel_delayed_work_sync(&dev->periodic_work);
cancel_work_sync(&wl->tx_work);
- cancel_work_sync(&wl->firmware_load);
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (!dev || b43_status(dev) < B43_STAT_STARTED) {
@@ -5434,6 +5433,7 @@ static void b43_bcma_remove(struct bcma_device *core)
/* We must cancel any work here before unregistering from ieee80211,
* as the ieee80211 unreg will destroy the workqueue. */
cancel_work_sync(&wldev->restart_work);
+ cancel_work_sync(&wl->firmware_load);
B43_WARN_ON(!wl);
if (!wldev->fw.ucode.data)
@@ -5510,6 +5510,7 @@ static void b43_ssb_remove(struct ssb_device *sdev)
/* We must cancel any work here before unregistering from ieee80211,
* as the ieee80211 unreg will destroy the workqueue. */
cancel_work_sync(&wldev->restart_work);
+ cancel_work_sync(&wl->firmware_load);
B43_WARN_ON(!wl);
if (!wldev->fw.ucode.data)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index cecc3eff72e..2af9c0f0798 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -4615,8 +4615,10 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
switch (ifevent->action) {
case BRCMF_E_IF_ADD:
/* waiting process may have timed out */
- if (!cfg->vif_event.vif)
+ if (!cfg->vif_event.vif) {
+ mutex_unlock(&event->vif_event_lock);
return -EBADF;
+ }
ifp->vif = vif;
vif->ifp = ifp;
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 9a0f45ec9e0..10f01793d7a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -349,25 +349,23 @@ TRACE_EVENT(iwlwifi_dev_rx_data,
TRACE_EVENT(iwlwifi_dev_hcmd,
TP_PROTO(const struct device *dev,
struct iwl_host_cmd *cmd, u16 total_size,
- const void *hdr, size_t hdr_len),
- TP_ARGS(dev, cmd, total_size, hdr, hdr_len),
+ struct iwl_cmd_header *hdr),
+ TP_ARGS(dev, cmd, total_size, hdr),
TP_STRUCT__entry(
DEV_ENTRY
__dynamic_array(u8, hcmd, total_size)
__field(u32, flags)
),
TP_fast_assign(
- int i, offset = hdr_len;
+ int i, offset = sizeof(*hdr);
DEV_ASSIGN;
__entry->flags = cmd->flags;
- memcpy(__get_dynamic_array(hcmd), hdr, hdr_len);
+ memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr));
for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
if (!cmd->len[i])
continue;
- if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
- continue;
memcpy((u8 *)__get_dynamic_array(hcmd) + offset,
cmd->data[i], cmd->len[i]);
offset += cmd->len[i];
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
index 14fc8d39fc2..3392011a876 100644
--- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
@@ -136,12 +136,6 @@ struct iwl_calib_res_notif_phy_db {
u8 data[];
} __packed;
-#define IWL_PHY_DB_STATIC_PIC cpu_to_le32(0x21436587)
-static inline void iwl_phy_db_test_pic(__le32 pic)
-{
- WARN_ON(IWL_PHY_DB_STATIC_PIC != pic);
-}
-
struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans)
{
struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db),
@@ -260,11 +254,6 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt,
(size - CHANNEL_NUM_SIZE) / phy_db->channel_num;
}
- /* Test PIC */
- if (type != IWL_PHY_DB_CFG)
- iwl_phy_db_test_pic(*(((__le32 *)phy_db_notif->data) +
- (size / sizeof(__le32)) - 1));
-
IWL_DEBUG_INFO(phy_db->trans,
"%s(%d): [PHYDB]SET: Type %d , Size: %d\n",
__func__, __LINE__, type, size);
@@ -372,11 +361,6 @@ int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db,
*size = entry->size;
}
- /* Test PIC */
- if (type != IWL_PHY_DB_CFG)
- iwl_phy_db_test_pic(*(((__le32 *)*data) +
- (*size / sizeof(__le32)) - 1));
-
IWL_DEBUG_INFO(phy_db->trans,
"%s(%d): [PHYDB] GET: Type %d , Size: %d\n",
__func__, __LINE__, type, *size);
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index c64d864799c..994c8c263dc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -61,6 +61,7 @@
*
*****************************************************************************/
+#include <linux/etherdevice.h>
#include <net/cfg80211.h>
#include <net/ipv6.h>
#include "iwl-modparams.h"
@@ -192,6 +193,11 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
sizeof(wkc), &wkc);
data->error = ret != 0;
+ mvm->ptk_ivlen = key->iv_len;
+ mvm->ptk_icvlen = key->icv_len;
+ mvm->gtk_ivlen = key->iv_len;
+ mvm->gtk_icvlen = key->icv_len;
+
/* don't upload key again */
goto out_unlock;
}
@@ -304,9 +310,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
*/
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
key->hw_key_idx = 0;
+ mvm->ptk_ivlen = key->iv_len;
+ mvm->ptk_icvlen = key->icv_len;
} else {
data->gtk_key_idx++;
key->hw_key_idx = data->gtk_key_idx;
+ mvm->gtk_ivlen = key->iv_len;
+ mvm->gtk_icvlen = key->icv_len;
}
ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true);
@@ -649,6 +659,11 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
/* We reprogram keys and shouldn't allocate new key indices */
memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
+ mvm->ptk_ivlen = 0;
+ mvm->ptk_icvlen = 0;
+ mvm->ptk_ivlen = 0;
+ mvm->ptk_icvlen = 0;
+
/*
* The D3 firmware still hardcodes the AP station ID for the
* BSS we're associated with as 0. As a result, we have to move
@@ -783,7 +798,6 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
struct iwl_wowlan_status *status;
u32 reasons;
int ret, len;
- bool pkt8023 = false;
struct sk_buff *pkt = NULL;
iwl_trans_read_mem_bytes(mvm->trans, base,
@@ -824,7 +838,8 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
status = (void *)cmd.resp_pkt->data;
if (len - sizeof(struct iwl_cmd_header) !=
- sizeof(*status) + le32_to_cpu(status->wake_packet_bufsize)) {
+ sizeof(*status) +
+ ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) {
IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
goto out;
}
@@ -836,61 +851,96 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
goto report;
}
- if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) {
+ if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET)
wakeup.magic_pkt = true;
- pkt8023 = true;
- }
- if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) {
+ if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN)
wakeup.pattern_idx =
le16_to_cpu(status->pattern_number);
- pkt8023 = true;
- }
if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH))
wakeup.disconnect = true;
- if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) {
+ if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)
wakeup.gtk_rekey_failure = true;
- pkt8023 = true;
- }
- if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) {
+ if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
wakeup.rfkill_release = true;
- pkt8023 = true;
- }
- if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) {
+ if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST)
wakeup.eap_identity_req = true;
- pkt8023 = true;
- }
- if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) {
+ if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE)
wakeup.four_way_handshake = true;
- pkt8023 = true;
- }
if (status->wake_packet_bufsize) {
- u32 pktsize = le32_to_cpu(status->wake_packet_bufsize);
- u32 pktlen = le32_to_cpu(status->wake_packet_length);
+ int pktsize = le32_to_cpu(status->wake_packet_bufsize);
+ int pktlen = le32_to_cpu(status->wake_packet_length);
+ const u8 *pktdata = status->wake_packet;
+ struct ieee80211_hdr *hdr = (void *)pktdata;
+ int truncated = pktlen - pktsize;
+
+ /* this would be a firmware bug */
+ if (WARN_ON_ONCE(truncated < 0))
+ truncated = 0;
+
+ if (ieee80211_is_data(hdr->frame_control)) {
+ int hdrlen = ieee80211_hdrlen(hdr->frame_control);
+ int ivlen = 0, icvlen = 4; /* also FCS */
- if (pkt8023) {
pkt = alloc_skb(pktsize, GFP_KERNEL);
if (!pkt)
goto report;
- memcpy(skb_put(pkt, pktsize), status->wake_packet,
- pktsize);
+
+ memcpy(skb_put(pkt, hdrlen), pktdata, hdrlen);
+ pktdata += hdrlen;
+ pktsize -= hdrlen;
+
+ if (ieee80211_has_protected(hdr->frame_control)) {
+ if (is_multicast_ether_addr(hdr->addr1)) {
+ ivlen = mvm->gtk_ivlen;
+ icvlen += mvm->gtk_icvlen;
+ } else {
+ ivlen = mvm->ptk_ivlen;
+ icvlen += mvm->ptk_icvlen;
+ }
+ }
+
+ /* if truncated, FCS/ICV is (partially) gone */
+ if (truncated >= icvlen) {
+ icvlen = 0;
+ truncated -= icvlen;
+ } else {
+ icvlen -= truncated;
+ truncated = 0;
+ }
+
+ pktsize -= ivlen + icvlen;
+ pktdata += ivlen;
+
+ memcpy(skb_put(pkt, pktsize), pktdata, pktsize);
+
if (ieee80211_data_to_8023(pkt, vif->addr, vif->type))
goto report;
wakeup.packet = pkt->data;
wakeup.packet_present_len = pkt->len;
- wakeup.packet_len = pkt->len - (pktlen - pktsize);
+ wakeup.packet_len = pkt->len - truncated;
wakeup.packet_80211 = false;
} else {
+ int fcslen = 4;
+
+ if (truncated >= 4) {
+ truncated -= 4;
+ fcslen = 0;
+ } else {
+ fcslen -= truncated;
+ truncated = 0;
+ }
+ pktsize -= fcslen;
wakeup.packet = status->wake_packet;
wakeup.packet_present_len = pktsize;
- wakeup.packet_len = pktlen;
+ wakeup.packet_len = pktlen - truncated;
wakeup.packet_80211 = true;
}
}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index e8264e11b12..7e169b085af 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -557,11 +557,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
return ret;
}
-static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif)
{
- struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
u32 tfd_msk = 0, ac;
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
@@ -594,12 +592,21 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
*/
flush_work(&mvm->sta_drained_wk);
}
+}
+
+static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+ iwl_mvm_prepare_mac_removal(mvm, vif);
mutex_lock(&mvm->mutex);
/*
* For AP/GO interface, the tear down of the resources allocated to the
- * interface should be handled as part of the bss_info_changed flow.
+ * interface is be handled as part of the stop_ap flow.
*/
if (vif->type == NL80211_IFTYPE_AP) {
iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
@@ -763,6 +770,8 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ iwl_mvm_prepare_mac_removal(mvm, vif);
+
mutex_lock(&mvm->mutex);
mvmvif->ap_active = false;
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 4e339ccfa80..537711b1047 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -327,6 +327,10 @@ struct iwl_mvm {
struct led_classdev led;
struct ieee80211_vif *p2p_device_vif;
+
+#ifdef CONFIG_PM_SLEEP
+ int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
+#endif
};
/* Extract MVM priv from op_mode and _hw */
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index aa2a39a637d..3d62e805535 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -182,6 +182,15 @@ struct iwl_queue {
#define TFD_TX_CMD_SLOTS 256
#define TFD_CMD_SLOTS 32
+/*
+ * The FH will write back to the first TB only, so we need
+ * to copy some data into the buffer regardless of whether
+ * it should be mapped or not. This indicates how much to
+ * copy, even for HCMDs it must be big enough to fit the
+ * DRAM scratch from the TX cmd, at least 16 bytes.
+ */
+#define IWL_HCMD_MIN_COPY_SIZE 16
+
struct iwl_pcie_txq_entry {
struct iwl_device_cmd *cmd;
struct iwl_device_cmd *copy_cmd;
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 8e9e3212fe7..8b625a7f568 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1152,10 +1152,12 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
void *dup_buf = NULL;
dma_addr_t phys_addr;
int idx;
- u16 copy_size, cmd_size;
+ u16 copy_size, cmd_size, dma_size;
bool had_nocopy = false;
int i;
u32 cmd_pos;
+ const u8 *cmddata[IWL_MAX_CMD_TFDS];
+ u16 cmdlen[IWL_MAX_CMD_TFDS];
copy_size = sizeof(out_cmd->hdr);
cmd_size = sizeof(out_cmd->hdr);
@@ -1164,8 +1166,23 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1);
for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+ cmddata[i] = cmd->data[i];
+ cmdlen[i] = cmd->len[i];
+
if (!cmd->len[i])
continue;
+
+ /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
+ if (copy_size < IWL_HCMD_MIN_COPY_SIZE) {
+ int copy = IWL_HCMD_MIN_COPY_SIZE - copy_size;
+
+ if (copy > cmdlen[i])
+ copy = cmdlen[i];
+ cmdlen[i] -= copy;
+ cmddata[i] += copy;
+ copy_size += copy;
+ }
+
if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
had_nocopy = true;
if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) {
@@ -1185,7 +1202,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
goto free_dup_buf;
}
- dup_buf = kmemdup(cmd->data[i], cmd->len[i],
+ dup_buf = kmemdup(cmddata[i], cmdlen[i],
GFP_ATOMIC);
if (!dup_buf)
return -ENOMEM;
@@ -1195,7 +1212,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
idx = -EINVAL;
goto free_dup_buf;
}
- copy_size += cmd->len[i];
+ copy_size += cmdlen[i];
}
cmd_size += cmd->len[i];
}
@@ -1242,14 +1259,31 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
/* and copy the data that needs to be copied */
cmd_pos = offsetof(struct iwl_device_cmd, payload);
+ copy_size = sizeof(out_cmd->hdr);
for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
- if (!cmd->len[i])
+ int copy = 0;
+
+ if (!cmd->len)
continue;
- if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
- IWL_HCMD_DFL_DUP))
- break;
- memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]);
- cmd_pos += cmd->len[i];
+
+ /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
+ if (copy_size < IWL_HCMD_MIN_COPY_SIZE) {
+ copy = IWL_HCMD_MIN_COPY_SIZE - copy_size;
+
+ if (copy > cmd->len[i])
+ copy = cmd->len[i];
+ }
+
+ /* copy everything if not nocopy/dup */
+ if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
+ IWL_HCMD_DFL_DUP)))
+ copy = cmd->len[i];
+
+ if (copy) {
+ memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy);
+ cmd_pos += copy;
+ copy_size += copy;
+ }
}
WARN_ON_ONCE(txq->entries[idx].copy_cmd);
@@ -1275,7 +1309,14 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue);
- phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size,
+ /*
+ * If the entire command is smaller than IWL_HCMD_MIN_COPY_SIZE, we must
+ * still map at least that many bytes for the hardware to write back to.
+ * We have enough space, so that's not a problem.
+ */
+ dma_size = max_t(u16, copy_size, IWL_HCMD_MIN_COPY_SIZE);
+
+ phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, dma_size,
DMA_BIDIRECTIONAL);
if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
idx = -ENOMEM;
@@ -1283,14 +1324,15 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
}
dma_unmap_addr_set(out_meta, mapping, phys_addr);
- dma_unmap_len_set(out_meta, len, copy_size);
+ dma_unmap_len_set(out_meta, len, dma_size);
iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1);
+ /* map the remaining (adjusted) nocopy/dup fragments */
for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
- const void *data = cmd->data[i];
+ const void *data = cmddata[i];
- if (!cmd->len[i])
+ if (!cmdlen[i])
continue;
if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
IWL_HCMD_DFL_DUP)))
@@ -1298,7 +1340,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP)
data = dup_buf;
phys_addr = dma_map_single(trans->dev, (void *)data,
- cmd->len[i], DMA_BIDIRECTIONAL);
+ cmdlen[i], DMA_BIDIRECTIONAL);
if (dma_mapping_error(trans->dev, phys_addr)) {
iwl_pcie_tfd_unmap(trans, out_meta,
&txq->tfds[q->write_ptr],
@@ -1307,7 +1349,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
goto out;
}
- iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0);
+ iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0);
}
out_meta->flags = cmd->flags;
@@ -1317,8 +1359,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
txq->need_update = 1;
- trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size,
- &out_cmd->hdr, copy_size);
+ trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr);
/* start timer if queue currently empty */
if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout)
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 739309e70d8..45578335e42 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -825,6 +825,11 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card)
sdio_release_host(func);
+ /* Set fw_ready before queuing any commands so that
+ * lbs_thread won't block from sending them to firmware.
+ */
+ priv->fw_ready = 1;
+
/*
* FUNC_INIT is required for SD8688 WLAN/BT multiple functions
*/
@@ -839,7 +844,6 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card)
netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n");
}
- priv->fw_ready = 1;
wake_up(&card->pwron_waitq);
if (!card->started) {
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 4b54bcf382f..5c395e2e6a2 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -171,7 +171,7 @@ static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct mwifiex_adapter *adapter;
struct pcie_service_card *card;
- int hs_actived, i;
+ int hs_actived;
if (pdev) {
card = (struct pcie_service_card *) pci_get_drvdata(pdev);
@@ -191,9 +191,6 @@ static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
/* Indicate device suspended */
adapter->is_suspended = true;
- for (i = 0; i < adapter->priv_num; i++)
- netif_carrier_off(adapter->priv[i]->netdev);
-
return 0;
}
@@ -209,7 +206,6 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev)
{
struct mwifiex_adapter *adapter;
struct pcie_service_card *card;
- int i;
if (pdev) {
card = (struct pcie_service_card *) pci_get_drvdata(pdev);
@@ -231,10 +227,6 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev)
adapter->is_suspended = false;
- for (i = 0; i < adapter->priv_num; i++)
- if (adapter->priv[i]->media_connected)
- netif_carrier_on(adapter->priv[i]->netdev);
-
mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
MWIFIEX_ASYNC_CMD);
@@ -310,7 +302,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
i++;
usleep_range(10, 20);
/* 50ms max wait */
- if (i == 50000)
+ if (i == 5000)
break;
}
@@ -916,17 +908,8 @@ static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
{
struct pcie_service_card *card = adapter->card;
- const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
- u32 rdptr;
-
- /* Read the TX ring read pointer set by firmware */
- if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
- dev_err(adapter->dev,
- "Flush TXBD: failed to read reg->tx_rdptr\n");
- return -1;
- }
- if (!mwifiex_pcie_txbd_empty(card, rdptr)) {
+ if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
card->txbd_flush = 1;
/* write pointer already set at last send
* send dnld-rdy intr again, wait for completion.
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index e63f646a260..363ba31b58b 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -161,7 +161,6 @@ static int mwifiex_sdio_suspend(struct device *dev)
struct sdio_mmc_card *card;
struct mwifiex_adapter *adapter;
mmc_pm_flag_t pm_flag = 0;
- int i;
int ret = 0;
if (func) {
@@ -198,9 +197,6 @@ static int mwifiex_sdio_suspend(struct device *dev)
/* Indicate device suspended */
adapter->is_suspended = true;
- for (i = 0; i < adapter->priv_num; i++)
- netif_carrier_off(adapter->priv[i]->netdev);
-
return ret;
}
@@ -220,7 +216,6 @@ static int mwifiex_sdio_resume(struct device *dev)
struct sdio_mmc_card *card;
struct mwifiex_adapter *adapter;
mmc_pm_flag_t pm_flag = 0;
- int i;
if (func) {
pm_flag = sdio_get_host_pm_caps(func);
@@ -243,10 +238,6 @@ static int mwifiex_sdio_resume(struct device *dev)
adapter->is_suspended = false;
- for (i = 0; i < adapter->priv_num; i++)
- if (adapter->priv[i]->media_connected)
- netif_carrier_on(adapter->priv[i]->netdev);
-
/* Disable Host Sleep */
mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
MWIFIEX_ASYNC_CMD);
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index e7cf37f550d..3109c0db66e 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -2778,7 +2778,7 @@ static ssize_t int_proc_write(struct file *file, const char __user *buffer,
nr = nr * 10 + c;
p++;
} while (--len);
- *(int *)PDE(file->f_path.dentry->d_inode)->data = nr;
+ *(int *)PDE(file_inode(file))->data = nr;
return count;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 1031db66474..189744db65e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1236,8 +1236,10 @@ static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev)
*/
if_limit = &rt2x00dev->if_limits_ap;
if_limit->max = rt2x00dev->ops->max_ap_intf;
- if_limit->types = BIT(NL80211_IFTYPE_AP) |
- BIT(NL80211_IFTYPE_MESH_POINT);
+ if_limit->types = BIT(NL80211_IFTYPE_AP);
+#ifdef CONFIG_MAC80211_MESH
+ if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT);
+#endif
/*
* Build up AP interface combinations structure.
@@ -1309,7 +1311,9 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
rt2x00dev->hw->wiphy->interface_modes |=
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_AP) |
+#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
BIT(NL80211_IFTYPE_WDS);
rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 48273dd05b6..4941f201d6c 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -309,7 +309,6 @@ static void zd1201_usbrx(struct urb *urb)
if (data[urb->actual_length-1] == ZD1201_PACKET_RXDATA) {
int datalen = urb->actual_length-1;
unsigned short len, fc, seq;
- struct hlist_node *node;
len = ntohs(*(__be16 *)&data[datalen-2]);
if (len>datalen)
@@ -362,7 +361,7 @@ static void zd1201_usbrx(struct urb *urb)
hlist_add_head(&frag->fnode, &zd->fraglist);
goto resubmit;
}
- hlist_for_each_entry(frag, node, &zd->fraglist, fnode)
+ hlist_for_each_entry(frag, &zd->fraglist, fnode)
if (frag->seq == (seq&IEEE80211_SCTL_SEQ))
break;
if (!frag)
@@ -1831,14 +1830,14 @@ err_zd:
static void zd1201_disconnect(struct usb_interface *interface)
{
struct zd1201 *zd = usb_get_intfdata(interface);
- struct hlist_node *node, *node2;
+ struct hlist_node *node2;
struct zd1201_frag *frag;
if (!zd)
return;
usb_set_intfdata(interface, NULL);
- hlist_for_each_entry_safe(frag, node, node2, &zd->fraglist, fnode) {
+ hlist_for_each_entry_safe(frag, node2, &zd->fraglist, fnode) {
hlist_del_init(&frag->fnode);
kfree_skb(frag->skb);
kfree(frag);