aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-03-26 05:35:50 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-03-26 05:35:50 -0400
commitb510446b643572903535c3b1d3e63e9cfa4e94d9 (patch)
tree9948562b6e050f5722663d2436835787e3e22504 /drivers
parent8c6e83d6d3e522bba314225863ff323991d514f7 (diff)
parent64513ef449e3beaacb801d41467f47642683e35a (diff)
Merge remote-tracking branch 'wireless-next/master' into iwlwifi-next
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bcma/sprom.c1
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c8
-rw-r--r--drivers/net/wireless/ath/ar5523/ar5523.c2
-rw-r--r--drivers/net/wireless/ath/ath6kl/trace.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c2
-rw-r--r--drivers/net/wireless/b43/main.c7
-rw-r--r--drivers/net/wireless/b43/phy_lp.c12
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c2
-rw-r--r--drivers/net/wireless/iwlegacy/common.c3
-rw-r--r--drivers/net/wireless/iwlegacy/common.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c2
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c8
-rw-r--r--drivers/net/wireless/mwifiex/11ac.c19
-rw-r--r--drivers/net/wireless/mwifiex/11ac.h17
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c7
-rw-r--r--drivers/net/wireless/mwifiex/fw.h11
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h8
-rw-r--r--drivers/net/wireless/mwifiex/main.h6
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c4
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c2
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c55
-rw-r--r--drivers/net/wireless/p54/main.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c2
-rw-r--r--drivers/net/wireless/rtlwifi/core.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.c2
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c220
-rw-r--r--drivers/net/wireless/rtlwifi/usb.h5
-rw-r--r--drivers/net/wireless/ti/wl1251/sdio.c4
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c1
-rw-r--r--drivers/net/wireless/ti/wl12xx/wl12xx.h2
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c25
-rw-r--r--drivers/net/wireless/ti/wl18xx/reg.h29
-rw-r--r--drivers/net/wireless/ti/wl18xx/wl18xx.h4
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.c29
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.h16
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c32
-rw-r--r--drivers/net/wireless/ti/wlcore/debug.h33
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.c3
-rw-r--r--drivers/net/wireless/ti/wlcore/event.c9
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c200
-rw-r--r--drivers/net/wireless/ti/wlcore/ps.c4
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.c39
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h3
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h29
-rw-r--r--drivers/ssb/pci.c23
47 files changed, 672 insertions, 242 deletions
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index 4adf9ef9a113..8934298a638d 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -217,6 +217,7 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
217 } 217 }
218 218
219 SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0); 219 SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0);
220 SPEX(board_type, SSB_SPROM1_SPID, ~0, 0);
220 221
221 SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0, 222 SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0,
222 SSB_SPROM4_TXPID2G0_SHIFT); 223 SSB_SPROM4_TXPID2G0_SHIFT);
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index 9959d4cb23dc..1cb51839912d 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -83,8 +83,8 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
83}; 83};
84 84
85static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { 85static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
86 .helper = "sd8688_helper.bin", 86 .helper = "mrvl/sd8688_helper.bin",
87 .firmware = "sd8688.bin", 87 .firmware = "mrvl/sd8688.bin",
88 .reg = &btmrvl_reg_8688, 88 .reg = &btmrvl_reg_8688,
89 .sd_blksz_fw_dl = 64, 89 .sd_blksz_fw_dl = 64,
90}; 90};
@@ -1185,7 +1185,7 @@ MODULE_AUTHOR("Marvell International Ltd.");
1185MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION); 1185MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION);
1186MODULE_VERSION(VERSION); 1186MODULE_VERSION(VERSION);
1187MODULE_LICENSE("GPL v2"); 1187MODULE_LICENSE("GPL v2");
1188MODULE_FIRMWARE("sd8688_helper.bin"); 1188MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
1189MODULE_FIRMWARE("sd8688.bin"); 1189MODULE_FIRMWARE("mrvl/sd8688.bin");
1190MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); 1190MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
1191MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); 1191MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c
index 7157f7d311c5..afd1e36d308f 100644
--- a/drivers/net/wireless/ath/ar5523/ar5523.c
+++ b/drivers/net/wireless/ath/ar5523/ar5523.c
@@ -1091,7 +1091,7 @@ static int ar5523_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1091 return ret; 1091 return ret;
1092} 1092}
1093 1093
1094static void ar5523_flush(struct ieee80211_hw *hw, bool drop) 1094static void ar5523_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1095{ 1095{
1096 struct ar5523 *ar = hw->priv; 1096 struct ar5523 *ar = hw->priv;
1097 1097
diff --git a/drivers/net/wireless/ath/ath6kl/trace.h b/drivers/net/wireless/ath/ath6kl/trace.h
index 6af6fa038312..1a1ea7881b4d 100644
--- a/drivers/net/wireless/ath/ath6kl/trace.h
+++ b/drivers/net/wireless/ath/ath6kl/trace.h
@@ -53,7 +53,7 @@ TRACE_EVENT(ath6kl_wmi_cmd,
53 ), 53 ),
54 54
55 TP_printk( 55 TP_printk(
56 "id %d len %d", 56 "id %d len %zd",
57 __entry->id, __entry->buf_len 57 __entry->id, __entry->buf_len
58 ) 58 )
59); 59);
@@ -76,7 +76,7 @@ TRACE_EVENT(ath6kl_wmi_event,
76 ), 76 ),
77 77
78 TP_printk( 78 TP_printk(
79 "id %d len %d", 79 "id %d len %zd",
80 __entry->id, __entry->buf_len 80 __entry->id, __entry->buf_len
81 ) 81 )
82); 82);
@@ -108,7 +108,7 @@ TRACE_EVENT(ath6kl_sdio,
108 ), 108 ),
109 109
110 TP_printk( 110 TP_printk(
111 "%s addr 0x%x flags 0x%x len %d\n", 111 "%s addr 0x%x flags 0x%x len %zd\n",
112 __entry->tx ? "tx" : "rx", 112 __entry->tx ? "tx" : "rx",
113 __entry->addr, 113 __entry->addr,
114 __entry->flags, 114 __entry->flags,
@@ -161,7 +161,7 @@ TRACE_EVENT(ath6kl_sdio_scat,
161 ), 161 ),
162 162
163 TP_printk( 163 TP_printk(
164 "%s addr 0x%x flags 0x%x entries %d total_len %d\n", 164 "%s addr 0x%x flags 0x%x entries %d total_len %zd\n",
165 __entry->tx ? "tx" : "rx", 165 __entry->tx ? "tx" : "rx",
166 __entry->addr, 166 __entry->addr,
167 __entry->flags, 167 __entry->flags,
@@ -186,7 +186,7 @@ TRACE_EVENT(ath6kl_sdio_irq,
186 ), 186 ),
187 187
188 TP_printk( 188 TP_printk(
189 "irq len %d\n", __entry->buf_len 189 "irq len %zd\n", __entry->buf_len
190 ) 190 )
191); 191);
192 192
@@ -211,7 +211,7 @@ TRACE_EVENT(ath6kl_htc_rx,
211 ), 211 ),
212 212
213 TP_printk( 213 TP_printk(
214 "status %d endpoint %d len %d\n", 214 "status %d endpoint %d len %zd\n",
215 __entry->status, 215 __entry->status,
216 __entry->endpoint, 216 __entry->endpoint,
217 __entry->buf_len 217 __entry->buf_len
@@ -239,7 +239,7 @@ TRACE_EVENT(ath6kl_htc_tx,
239 ), 239 ),
240 240
241 TP_printk( 241 TP_printk(
242 "status %d endpoint %d len %d\n", 242 "status %d endpoint %d len %zd\n",
243 __entry->status, 243 __entry->status,
244 __entry->endpoint, 244 __entry->endpoint,
245 __entry->buf_len 245 __entry->buf_len
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 6e66f9c6782b..24650fd41694 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1745,7 +1745,7 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
1745 mutex_unlock(&sc->mutex); 1745 mutex_unlock(&sc->mutex);
1746} 1746}
1747 1747
1748static void ath9k_flush(struct ieee80211_hw *hw, bool drop) 1748static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1749{ 1749{
1750 struct ath_softc *sc = hw->priv; 1750 struct ath_softc *sc = hw->priv;
1751 struct ath_hw *ah = sc->sc_ah; 1751 struct ath_hw *ah = sc->sc_ah;
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index f293b3ff4756..08b193199946 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -1703,7 +1703,7 @@ found:
1703 return 0; 1703 return 0;
1704} 1704}
1705 1705
1706static void carl9170_op_flush(struct ieee80211_hw *hw, bool drop) 1706static void carl9170_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1707{ 1707{
1708 struct ar9170 *ar = hw->priv; 1708 struct ar9170 *ar = hw->priv;
1709 unsigned int vid; 1709 unsigned int vid;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index c4d0cc582555..ae4eeb3bfa54 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2780,9 +2780,7 @@ static int b43_gpio_init(struct b43_wldev *dev)
2780 switch (dev->dev->bus_type) { 2780 switch (dev->dev->bus_type) {
2781#ifdef CONFIG_B43_BCMA 2781#ifdef CONFIG_B43_BCMA
2782 case B43_BUS_BCMA: 2782 case B43_BUS_BCMA:
2783 bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, 2783 bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc, mask, set);
2784 (bcma_cc_read32(&dev->dev->bdev->bus->drv_cc,
2785 BCMA_CC_GPIOCTL) & ~mask) | set);
2786 break; 2784 break;
2787#endif 2785#endif
2788#ifdef CONFIG_B43_SSB 2786#ifdef CONFIG_B43_SSB
@@ -2807,8 +2805,7 @@ static void b43_gpio_cleanup(struct b43_wldev *dev)
2807 switch (dev->dev->bus_type) { 2805 switch (dev->dev->bus_type) {
2808#ifdef CONFIG_B43_BCMA 2806#ifdef CONFIG_B43_BCMA
2809 case B43_BUS_BCMA: 2807 case B43_BUS_BCMA:
2810 bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, 2808 bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc, ~0, 0);
2811 0);
2812 break; 2809 break;
2813#endif 2810#endif
2814#ifdef CONFIG_B43_SSB 2811#ifdef CONFIG_B43_SSB
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 3ae28561f7a4..5ed352ddae9e 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -104,14 +104,8 @@ static void lpphy_read_band_sprom(struct b43_wldev *dev)
104 maxpwr = sprom->maxpwr_bg; 104 maxpwr = sprom->maxpwr_bg;
105 lpphy->max_tx_pwr_med_band = maxpwr; 105 lpphy->max_tx_pwr_med_band = maxpwr;
106 cckpo = sprom->cck2gpo; 106 cckpo = sprom->cck2gpo;
107 /*
108 * We don't read SPROM's opo as specs say. On rev8 SPROMs
109 * opo == ofdm2gpo and we don't know any SSB with LP-PHY
110 * and SPROM rev below 8.
111 */
112 B43_WARN_ON(sprom->revision < 8);
113 ofdmpo = sprom->ofdm2gpo;
114 if (cckpo) { 107 if (cckpo) {
108 ofdmpo = sprom->ofdm2gpo;
115 for (i = 0; i < 4; i++) { 109 for (i = 0; i < 4; i++) {
116 lpphy->tx_max_rate[i] = 110 lpphy->tx_max_rate[i] =
117 maxpwr - (ofdmpo & 0xF) * 2; 111 maxpwr - (ofdmpo & 0xF) * 2;
@@ -124,11 +118,11 @@ static void lpphy_read_band_sprom(struct b43_wldev *dev)
124 ofdmpo >>= 4; 118 ofdmpo >>= 4;
125 } 119 }
126 } else { 120 } else {
127 ofdmpo &= 0xFF; 121 u8 opo = sprom->opo;
128 for (i = 0; i < 4; i++) 122 for (i = 0; i < 4; i++)
129 lpphy->tx_max_rate[i] = maxpwr; 123 lpphy->tx_max_rate[i] = maxpwr;
130 for (i = 4; i < 15; i++) 124 for (i = 4; i < 15; i++)
131 lpphy->tx_max_rate[i] = maxpwr - ofdmpo; 125 lpphy->tx_max_rate[i] = maxpwr - opo;
132 } 126 }
133 } else { /* 5GHz */ 127 } else { /* 5GHz */
134 lpphy->tx_isolation_low_band = sprom->tri5gl; 128 lpphy->tx_isolation_low_band = sprom->tri5gl;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index c70cf7b654cd..7cc30f8fed7d 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -724,7 +724,7 @@ static bool brcms_tx_flush_completed(struct brcms_info *wl)
724 return result; 724 return result;
725} 725}
726 726
727static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop) 727static void brcms_ops_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
728{ 728{
729 struct brcms_info *wl = hw->priv; 729 struct brcms_info *wl = hw->priv;
730 int ret; 730 int ret;
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index bc465da40476..1a518feb4b26 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -4704,8 +4704,7 @@ out:
4704} 4704}
4705EXPORT_SYMBOL(il_mac_change_interface); 4705EXPORT_SYMBOL(il_mac_change_interface);
4706 4706
4707void 4707void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
4708il_mac_flush(struct ieee80211_hw *hw, bool drop)
4709{ 4708{
4710 struct il_priv *il = hw->priv; 4709 struct il_priv *il = hw->priv;
4711 unsigned long timeout = jiffies + msecs_to_jiffies(500); 4710 unsigned long timeout = jiffies + msecs_to_jiffies(500);
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index 73bd3ef316c8..728aa1306ab8 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1720,7 +1720,7 @@ void il_mac_remove_interface(struct ieee80211_hw *hw,
1720 struct ieee80211_vif *vif); 1720 struct ieee80211_vif *vif);
1721int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1721int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1722 enum nl80211_iftype newtype, bool newp2p); 1722 enum nl80211_iftype newtype, bool newp2p);
1723void il_mac_flush(struct ieee80211_hw *hw, bool drop); 1723void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
1724int il_alloc_txq_mem(struct il_priv *il); 1724int il_alloc_txq_mem(struct il_priv *il);
1725void il_free_txq_mem(struct il_priv *il); 1725void il_free_txq_mem(struct il_priv *il);
1726 1726
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index c7cd2dffa5cd..a7294fa4d7e5 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1100,7 +1100,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
1100 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; 1100 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
1101} 1101}
1102 1102
1103static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) 1103static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1104{ 1104{
1105 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1105 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1106 1106
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 7490c4fc7177..0064d38276bf 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -964,6 +964,12 @@ static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw,
964 newtype, vif->addr); 964 newtype, vif->addr);
965 hwsim_check_magic(vif); 965 hwsim_check_magic(vif);
966 966
967 /*
968 * interface may change from non-AP to AP in
969 * which case this needs to be set up again
970 */
971 vif->cab_queue = 0;
972
967 return 0; 973 return 0;
968} 974}
969 975
@@ -1389,7 +1395,7 @@ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
1389 return 0; 1395 return 0;
1390} 1396}
1391 1397
1392static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop) 1398static void mac80211_hwsim_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1393{ 1399{
1394 /* Not implemented, queues only on kernel side */ 1400 /* Not implemented, queues only on kernel side */
1395} 1401}
diff --git a/drivers/net/wireless/mwifiex/11ac.c b/drivers/net/wireless/mwifiex/11ac.c
index cf43b3c29250..de0a63469cb1 100644
--- a/drivers/net/wireless/mwifiex/11ac.c
+++ b/drivers/net/wireless/mwifiex/11ac.c
@@ -259,3 +259,22 @@ int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv,
259 259
260 return ret_len; 260 return ret_len;
261} 261}
262
263int mwifiex_cmd_11ac_cfg(struct mwifiex_private *priv,
264 struct host_cmd_ds_command *cmd, u16 cmd_action,
265 struct mwifiex_11ac_vht_cfg *cfg)
266{
267 struct host_cmd_11ac_vht_cfg *vhtcfg = &cmd->params.vht_cfg;
268
269 cmd->command = cpu_to_le16(HostCmd_CMD_11AC_CFG);
270 cmd->size = cpu_to_le16(sizeof(struct host_cmd_11ac_vht_cfg) +
271 S_DS_GEN);
272 vhtcfg->action = cpu_to_le16(cmd_action);
273 vhtcfg->band_config = cfg->band_config;
274 vhtcfg->misc_config = cfg->misc_config;
275 vhtcfg->cap_info = cpu_to_le32(cfg->cap_info);
276 vhtcfg->mcs_tx_set = cpu_to_le32(cfg->mcs_tx_set);
277 vhtcfg->mcs_rx_set = cpu_to_le32(cfg->mcs_rx_set);
278
279 return 0;
280}
diff --git a/drivers/net/wireless/mwifiex/11ac.h b/drivers/net/wireless/mwifiex/11ac.h
index 80fd1ba46200..7c2c69b5b3eb 100644
--- a/drivers/net/wireless/mwifiex/11ac.h
+++ b/drivers/net/wireless/mwifiex/11ac.h
@@ -20,7 +20,24 @@
20#ifndef _MWIFIEX_11AC_H_ 20#ifndef _MWIFIEX_11AC_H_
21#define _MWIFIEX_11AC_H_ 21#define _MWIFIEX_11AC_H_
22 22
23#define VHT_CFG_2GHZ BIT(0)
24#define VHT_CFG_5GHZ BIT(1)
25
26enum vht_cfg_misc_config {
27 VHT_CAP_TX_OPERATION = 1,
28 VHT_CAP_ASSOCIATION,
29 VHT_CAP_UAP_ONLY
30};
31
32#define DEFAULT_VHT_MCS_SET 0xfffa
33#define DISABLE_VHT_MCS_SET 0xffff
34
35#define VHT_BW_80_160_80P80 BIT(2)
36
23int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv, 37int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv,
24 struct mwifiex_bssdescriptor *bss_desc, 38 struct mwifiex_bssdescriptor *bss_desc,
25 u8 **buffer); 39 u8 **buffer);
40int mwifiex_cmd_11ac_cfg(struct mwifiex_private *priv,
41 struct host_cmd_ds_command *cmd, u16 cmd_action,
42 struct mwifiex_11ac_vht_cfg *cfg);
26#endif /* _MWIFIEX_11AC_H_ */ 43#endif /* _MWIFIEX_11AC_H_ */
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index dbf5b1289516..95f3306e2836 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1374,6 +1374,13 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1374 } 1374 }
1375 1375
1376 mwifiex_set_ht_params(priv, bss_cfg, params); 1376 mwifiex_set_ht_params(priv, bss_cfg, params);
1377
1378 if (priv->adapter->is_hw_11ac_capable) {
1379 mwifiex_set_vht_params(priv, bss_cfg, params);
1380 mwifiex_set_vht_width(priv, params->chandef.width,
1381 priv->ap_11ac_enabled);
1382 }
1383
1377 mwifiex_set_wmm_params(priv, bss_cfg, params); 1384 mwifiex_set_wmm_params(priv, bss_cfg, params);
1378 1385
1379 if (params->inactivity_timeout > 0) { 1386 if (params->inactivity_timeout > 0) {
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 57c5defe1f9d..1f7578d553ec 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -295,6 +295,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
295#define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa 295#define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa
296#define HostCmd_CMD_MGMT_FRAME_REG 0x010c 296#define HostCmd_CMD_MGMT_FRAME_REG 0x010c
297#define HostCmd_CMD_REMAIN_ON_CHAN 0x010d 297#define HostCmd_CMD_REMAIN_ON_CHAN 0x010d
298#define HostCmd_CMD_11AC_CFG 0x0112
298 299
299#define PROTOCOL_NO_SECURITY 0x01 300#define PROTOCOL_NO_SECURITY 0x01
300#define PROTOCOL_STATIC_WEP 0x02 301#define PROTOCOL_STATIC_WEP 0x02
@@ -1363,6 +1364,15 @@ struct host_cmd_ds_sys_config {
1363 u8 tlv[0]; 1364 u8 tlv[0];
1364}; 1365};
1365 1366
1367struct host_cmd_11ac_vht_cfg {
1368 __le16 action;
1369 u8 band_config;
1370 u8 misc_config;
1371 __le32 cap_info;
1372 __le32 mcs_tx_set;
1373 __le32 mcs_rx_set;
1374} __packed;
1375
1366struct host_cmd_tlv_akmp { 1376struct host_cmd_tlv_akmp {
1367 struct host_cmd_tlv tlv; 1377 struct host_cmd_tlv tlv;
1368 __le16 key_mgmt; 1378 __le16 key_mgmt;
@@ -1620,6 +1630,7 @@ struct host_cmd_ds_command {
1620 struct host_cmd_ds_802_11_eeprom_access eeprom; 1630 struct host_cmd_ds_802_11_eeprom_access eeprom;
1621 struct host_cmd_ds_802_11_subsc_evt subsc_evt; 1631 struct host_cmd_ds_802_11_subsc_evt subsc_evt;
1622 struct host_cmd_ds_sys_config uap_sys_config; 1632 struct host_cmd_ds_sys_config uap_sys_config;
1633 struct host_cmd_11ac_vht_cfg vht_cfg;
1623 } params; 1634 } params;
1624} __packed; 1635} __packed;
1625 1636
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 91d522c746ed..7f27e45680b5 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -272,6 +272,14 @@ struct mwifiex_ds_pm_cfg {
272 } param; 272 } param;
273}; 273};
274 274
275struct mwifiex_11ac_vht_cfg {
276 u8 band_config;
277 u8 misc_config;
278 u32 cap_info;
279 u32 mcs_tx_set;
280 u32 mcs_rx_set;
281};
282
275struct mwifiex_ds_11n_tx_cfg { 283struct mwifiex_ds_11n_tx_cfg {
276 u16 tx_htcap; 284 u16 tx_htcap;
277 u16 tx_htinfo; 285 u16 tx_htinfo;
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 920657587fff..975bc186a643 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -913,8 +913,14 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv,
913void mwifiex_set_ht_params(struct mwifiex_private *priv, 913void mwifiex_set_ht_params(struct mwifiex_private *priv,
914 struct mwifiex_uap_bss_param *bss_cfg, 914 struct mwifiex_uap_bss_param *bss_cfg,
915 struct cfg80211_ap_settings *params); 915 struct cfg80211_ap_settings *params);
916void mwifiex_set_vht_params(struct mwifiex_private *priv,
917 struct mwifiex_uap_bss_param *bss_cfg,
918 struct cfg80211_ap_settings *params);
916void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg, 919void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
917 struct cfg80211_ap_settings *params); 920 struct cfg80211_ap_settings *params);
921void mwifiex_set_vht_width(struct mwifiex_private *priv,
922 enum nl80211_chan_width width,
923 bool ap_11ac_disable);
918void 924void
919mwifiex_set_wmm_params(struct mwifiex_private *priv, 925mwifiex_set_wmm_params(struct mwifiex_private *priv,
920 struct mwifiex_uap_bss_param *bss_cfg, 926 struct mwifiex_uap_bss_param *bss_cfg,
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index a2ae690a0a67..b193e25977d2 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -24,6 +24,7 @@
24#include "main.h" 24#include "main.h"
25#include "wmm.h" 25#include "wmm.h"
26#include "11n.h" 26#include "11n.h"
27#include "11ac.h"
27 28
28/* 29/*
29 * This function prepares command to set/get RSSI information. 30 * This function prepares command to set/get RSSI information.
@@ -1258,6 +1259,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1258 cpu_to_le16(sizeof(struct host_cmd_ds_remain_on_chan) + 1259 cpu_to_le16(sizeof(struct host_cmd_ds_remain_on_chan) +
1259 S_DS_GEN); 1260 S_DS_GEN);
1260 break; 1261 break;
1262 case HostCmd_CMD_11AC_CFG:
1263 ret = mwifiex_cmd_11ac_cfg(priv, cmd_ptr, cmd_action, data_buf);
1264 break;
1261 case HostCmd_CMD_P2P_MODE_CFG: 1265 case HostCmd_CMD_P2P_MODE_CFG:
1262 cmd_ptr->command = cpu_to_le16(cmd_no); 1266 cmd_ptr->command = cpu_to_le16(cmd_no);
1263 cmd_ptr->params.mode_cfg.action = cpu_to_le16(cmd_action); 1267 cmd_ptr->params.mode_cfg.action = cpu_to_le16(cmd_action);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 80b9f2238001..c7dc450f0bf3 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -907,6 +907,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
907 case HostCmd_CMD_REMAIN_ON_CHAN: 907 case HostCmd_CMD_REMAIN_ON_CHAN:
908 ret = mwifiex_ret_remain_on_chan(priv, resp, data_buf); 908 ret = mwifiex_ret_remain_on_chan(priv, resp, data_buf);
909 break; 909 break;
910 case HostCmd_CMD_11AC_CFG:
911 break;
910 case HostCmd_CMD_P2P_MODE_CFG: 912 case HostCmd_CMD_P2P_MODE_CFG:
911 ret = mwifiex_ret_p2p_mode_cfg(priv, resp, data_buf); 913 ret = mwifiex_ret_p2p_mode_cfg(priv, resp, data_buf);
912 break; 914 break;
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 6e76a15a8950..b04b1db29100 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include "main.h" 20#include "main.h"
21#include "11ac.h"
21 22
22/* This function parses security related parameters from cfg80211_ap_settings 23/* This function parses security related parameters from cfg80211_ap_settings
23 * and sets into FW understandable bss_config structure. 24 * and sets into FW understandable bss_config structure.
@@ -177,6 +178,60 @@ mwifiex_set_ht_params(struct mwifiex_private *priv,
177 return; 178 return;
178} 179}
179 180
181/* This function updates 11ac related parameters from IE
182 * and sets them into bss_config structure.
183 */
184void mwifiex_set_vht_params(struct mwifiex_private *priv,
185 struct mwifiex_uap_bss_param *bss_cfg,
186 struct cfg80211_ap_settings *params)
187{
188 const u8 *vht_ie;
189
190 vht_ie = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, params->beacon.tail,
191 params->beacon.tail_len);
192 if (vht_ie) {
193 memcpy(&bss_cfg->vht_cap, vht_ie + 2,
194 sizeof(struct ieee80211_vht_cap));
195 priv->ap_11ac_enabled = 1;
196 } else {
197 priv->ap_11ac_enabled = 0;
198 }
199
200 return;
201}
202
203/* Enable VHT only when cfg80211_ap_settings has VHT IE.
204 * Otherwise disable VHT.
205 */
206void mwifiex_set_vht_width(struct mwifiex_private *priv,
207 enum nl80211_chan_width width,
208 bool ap_11ac_enable)
209{
210 struct mwifiex_adapter *adapter = priv->adapter;
211 struct mwifiex_11ac_vht_cfg vht_cfg;
212
213 vht_cfg.band_config = VHT_CFG_5GHZ;
214 vht_cfg.cap_info = adapter->hw_dot_11ac_dev_cap;
215
216 if (!ap_11ac_enable) {
217 vht_cfg.mcs_tx_set = DISABLE_VHT_MCS_SET;
218 vht_cfg.mcs_rx_set = DISABLE_VHT_MCS_SET;
219 } else {
220 vht_cfg.mcs_tx_set = DEFAULT_VHT_MCS_SET;
221 vht_cfg.mcs_rx_set = DEFAULT_VHT_MCS_SET;
222 }
223
224 vht_cfg.misc_config = VHT_CAP_UAP_ONLY;
225
226 if (ap_11ac_enable && width >= NL80211_CHAN_WIDTH_80)
227 vht_cfg.misc_config |= VHT_BW_80_160_80P80;
228
229 mwifiex_send_cmd_sync(priv, HostCmd_CMD_11AC_CFG,
230 HostCmd_ACT_GEN_SET, 0, &vht_cfg);
231
232 return;
233}
234
180/* This function finds supported rates IE from beacon parameter and sets 235/* This function finds supported rates IE from beacon parameter and sets
181 * these rates into bss_config structure. 236 * these rates into bss_config structure.
182 */ 237 */
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index aadda99989c0..ee654a691f38 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -670,7 +670,7 @@ static unsigned int p54_flush_count(struct p54_common *priv)
670 return total; 670 return total;
671} 671}
672 672
673static void p54_flush(struct ieee80211_hw *dev, bool drop) 673static void p54_flush(struct ieee80211_hw *dev, u32 queues, bool drop)
674{ 674{
675 struct p54_common *priv = dev->priv; 675 struct p54_common *priv = dev->priv;
676 unsigned int total, i; 676 unsigned int total, i;
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 51922cc179de..cdf26ede7270 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -1366,7 +1366,7 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw,
1366 struct ieee80211_vif *vif, u16 queue, 1366 struct ieee80211_vif *vif, u16 queue,
1367 const struct ieee80211_tx_queue_params *params); 1367 const struct ieee80211_tx_queue_params *params);
1368void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); 1368void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
1369void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop); 1369void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
1370int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); 1370int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
1371int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 1371int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
1372void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, 1372void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 20c6eccce5aa..9161c02d8ff9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -748,7 +748,7 @@ void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw)
748} 748}
749EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll); 749EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
750 750
751void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) 751void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
752{ 752{
753 struct rt2x00_dev *rt2x00dev = hw->priv; 753 struct rt2x00_dev *rt2x00dev = hw->priv;
754 struct data_queue *queue; 754 struct data_queue *queue;
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index d3ce9fbef00e..b5a7a260bf63 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -1166,7 +1166,7 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
1166 * before switch channle or power save, or tx buffer packet 1166 * before switch channle or power save, or tx buffer packet
1167 * maybe send after offchannel or rf sleep, this may cause 1167 * maybe send after offchannel or rf sleep, this may cause
1168 * dis-association by AP */ 1168 * dis-association by AP */
1169static void rtl_op_flush(struct ieee80211_hw *hw, bool drop) 1169static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1170{ 1170{
1171 struct rtl_priv *rtlpriv = rtl_priv(hw); 1171 struct rtl_priv *rtlpriv = rtl_priv(hw);
1172 1172
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index b6222eedb835..710f7904ecdf 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -434,7 +434,7 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
434 (u32)hdr->addr1[2], (u32)hdr->addr1[3], 434 (u32)hdr->addr1[2], (u32)hdr->addr1[3],
435 (u32)hdr->addr1[4], (u32)hdr->addr1[5]); 435 (u32)hdr->addr1[4], (u32)hdr->addr1[5]);
436 memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status)); 436 memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
437 ieee80211_rx_irqsafe(hw, skb); 437 ieee80211_rx(hw, skb);
438} 438}
439 439
440void rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb) 440void rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb)
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index b5c80b5d57ef..72c2614213c4 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -308,6 +308,8 @@ static int _rtl_usb_init_tx(struct ieee80211_hw *hw)
308 return 0; 308 return 0;
309} 309}
310 310
311static void _rtl_rx_work(unsigned long param);
312
311static int _rtl_usb_init_rx(struct ieee80211_hw *hw) 313static int _rtl_usb_init_rx(struct ieee80211_hw *hw)
312{ 314{
313 struct rtl_priv *rtlpriv = rtl_priv(hw); 315 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -324,6 +326,12 @@ static int _rtl_usb_init_rx(struct ieee80211_hw *hw)
324 pr_info("rx_max_size %d, rx_urb_num %d, in_ep %d\n", 326 pr_info("rx_max_size %d, rx_urb_num %d, in_ep %d\n",
325 rtlusb->rx_max_size, rtlusb->rx_urb_num, rtlusb->in_ep); 327 rtlusb->rx_max_size, rtlusb->rx_urb_num, rtlusb->in_ep);
326 init_usb_anchor(&rtlusb->rx_submitted); 328 init_usb_anchor(&rtlusb->rx_submitted);
329 init_usb_anchor(&rtlusb->rx_cleanup_urbs);
330
331 skb_queue_head_init(&rtlusb->rx_queue);
332 rtlusb->rx_work_tasklet.func = _rtl_rx_work;
333 rtlusb->rx_work_tasklet.data = (unsigned long)rtlusb;
334
327 return 0; 335 return 0;
328} 336}
329 337
@@ -405,40 +413,30 @@ static void rtl_usb_init_sw(struct ieee80211_hw *hw)
405 rtlusb->disableHWSM = true; 413 rtlusb->disableHWSM = true;
406} 414}
407 415
408#define __RADIO_TAP_SIZE_RSV 32
409
410static void _rtl_rx_completed(struct urb *urb); 416static void _rtl_rx_completed(struct urb *urb);
411 417
412static struct sk_buff *_rtl_prep_rx_urb(struct ieee80211_hw *hw, 418static int _rtl_prep_rx_urb(struct ieee80211_hw *hw, struct rtl_usb *rtlusb,
413 struct rtl_usb *rtlusb, 419 struct urb *urb, gfp_t gfp_mask)
414 struct urb *urb,
415 gfp_t gfp_mask)
416{ 420{
417 struct sk_buff *skb;
418 struct rtl_priv *rtlpriv = rtl_priv(hw); 421 struct rtl_priv *rtlpriv = rtl_priv(hw);
422 void *buf;
419 423
420 skb = __dev_alloc_skb((rtlusb->rx_max_size + __RADIO_TAP_SIZE_RSV), 424 buf = usb_alloc_coherent(rtlusb->udev, rtlusb->rx_max_size, gfp_mask,
421 gfp_mask); 425 &urb->transfer_dma);
422 if (!skb) { 426 if (!buf) {
423 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, 427 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
424 "Failed to __dev_alloc_skb!!\n"); 428 "Failed to usb_alloc_coherent!!\n");
425 return ERR_PTR(-ENOMEM); 429 return -ENOMEM;
426 } 430 }
427 431
428 /* reserve some space for mac80211's radiotap */
429 skb_reserve(skb, __RADIO_TAP_SIZE_RSV);
430 usb_fill_bulk_urb(urb, rtlusb->udev, 432 usb_fill_bulk_urb(urb, rtlusb->udev,
431 usb_rcvbulkpipe(rtlusb->udev, rtlusb->in_ep), 433 usb_rcvbulkpipe(rtlusb->udev, rtlusb->in_ep),
432 skb->data, min(skb_tailroom(skb), 434 buf, rtlusb->rx_max_size, _rtl_rx_completed, rtlusb);
433 (int)rtlusb->rx_max_size), 435 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
434 _rtl_rx_completed, skb);
435 436
436 _rtl_install_trx_info(rtlusb, skb, rtlusb->in_ep); 437 return 0;
437 return skb;
438} 438}
439 439
440#undef __RADIO_TAP_SIZE_RSV
441
442static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw, 440static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw,
443 struct sk_buff *skb) 441 struct sk_buff *skb)
444{ 442{
@@ -522,22 +520,11 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw,
522 if (unicast) 520 if (unicast)
523 rtlpriv->link_info.num_rx_inperiod++; 521 rtlpriv->link_info.num_rx_inperiod++;
524 } 522 }
525 if (likely(rtl_action_proc(hw, skb, false))) { 523
526 struct sk_buff *uskb = NULL; 524 if (likely(rtl_action_proc(hw, skb, false)))
527 u8 *pdata; 525 ieee80211_rx(hw, skb);
528 526 else
529 uskb = dev_alloc_skb(skb->len + 128);
530 if (uskb) { /* drop packet on allocation failure */
531 memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status,
532 sizeof(rx_status));
533 pdata = (u8 *)skb_put(uskb, skb->len);
534 memcpy(pdata, skb->data, skb->len);
535 ieee80211_rx_irqsafe(hw, uskb);
536 }
537 dev_kfree_skb_any(skb);
538 } else {
539 dev_kfree_skb_any(skb); 527 dev_kfree_skb_any(skb);
540 }
541 } 528 }
542} 529}
543 530
@@ -554,15 +541,70 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb)
554 while (!skb_queue_empty(&rx_queue)) { 541 while (!skb_queue_empty(&rx_queue)) {
555 _skb = skb_dequeue(&rx_queue); 542 _skb = skb_dequeue(&rx_queue);
556 _rtl_usb_rx_process_agg(hw, _skb); 543 _rtl_usb_rx_process_agg(hw, _skb);
557 ieee80211_rx_irqsafe(hw, _skb); 544 ieee80211_rx(hw, _skb);
558 } 545 }
559} 546}
560 547
548#define __RX_SKB_MAX_QUEUED 32
549
550static void _rtl_rx_work(unsigned long param)
551{
552 struct rtl_usb *rtlusb = (struct rtl_usb *)param;
553 struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf);
554 struct sk_buff *skb;
555
556 while ((skb = skb_dequeue(&rtlusb->rx_queue))) {
557 if (unlikely(IS_USB_STOP(rtlusb))) {
558 dev_kfree_skb_any(skb);
559 continue;
560 }
561
562 if (likely(!rtlusb->usb_rx_segregate_hdl)) {
563 _rtl_usb_rx_process_noagg(hw, skb);
564 } else {
565 /* TO DO */
566 _rtl_rx_pre_process(hw, skb);
567 pr_err("rx agg not supported\n");
568 }
569 }
570}
571
572static unsigned int _rtl_rx_get_padding(struct ieee80211_hdr *hdr,
573 unsigned int len)
574{
575 unsigned int padding = 0;
576
577 /* make function no-op when possible */
578 if (NET_IP_ALIGN == 0 || len < sizeof(*hdr))
579 return 0;
580
581 /* alignment calculation as in lbtf_rx() / carl9170_rx_copy_data() */
582 /* TODO: deduplicate common code, define helper function instead? */
583
584 if (ieee80211_is_data_qos(hdr->frame_control)) {
585 u8 *qc = ieee80211_get_qos_ctl(hdr);
586
587 padding ^= NET_IP_ALIGN;
588
589 /* Input might be invalid, avoid accessing memory outside
590 * the buffer.
591 */
592 if ((unsigned long)qc - (unsigned long)hdr < len &&
593 *qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT)
594 padding ^= NET_IP_ALIGN;
595 }
596
597 if (ieee80211_has_a4(hdr->frame_control))
598 padding ^= NET_IP_ALIGN;
599
600 return padding;
601}
602
603#define __RADIO_TAP_SIZE_RSV 32
604
561static void _rtl_rx_completed(struct urb *_urb) 605static void _rtl_rx_completed(struct urb *_urb)
562{ 606{
563 struct sk_buff *skb = (struct sk_buff *)_urb->context; 607 struct rtl_usb *rtlusb = (struct rtl_usb *)_urb->context;
564 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
565 struct rtl_usb *rtlusb = (struct rtl_usb *)info->rate_driver_data[0];
566 struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf); 608 struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf);
567 struct rtl_priv *rtlpriv = rtl_priv(hw); 609 struct rtl_priv *rtlpriv = rtl_priv(hw);
568 int err = 0; 610 int err = 0;
@@ -571,28 +613,50 @@ static void _rtl_rx_completed(struct urb *_urb)
571 goto free; 613 goto free;
572 614
573 if (likely(0 == _urb->status)) { 615 if (likely(0 == _urb->status)) {
574 /* If this code were moved to work queue, would CPU 616 unsigned int padding;
575 * utilization be improved? NOTE: We shall allocate another skb 617 struct sk_buff *skb;
576 * and reuse the original one. 618 unsigned int qlen;
577 */ 619 unsigned int size = _urb->actual_length;
578 skb_put(skb, _urb->actual_length); 620 struct ieee80211_hdr *hdr;
579 621
580 if (likely(!rtlusb->usb_rx_segregate_hdl)) { 622 if (size < RTL_RX_DESC_SIZE + sizeof(struct ieee80211_hdr)) {
581 struct sk_buff *_skb; 623 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
582 _rtl_usb_rx_process_noagg(hw, skb); 624 "Too short packet from bulk IN! (len: %d)\n",
583 _skb = _rtl_prep_rx_urb(hw, rtlusb, _urb, GFP_ATOMIC); 625 size);
584 if (IS_ERR(_skb)) { 626 goto resubmit;
585 err = PTR_ERR(_skb); 627 }
586 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, 628
587 "Can't allocate skb for bulk IN!\n"); 629 qlen = skb_queue_len(&rtlusb->rx_queue);
588 return; 630 if (qlen >= __RX_SKB_MAX_QUEUED) {
589 } 631 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
590 skb = _skb; 632 "Pending RX skbuff queue full! (qlen: %d)\n",
591 } else{ 633 qlen);
592 /* TO DO */ 634 goto resubmit;
593 _rtl_rx_pre_process(hw, skb);
594 pr_err("rx agg not supported\n");
595 } 635 }
636
637 hdr = (void *)(_urb->transfer_buffer + RTL_RX_DESC_SIZE);
638 padding = _rtl_rx_get_padding(hdr, size - RTL_RX_DESC_SIZE);
639
640 skb = dev_alloc_skb(size + __RADIO_TAP_SIZE_RSV + padding);
641 if (!skb) {
642 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
643 "Can't allocate skb for bulk IN!\n");
644 goto resubmit;
645 }
646
647 _rtl_install_trx_info(rtlusb, skb, rtlusb->in_ep);
648
649 /* Make sure the payload data is 4 byte aligned. */
650 skb_reserve(skb, padding);
651
652 /* reserve some space for mac80211's radiotap */
653 skb_reserve(skb, __RADIO_TAP_SIZE_RSV);
654
655 memcpy(skb_put(skb, size), _urb->transfer_buffer, size);
656
657 skb_queue_tail(&rtlusb->rx_queue, skb);
658 tasklet_schedule(&rtlusb->rx_work_tasklet);
659
596 goto resubmit; 660 goto resubmit;
597 } 661 }
598 662
@@ -608,9 +672,6 @@ static void _rtl_rx_completed(struct urb *_urb)
608 } 672 }
609 673
610resubmit: 674resubmit:
611 skb_reset_tail_pointer(skb);
612 skb_trim(skb, 0);
613
614 usb_anchor_urb(_urb, &rtlusb->rx_submitted); 675 usb_anchor_urb(_urb, &rtlusb->rx_submitted);
615 err = usb_submit_urb(_urb, GFP_ATOMIC); 676 err = usb_submit_urb(_urb, GFP_ATOMIC);
616 if (unlikely(err)) { 677 if (unlikely(err)) {
@@ -620,13 +681,34 @@ resubmit:
620 return; 681 return;
621 682
622free: 683free:
623 dev_kfree_skb_irq(skb); 684 /* On some architectures, usb_free_coherent must not be called from
685 * hardirq context. Queue urb to cleanup list.
686 */
687 usb_anchor_urb(_urb, &rtlusb->rx_cleanup_urbs);
688}
689
690#undef __RADIO_TAP_SIZE_RSV
691
692static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw)
693{
694 struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
695 struct urb *urb;
696
697 usb_kill_anchored_urbs(&rtlusb->rx_submitted);
698
699 tasklet_kill(&rtlusb->rx_work_tasklet);
700 skb_queue_purge(&rtlusb->rx_queue);
701
702 while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) {
703 usb_free_coherent(urb->dev, urb->transfer_buffer_length,
704 urb->transfer_buffer, urb->transfer_dma);
705 usb_free_urb(urb);
706 }
624} 707}
625 708
626static int _rtl_usb_receive(struct ieee80211_hw *hw) 709static int _rtl_usb_receive(struct ieee80211_hw *hw)
627{ 710{
628 struct urb *urb; 711 struct urb *urb;
629 struct sk_buff *skb;
630 int err; 712 int err;
631 int i; 713 int i;
632 struct rtl_priv *rtlpriv = rtl_priv(hw); 714 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -645,11 +727,10 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw)
645 goto err_out; 727 goto err_out;
646 } 728 }
647 729
648 skb = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL); 730 err = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL);
649 if (IS_ERR(skb)) { 731 if (err < 0) {
650 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, 732 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
651 "Failed to prep_rx_urb!!\n"); 733 "Failed to prep_rx_urb!!\n");
652 err = PTR_ERR(skb);
653 usb_free_urb(urb); 734 usb_free_urb(urb);
654 goto err_out; 735 goto err_out;
655 } 736 }
@@ -664,6 +745,7 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw)
664 745
665err_out: 746err_out:
666 usb_kill_anchored_urbs(&rtlusb->rx_submitted); 747 usb_kill_anchored_urbs(&rtlusb->rx_submitted);
748 _rtl_usb_cleanup_rx(hw);
667 return err; 749 return err;
668} 750}
669 751
@@ -705,7 +787,7 @@ static void rtl_usb_cleanup(struct ieee80211_hw *hw)
705 SET_USB_STOP(rtlusb); 787 SET_USB_STOP(rtlusb);
706 788
707 /* clean up rx stuff. */ 789 /* clean up rx stuff. */
708 usb_kill_anchored_urbs(&rtlusb->rx_submitted); 790 _rtl_usb_cleanup_rx(hw);
709 791
710 /* clean up tx stuff */ 792 /* clean up tx stuff */
711 for (i = 0; i < RTL_USB_MAX_EP_NUM; i++) { 793 for (i = 0; i < RTL_USB_MAX_EP_NUM; i++) {
diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h
index fb986f98d1df..685273ca9561 100644
--- a/drivers/net/wireless/rtlwifi/usb.h
+++ b/drivers/net/wireless/rtlwifi/usb.h
@@ -136,11 +136,14 @@ struct rtl_usb {
136 void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *); 136 void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *);
137 137
138 /* Rx */ 138 /* Rx */
139 u8 in_ep_nums ; 139 u8 in_ep_nums;
140 u32 in_ep; /* Bulk IN endpoint number */ 140 u32 in_ep; /* Bulk IN endpoint number */
141 u32 rx_max_size; /* Bulk IN max buffer size */ 141 u32 rx_max_size; /* Bulk IN max buffer size */
142 u32 rx_urb_num; /* How many Bulk INs are submitted to host. */ 142 u32 rx_urb_num; /* How many Bulk INs are submitted to host. */
143 struct usb_anchor rx_submitted; 143 struct usb_anchor rx_submitted;
144 struct usb_anchor rx_cleanup_urbs;
145 struct tasklet_struct rx_work_tasklet;
146 struct sk_buff_head rx_queue;
144 void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *, 147 void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *,
145 struct sk_buff_head *); 148 struct sk_buff_head *);
146 void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *); 149 void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *);
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index e57ee48edff6..e2b3d9c541e8 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -186,8 +186,10 @@ static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
186 wl->set_power(true); 186 wl->set_power(true);
187 187
188 ret = pm_runtime_get_sync(&func->dev); 188 ret = pm_runtime_get_sync(&func->dev);
189 if (ret < 0) 189 if (ret < 0) {
190 pm_runtime_put_sync(&func->dev);
190 goto out; 191 goto out;
192 }
191 193
192 sdio_claim_host(func); 194 sdio_claim_host(func);
193 sdio_enable_func(func); 195 sdio_enable_func(func);
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index 09694e39bb14..1c627da85083 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -723,6 +723,7 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
723 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4; 723 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
724 wl->sched_scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5; 724 wl->sched_scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
725 wl->max_channels_5 = WL12XX_MAX_CHANNELS_5GHZ; 725 wl->max_channels_5 = WL12XX_MAX_CHANNELS_5GHZ;
726 wl->ba_rx_session_count_max = WL12XX_RX_BA_MAX_SESSIONS;
726out: 727out:
727 return ret; 728 return ret;
728} 729}
diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h
index d4552857480c..222d03540200 100644
--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
@@ -63,6 +63,8 @@
63 63
64#define WL12XX_NUM_MAC_ADDRESSES 2 64#define WL12XX_NUM_MAC_ADDRESSES 2
65 65
66#define WL12XX_RX_BA_MAX_SESSIONS 3
67
66struct wl127x_rx_mem_pool_addr { 68struct wl127x_rx_mem_pool_addr {
67 u32 addr; 69 u32 addr;
68 u32 addr_extra; 70 u32 addr_extra;
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index da3ef1b10a9c..9fa692d11025 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -678,6 +678,7 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
678 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC; 678 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC;
679 wl->sched_scan_templ_id_5 = CMD_TEMPL_PROBE_REQ_5_PERIODIC; 679 wl->sched_scan_templ_id_5 = CMD_TEMPL_PROBE_REQ_5_PERIODIC;
680 wl->max_channels_5 = WL18XX_MAX_CHANNELS_5GHZ; 680 wl->max_channels_5 = WL18XX_MAX_CHANNELS_5GHZ;
681 wl->ba_rx_session_count_max = WL18XX_RX_BA_MAX_SESSIONS;
681out: 682out:
682 return ret; 683 return ret;
683} 684}
@@ -1144,6 +1145,7 @@ static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl,
1144static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver) 1145static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
1145{ 1146{
1146 u32 fuse; 1147 u32 fuse;
1148 s8 rom = 0, metal = 0, pg_ver = 0, rdl_ver = 0;
1147 int ret; 1149 int ret;
1148 1150
1149 ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); 1151 ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
@@ -1154,8 +1156,29 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
1154 if (ret < 0) 1156 if (ret < 0)
1155 goto out; 1157 goto out;
1156 1158
1159 pg_ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET;
1160 rom = (fuse & WL18XX_ROM_VER_MASK) >> WL18XX_ROM_VER_OFFSET;
1161
1162 if (rom <= 0xE)
1163 metal = (fuse & WL18XX_METAL_VER_MASK) >>
1164 WL18XX_METAL_VER_OFFSET;
1165 else
1166 metal = (fuse & WL18XX_NEW_METAL_VER_MASK) >>
1167 WL18XX_NEW_METAL_VER_OFFSET;
1168
1169 ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_2_3, &fuse);
1170 if (ret < 0)
1171 goto out;
1172
1173 rdl_ver = (fuse & WL18XX_RDL_VER_MASK) >> WL18XX_RDL_VER_OFFSET;
1174 if (rdl_ver > RDL_MAX)
1175 rdl_ver = RDL_NONE;
1176
1177 wl1271_info("wl18xx HW: RDL %d, %s, PG %x.%x (ROM %x)",
1178 rdl_ver, rdl_names[rdl_ver], pg_ver, metal, rom);
1179
1157 if (ver) 1180 if (ver)
1158 *ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET; 1181 *ver = pg_ver;
1159 1182
1160 ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); 1183 ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
1161 1184
diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h
index 937b71d8783f..6306e04cd258 100644
--- a/drivers/net/wireless/ti/wl18xx/reg.h
+++ b/drivers/net/wireless/ti/wl18xx/reg.h
@@ -131,6 +131,16 @@
131#define WL18XX_REG_FUSE_DATA_1_3 0xA0260C 131#define WL18XX_REG_FUSE_DATA_1_3 0xA0260C
132#define WL18XX_PG_VER_MASK 0x70 132#define WL18XX_PG_VER_MASK 0x70
133#define WL18XX_PG_VER_OFFSET 4 133#define WL18XX_PG_VER_OFFSET 4
134#define WL18XX_ROM_VER_MASK 0x3
135#define WL18XX_ROM_VER_OFFSET 0
136#define WL18XX_METAL_VER_MASK 0xC
137#define WL18XX_METAL_VER_OFFSET 2
138#define WL18XX_NEW_METAL_VER_MASK 0x180
139#define WL18XX_NEW_METAL_VER_OFFSET 7
140
141#define WL18XX_REG_FUSE_DATA_2_3 0xA02614
142#define WL18XX_RDL_VER_MASK 0x1f00
143#define WL18XX_RDL_VER_OFFSET 8
134 144
135#define WL18XX_REG_FUSE_BD_ADDR_1 0xA02602 145#define WL18XX_REG_FUSE_BD_ADDR_1 0xA02602
136#define WL18XX_REG_FUSE_BD_ADDR_2 0xA02606 146#define WL18XX_REG_FUSE_BD_ADDR_2 0xA02606
@@ -188,4 +198,23 @@ enum {
188 NUM_BOARD_TYPES, 198 NUM_BOARD_TYPES,
189}; 199};
190 200
201enum {
202 RDL_NONE = 0,
203 RDL_1_HP = 1,
204 RDL_2_SP = 2,
205 RDL_3_HP = 3,
206 RDL_4_SP = 4,
207
208 _RDL_LAST,
209 RDL_MAX = _RDL_LAST - 1,
210};
211
212static const char * const rdl_names[] = {
213 [RDL_NONE] = "",
214 [RDL_1_HP] = "1853 SISO",
215 [RDL_2_SP] = "1857 MIMO",
216 [RDL_3_HP] = "1893 SISO",
217 [RDL_4_SP] = "1897 MIMO",
218};
219
191#endif /* __REG_H__ */ 220#endif /* __REG_H__ */
diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h
index b6739e79efcf..9204e07ee432 100644
--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
@@ -29,7 +29,7 @@
29#define WL18XX_IFTYPE_VER 5 29#define WL18XX_IFTYPE_VER 5
30#define WL18XX_MAJOR_VER WLCORE_FW_VER_IGNORE 30#define WL18XX_MAJOR_VER WLCORE_FW_VER_IGNORE
31#define WL18XX_SUBTYPE_VER WLCORE_FW_VER_IGNORE 31#define WL18XX_SUBTYPE_VER WLCORE_FW_VER_IGNORE
32#define WL18XX_MINOR_VER 28 32#define WL18XX_MINOR_VER 39
33 33
34#define WL18XX_CMD_MAX_SIZE 740 34#define WL18XX_CMD_MAX_SIZE 740
35 35
@@ -40,6 +40,8 @@
40 40
41#define WL18XX_NUM_MAC_ADDRESSES 3 41#define WL18XX_NUM_MAC_ADDRESSES 3
42 42
43#define WL18XX_RX_BA_MAX_SESSIONS 5
44
43struct wl18xx_priv { 45struct wl18xx_priv {
44 /* buffer for sending commands to FW */ 46 /* buffer for sending commands to FW */
45 u8 cmd_buf[WL18XX_CMD_MAX_SIZE]; 47 u8 cmd_buf[WL18XX_CMD_MAX_SIZE];
diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
index c79654323396..7a970cd9c555 100644
--- a/drivers/net/wireless/ti/wlcore/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -1736,6 +1736,35 @@ out:
1736 1736
1737} 1737}
1738 1738
1739int wlcore_acx_average_rssi(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1740 s8 *avg_rssi)
1741{
1742 struct acx_roaming_stats *acx;
1743 int ret = 0;
1744
1745 wl1271_debug(DEBUG_ACX, "acx roaming statistics");
1746
1747 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1748 if (!acx) {
1749 ret = -ENOMEM;
1750 goto out;
1751 }
1752
1753 acx->role_id = wlvif->role_id;
1754 ret = wl1271_cmd_interrogate(wl, ACX_ROAMING_STATISTICS_TBL,
1755 acx, sizeof(*acx));
1756 if (ret < 0) {
1757 wl1271_warning("acx roaming statistics failed: %d", ret);
1758 ret = -ENOMEM;
1759 goto out;
1760 }
1761
1762 *avg_rssi = acx->rssi_beacon;
1763out:
1764 kfree(acx);
1765 return ret;
1766}
1767
1739#ifdef CONFIG_PM 1768#ifdef CONFIG_PM
1740/* Set the global behaviour of RX filters - On/Off + default action */ 1769/* Set the global behaviour of RX filters - On/Off + default action */
1741int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, 1770int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h
index 126536c6a393..6dcfad9b0472 100644
--- a/drivers/net/wireless/ti/wlcore/acx.h
+++ b/drivers/net/wireless/ti/wlcore/acx.h
@@ -728,8 +728,6 @@ struct wl1271_acx_ht_information {
728 u8 padding[2]; 728 u8 padding[2];
729} __packed; 729} __packed;
730 730
731#define RX_BA_MAX_SESSIONS 3
732
733struct wl1271_acx_ba_initiator_policy { 731struct wl1271_acx_ba_initiator_policy {
734 struct acx_header header; 732 struct acx_header header;
735 733
@@ -955,6 +953,18 @@ struct acx_rx_filter_cfg {
955 u8 fields[0]; 953 u8 fields[0];
956} __packed; 954} __packed;
957 955
956struct acx_roaming_stats {
957 struct acx_header header;
958
959 u8 role_id;
960 u8 pad[3];
961 u32 missed_beacons;
962 u8 snr_data;
963 u8 snr_bacon;
964 s8 rssi_data;
965 s8 rssi_beacon;
966} __packed;
967
958enum { 968enum {
959 ACX_WAKE_UP_CONDITIONS = 0x0000, 969 ACX_WAKE_UP_CONDITIONS = 0x0000,
960 ACX_MEM_CFG = 0x0001, 970 ACX_MEM_CFG = 0x0001,
@@ -1112,6 +1122,8 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
1112int wl1271_acx_fm_coex(struct wl1271 *wl); 1122int wl1271_acx_fm_coex(struct wl1271 *wl);
1113int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl); 1123int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
1114int wl12xx_acx_config_hangover(struct wl1271 *wl); 1124int wl12xx_acx_config_hangover(struct wl1271 *wl);
1125int wlcore_acx_average_rssi(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1126 s8 *avg_rssi);
1115 1127
1116#ifdef CONFIG_PM 1128#ifdef CONFIG_PM
1117int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, 1129int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 6331f9e1cb39..c9e060795d13 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -327,6 +327,14 @@ int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
327 wl->links[link].prev_freed_pkts = 327 wl->links[link].prev_freed_pkts =
328 wl->fw_status_2->counters.tx_lnk_free_pkts[link]; 328 wl->fw_status_2->counters.tx_lnk_free_pkts[link];
329 wl->links[link].wlvif = wlvif; 329 wl->links[link].wlvif = wlvif;
330
331 /*
332 * Take saved value for total freed packets from wlvif, in case this is
333 * recovery/resume
334 */
335 if (wlvif->bss_type != BSS_TYPE_AP_BSS)
336 wl->links[link].total_freed_pkts = wlvif->total_freed_pkts;
337
330 *hlid = link; 338 *hlid = link;
331 339
332 wl->active_link_count++; 340 wl->active_link_count++;
@@ -358,6 +366,26 @@ void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
358 wl1271_tx_reset_link_queues(wl, *hlid); 366 wl1271_tx_reset_link_queues(wl, *hlid);
359 wl->links[*hlid].wlvif = NULL; 367 wl->links[*hlid].wlvif = NULL;
360 368
369 if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
370 (wlvif->bss_type == BSS_TYPE_AP_BSS &&
371 *hlid == wlvif->ap.bcast_hlid)) {
372 /*
373 * save the total freed packets in the wlvif, in case this is
374 * recovery or suspend
375 */
376 wlvif->total_freed_pkts = wl->links[*hlid].total_freed_pkts;
377
378 /*
379 * increment the initial seq number on recovery to account for
380 * transmitted packets that we haven't yet got in the FW status
381 */
382 if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
383 wlvif->total_freed_pkts +=
384 WL1271_TX_SQN_POST_RECOVERY_PADDING;
385 }
386
387 wl->links[*hlid].total_freed_pkts = 0;
388
361 *hlid = WL12XX_INVALID_LINK_ID; 389 *hlid = WL12XX_INVALID_LINK_ID;
362 wl->active_link_count--; 390 wl->active_link_count--;
363 WARN_ON_ONCE(wl->active_link_count < 0); 391 WARN_ON_ONCE(wl->active_link_count < 0);
@@ -609,6 +637,10 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
609 if (ret < 0) 637 if (ret < 0)
610 goto out_free_global; 638 goto out_free_global;
611 639
640 /* use the previous security seq, if this is a recovery/resume */
641 wl->links[wlvif->ap.bcast_hlid].total_freed_pkts =
642 wlvif->total_freed_pkts;
643
612 cmd->role_id = wlvif->role_id; 644 cmd->role_id = wlvif->role_id;
613 cmd->ap.aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period); 645 cmd->ap.aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period);
614 cmd->ap.bss_index = WL1271_AP_BSS_INDEX; 646 cmd->ap.bss_index = WL1271_AP_BSS_INDEX;
diff --git a/drivers/net/wireless/ti/wlcore/debug.h b/drivers/net/wireless/ti/wlcore/debug.h
index db4bf5a68ce2..0420bd45e4ee 100644
--- a/drivers/net/wireless/ti/wlcore/debug.h
+++ b/drivers/net/wireless/ti/wlcore/debug.h
@@ -89,25 +89,24 @@ extern u32 wl12xx_debug_level;
89 } while (0) 89 } while (0)
90#endif 90#endif
91 91
92/* TODO: use pr_debug_hex_dump when it becomes available */ 92#define wl1271_dump(level, prefix, buf, len) \
93#define wl1271_dump(level, prefix, buf, len) \ 93 do { \
94 do { \ 94 if (level & wl12xx_debug_level) \
95 if (level & wl12xx_debug_level) \ 95 print_hex_dump_debug(DRIVER_PREFIX prefix, \
96 print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ 96 DUMP_PREFIX_OFFSET, 16, 1, \
97 DUMP_PREFIX_OFFSET, 16, 1, \ 97 buf, \
98 buf, \ 98 min_t(size_t, len, DEBUG_DUMP_LIMIT), \
99 min_t(size_t, len, DEBUG_DUMP_LIMIT), \ 99 0); \
100 0); \
101 } while (0) 100 } while (0)
102 101
103#define wl1271_dump_ascii(level, prefix, buf, len) \ 102#define wl1271_dump_ascii(level, prefix, buf, len) \
104 do { \ 103 do { \
105 if (level & wl12xx_debug_level) \ 104 if (level & wl12xx_debug_level) \
106 print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ 105 print_hex_dump_debug(DRIVER_PREFIX prefix, \
107 DUMP_PREFIX_OFFSET, 16, 1, \ 106 DUMP_PREFIX_OFFSET, 16, 1, \
108 buf, \ 107 buf, \
109 min_t(size_t, len, DEBUG_DUMP_LIMIT), \ 108 min_t(size_t, len, DEBUG_DUMP_LIMIT), \
110 true); \ 109 true); \
111 } while (0) 110 } while (0)
112 111
113#endif /* __DEBUG_H__ */ 112#endif /* __DEBUG_H__ */
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index e70a7c864865..c3e1f79c7856 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -598,8 +598,7 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
598 VIF_STATE_PRINT_INT(last_rssi_event); 598 VIF_STATE_PRINT_INT(last_rssi_event);
599 VIF_STATE_PRINT_INT(ba_support); 599 VIF_STATE_PRINT_INT(ba_support);
600 VIF_STATE_PRINT_INT(ba_allowed); 600 VIF_STATE_PRINT_INT(ba_allowed);
601 VIF_STATE_PRINT_LLHEX(tx_security_seq); 601 VIF_STATE_PRINT_LLHEX(total_freed_pkts);
602 VIF_STATE_PRINT_INT(tx_security_last_seq_lsb);
603 } 602 }
604 603
605#undef VIF_STATE_PRINT_INT 604#undef VIF_STATE_PRINT_INT
diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c
index 70f289aa1bc6..67f61689b49e 100644
--- a/drivers/net/wireless/ti/wlcore/event.c
+++ b/drivers/net/wireless/ti/wlcore/event.c
@@ -237,6 +237,14 @@ void wlcore_event_beacon_loss(struct wl1271 *wl, unsigned long roles_bitmap)
237 !test_bit(wlvif->role_id , &roles_bitmap)) 237 !test_bit(wlvif->role_id , &roles_bitmap))
238 continue; 238 continue;
239 239
240 vif = wl12xx_wlvif_to_vif(wlvif);
241
242 /* don't attempt roaming in case of p2p */
243 if (wlvif->p2p) {
244 ieee80211_connection_loss(vif);
245 continue;
246 }
247
240 /* 248 /*
241 * if the work is already queued, it should take place. 249 * if the work is already queued, it should take place.
242 * We don't want to delay the connection loss 250 * We don't want to delay the connection loss
@@ -246,7 +254,6 @@ void wlcore_event_beacon_loss(struct wl1271 *wl, unsigned long roles_bitmap)
246 &wlvif->connection_loss_work, 254 &wlvif->connection_loss_work,
247 msecs_to_jiffies(delay)); 255 msecs_to_jiffies(delay));
248 256
249 vif = wl12xx_wlvif_to_vif(wlvif);
250 ieee80211_cqm_rssi_notify( 257 ieee80211_cqm_rssi_notify(
251 vif, 258 vif,
252 NL80211_CQM_RSSI_BEACON_LOSS_EVENT, 259 NL80211_CQM_RSSI_BEACON_LOSS_EVENT,
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index d7e306333f6c..d10954c0c181 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -108,8 +108,7 @@ static void wl1271_reg_notify(struct wiphy *wiphy,
108 108
109 } 109 }
110 110
111 if (likely(wl->state == WLCORE_STATE_ON)) 111 wlcore_regdomain_config(wl);
112 wlcore_regdomain_config(wl);
113} 112}
114 113
115static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif, 114static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
@@ -332,10 +331,9 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
332 struct wl12xx_vif *wlvif, 331 struct wl12xx_vif *wlvif,
333 u8 hlid, u8 tx_pkts) 332 u8 hlid, u8 tx_pkts)
334{ 333{
335 bool fw_ps, single_link; 334 bool fw_ps;
336 335
337 fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); 336 fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
338 single_link = (wl->active_link_count == 1);
339 337
340 /* 338 /*
341 * Wake up from high level PS if the STA is asleep with too little 339 * Wake up from high level PS if the STA is asleep with too little
@@ -348,8 +346,13 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
348 * Start high-level PS if the STA is asleep with enough blocks in FW. 346 * Start high-level PS if the STA is asleep with enough blocks in FW.
349 * Make an exception if this is the only connected link. In this 347 * Make an exception if this is the only connected link. In this
350 * case FW-memory congestion is less of a problem. 348 * case FW-memory congestion is less of a problem.
349 * Note that a single connected STA means 3 active links, since we must
350 * account for the global and broadcast AP links. The "fw_ps" check
351 * assures us the third link is a STA connected to the AP. Otherwise
352 * the FW would not set the PSM bit.
351 */ 353 */
352 else if (!single_link && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS) 354 else if (wl->active_link_count > 3 && fw_ps &&
355 tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
353 wl12xx_ps_link_start(wl, wlvif, hlid, true); 356 wl12xx_ps_link_start(wl, wlvif, hlid, true);
354} 357}
355 358
@@ -414,13 +417,21 @@ static int wlcore_fw_status(struct wl1271 *wl,
414 417
415 418
416 for_each_set_bit(i, wl->links_map, WL12XX_MAX_LINKS) { 419 for_each_set_bit(i, wl->links_map, WL12XX_MAX_LINKS) {
420 u8 diff;
417 lnk = &wl->links[i]; 421 lnk = &wl->links[i];
422
418 /* prevent wrap-around in freed-packets counter */ 423 /* prevent wrap-around in freed-packets counter */
419 lnk->allocated_pkts -= 424 diff = (status_2->counters.tx_lnk_free_pkts[i] -
420 (status_2->counters.tx_lnk_free_pkts[i] - 425 lnk->prev_freed_pkts) & 0xff;
421 lnk->prev_freed_pkts) & 0xff; 426
427 if (diff == 0)
428 continue;
422 429
430 lnk->allocated_pkts -= diff;
423 lnk->prev_freed_pkts = status_2->counters.tx_lnk_free_pkts[i]; 431 lnk->prev_freed_pkts = status_2->counters.tx_lnk_free_pkts[i];
432
433 /* accumulate the prev_freed_pkts counter */
434 lnk->total_freed_pkts += diff;
424 } 435 }
425 436
426 /* prevent wrap-around in total blocks counter */ 437 /* prevent wrap-around in total blocks counter */
@@ -640,6 +651,25 @@ static irqreturn_t wlcore_irq(int irq, void *cookie)
640 unsigned long flags; 651 unsigned long flags;
641 struct wl1271 *wl = cookie; 652 struct wl1271 *wl = cookie;
642 653
654 /* complete the ELP completion */
655 spin_lock_irqsave(&wl->wl_lock, flags);
656 set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
657 if (wl->elp_compl) {
658 complete(wl->elp_compl);
659 wl->elp_compl = NULL;
660 }
661
662 if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) {
663 /* don't enqueue a work right now. mark it as pending */
664 set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags);
665 wl1271_debug(DEBUG_IRQ, "should not enqueue work");
666 disable_irq_nosync(wl->irq);
667 pm_wakeup_event(wl->dev, 0);
668 spin_unlock_irqrestore(&wl->wl_lock, flags);
669 return IRQ_HANDLED;
670 }
671 spin_unlock_irqrestore(&wl->wl_lock, flags);
672
643 /* TX might be handled here, avoid redundant work */ 673 /* TX might be handled here, avoid redundant work */
644 set_bit(WL1271_FLAG_TX_PENDING, &wl->flags); 674 set_bit(WL1271_FLAG_TX_PENDING, &wl->flags);
645 cancel_work_sync(&wl->tx_work); 675 cancel_work_sync(&wl->tx_work);
@@ -919,18 +949,6 @@ static void wl1271_recovery_work(struct work_struct *work)
919 goto out_unlock; 949 goto out_unlock;
920 } 950 }
921 951
922 /*
923 * Advance security sequence number to overcome potential progress
924 * in the firmware during recovery. This doens't hurt if the network is
925 * not encrypted.
926 */
927 wl12xx_for_each_wlvif(wl, wlvif) {
928 if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) ||
929 test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
930 wlvif->tx_security_seq +=
931 WL1271_TX_SQN_POST_RECOVERY_PADDING;
932 }
933
934 /* Prevent spurious TX during FW restart */ 952 /* Prevent spurious TX during FW restart */
935 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART); 953 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART);
936 954
@@ -2523,6 +2541,8 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
2523 wl1271_ps_elp_sleep(wl); 2541 wl1271_ps_elp_sleep(wl);
2524 } 2542 }
2525deinit: 2543deinit:
2544 wl12xx_tx_reset_wlvif(wl, wlvif);
2545
2526 /* clear all hlids (except system_hlid) */ 2546 /* clear all hlids (except system_hlid) */
2527 wlvif->dev_hlid = WL12XX_INVALID_LINK_ID; 2547 wlvif->dev_hlid = WL12XX_INVALID_LINK_ID;
2528 2548
@@ -2546,7 +2566,6 @@ deinit:
2546 2566
2547 dev_kfree_skb(wlvif->probereq); 2567 dev_kfree_skb(wlvif->probereq);
2548 wlvif->probereq = NULL; 2568 wlvif->probereq = NULL;
2549 wl12xx_tx_reset_wlvif(wl, wlvif);
2550 if (wl->last_wlvif == wlvif) 2569 if (wl->last_wlvif == wlvif)
2551 wl->last_wlvif = NULL; 2570 wl->last_wlvif = NULL;
2552 list_del(&wlvif->list); 2571 list_del(&wlvif->list);
@@ -2860,10 +2879,6 @@ static int wlcore_unset_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2860 wlvif->sta.klv_template_id, 2879 wlvif->sta.klv_template_id,
2861 ACX_KEEP_ALIVE_TPL_INVALID); 2880 ACX_KEEP_ALIVE_TPL_INVALID);
2862 2881
2863 /* reset TX security counters on a clean disconnect */
2864 wlvif->tx_security_last_seq_lsb = 0;
2865 wlvif->tx_security_seq = 0;
2866
2867 return 0; 2882 return 0;
2868} 2883}
2869 2884
@@ -3262,6 +3277,7 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
3262 u32 tx_seq_32 = 0; 3277 u32 tx_seq_32 = 0;
3263 u16 tx_seq_16 = 0; 3278 u16 tx_seq_16 = 0;
3264 u8 key_type; 3279 u8 key_type;
3280 u8 hlid;
3265 3281
3266 wl1271_debug(DEBUG_MAC80211, "mac80211 set key"); 3282 wl1271_debug(DEBUG_MAC80211, "mac80211 set key");
3267 3283
@@ -3271,6 +3287,22 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
3271 key_conf->keylen, key_conf->flags); 3287 key_conf->keylen, key_conf->flags);
3272 wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen); 3288 wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen);
3273 3289
3290 if (wlvif->bss_type == BSS_TYPE_AP_BSS)
3291 if (sta) {
3292 struct wl1271_station *wl_sta = (void *)sta->drv_priv;
3293 hlid = wl_sta->hlid;
3294 } else {
3295 hlid = wlvif->ap.bcast_hlid;
3296 }
3297 else
3298 hlid = wlvif->sta.hlid;
3299
3300 if (hlid != WL12XX_INVALID_LINK_ID) {
3301 u64 tx_seq = wl->links[hlid].total_freed_pkts;
3302 tx_seq_32 = WL1271_TX_SECURITY_HI32(tx_seq);
3303 tx_seq_16 = WL1271_TX_SECURITY_LO16(tx_seq);
3304 }
3305
3274 switch (key_conf->cipher) { 3306 switch (key_conf->cipher) {
3275 case WLAN_CIPHER_SUITE_WEP40: 3307 case WLAN_CIPHER_SUITE_WEP40:
3276 case WLAN_CIPHER_SUITE_WEP104: 3308 case WLAN_CIPHER_SUITE_WEP104:
@@ -3280,22 +3312,14 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
3280 break; 3312 break;
3281 case WLAN_CIPHER_SUITE_TKIP: 3313 case WLAN_CIPHER_SUITE_TKIP:
3282 key_type = KEY_TKIP; 3314 key_type = KEY_TKIP;
3283
3284 key_conf->hw_key_idx = key_conf->keyidx; 3315 key_conf->hw_key_idx = key_conf->keyidx;
3285 tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
3286 tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
3287 break; 3316 break;
3288 case WLAN_CIPHER_SUITE_CCMP: 3317 case WLAN_CIPHER_SUITE_CCMP:
3289 key_type = KEY_AES; 3318 key_type = KEY_AES;
3290
3291 key_conf->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE; 3319 key_conf->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
3292 tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
3293 tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
3294 break; 3320 break;
3295 case WL1271_CIPHER_SUITE_GEM: 3321 case WL1271_CIPHER_SUITE_GEM:
3296 key_type = KEY_GEM; 3322 key_type = KEY_GEM;
3297 tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
3298 tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
3299 break; 3323 break;
3300 default: 3324 default:
3301 wl1271_error("Unknown key algo 0x%x", key_conf->cipher); 3325 wl1271_error("Unknown key algo 0x%x", key_conf->cipher);
@@ -3358,6 +3382,10 @@ void wlcore_regdomain_config(struct wl1271 *wl)
3358 return; 3382 return;
3359 3383
3360 mutex_lock(&wl->mutex); 3384 mutex_lock(&wl->mutex);
3385
3386 if (unlikely(wl->state != WLCORE_STATE_ON))
3387 goto out;
3388
3361 ret = wl1271_ps_elp_wakeup(wl); 3389 ret = wl1271_ps_elp_wakeup(wl);
3362 if (ret < 0) 3390 if (ret < 0)
3363 goto out; 3391 goto out;
@@ -4499,6 +4527,9 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
4499 return -EBUSY; 4527 return -EBUSY;
4500 } 4528 }
4501 4529
4530 /* use the previous security seq, if this is a recovery/resume */
4531 wl->links[wl_sta->hlid].total_freed_pkts = wl_sta->total_freed_pkts;
4532
4502 set_bit(wl_sta->hlid, wlvif->ap.sta_hlid_map); 4533 set_bit(wl_sta->hlid, wlvif->ap.sta_hlid_map);
4503 memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN); 4534 memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN);
4504 wl->active_sta_count++; 4535 wl->active_sta_count++;
@@ -4507,12 +4538,37 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
4507 4538
4508void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid) 4539void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
4509{ 4540{
4541 struct wl1271_station *wl_sta;
4542 struct ieee80211_sta *sta;
4543 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
4544
4510 if (!test_bit(hlid, wlvif->ap.sta_hlid_map)) 4545 if (!test_bit(hlid, wlvif->ap.sta_hlid_map))
4511 return; 4546 return;
4512 4547
4513 clear_bit(hlid, wlvif->ap.sta_hlid_map); 4548 clear_bit(hlid, wlvif->ap.sta_hlid_map);
4514 __clear_bit(hlid, &wl->ap_ps_map); 4549 __clear_bit(hlid, &wl->ap_ps_map);
4515 __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); 4550 __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
4551
4552 /*
4553 * save the last used PN in the private part of iee80211_sta,
4554 * in case of recovery/suspend
4555 */
4556 rcu_read_lock();
4557 sta = ieee80211_find_sta(vif, wl->links[hlid].addr);
4558 if (sta) {
4559 wl_sta = (void *)sta->drv_priv;
4560 wl_sta->total_freed_pkts = wl->links[hlid].total_freed_pkts;
4561
4562 /*
4563 * increment the initial seq number on recovery to account for
4564 * transmitted packets that we haven't yet got in the FW status
4565 */
4566 if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
4567 wl_sta->total_freed_pkts +=
4568 WL1271_TX_SQN_POST_RECOVERY_PADDING;
4569 }
4570 rcu_read_unlock();
4571
4516 wl12xx_free_link(wl, wlvif, &hlid); 4572 wl12xx_free_link(wl, wlvif, &hlid);
4517 wl->active_sta_count--; 4573 wl->active_sta_count--;
4518 4574
@@ -4616,13 +4672,11 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
4616 enum ieee80211_sta_state new_state) 4672 enum ieee80211_sta_state new_state)
4617{ 4673{
4618 struct wl1271_station *wl_sta; 4674 struct wl1271_station *wl_sta;
4619 u8 hlid;
4620 bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS; 4675 bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
4621 bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS; 4676 bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
4622 int ret; 4677 int ret;
4623 4678
4624 wl_sta = (struct wl1271_station *)sta->drv_priv; 4679 wl_sta = (struct wl1271_station *)sta->drv_priv;
4625 hlid = wl_sta->hlid;
4626 4680
4627 /* Add station (AP mode) */ 4681 /* Add station (AP mode) */
4628 if (is_ap && 4682 if (is_ap &&
@@ -4648,12 +4702,12 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
4648 /* Authorize station (AP mode) */ 4702 /* Authorize station (AP mode) */
4649 if (is_ap && 4703 if (is_ap &&
4650 new_state == IEEE80211_STA_AUTHORIZED) { 4704 new_state == IEEE80211_STA_AUTHORIZED) {
4651 ret = wl12xx_cmd_set_peer_state(wl, wlvif, hlid); 4705 ret = wl12xx_cmd_set_peer_state(wl, wlvif, wl_sta->hlid);
4652 if (ret < 0) 4706 if (ret < 0)
4653 return ret; 4707 return ret;
4654 4708
4655 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, 4709 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true,
4656 hlid); 4710 wl_sta->hlid);
4657 if (ret) 4711 if (ret)
4658 return ret; 4712 return ret;
4659 4713
@@ -4784,7 +4838,7 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
4784 break; 4838 break;
4785 } 4839 }
4786 4840
4787 if (wl->ba_rx_session_count >= RX_BA_MAX_SESSIONS) { 4841 if (wl->ba_rx_session_count >= wl->ba_rx_session_count_max) {
4788 ret = -EBUSY; 4842 ret = -EBUSY;
4789 wl1271_error("exceeded max RX BA sessions"); 4843 wl1271_error("exceeded max RX BA sessions");
4790 break; 4844 break;
@@ -4946,7 +5000,7 @@ out:
4946 mutex_unlock(&wl->mutex); 5000 mutex_unlock(&wl->mutex);
4947} 5001}
4948 5002
4949static void wlcore_op_flush(struct ieee80211_hw *hw, bool drop) 5003static void wlcore_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
4950{ 5004{
4951 struct wl1271 *wl = hw->priv; 5005 struct wl1271 *wl = hw->priv;
4952 5006
@@ -5092,6 +5146,39 @@ static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
5092 wlcore_hw_sta_rc_update(wl, wlvif, sta, changed); 5146 wlcore_hw_sta_rc_update(wl, wlvif, sta, changed);
5093} 5147}
5094 5148
5149static int wlcore_op_get_rssi(struct ieee80211_hw *hw,
5150 struct ieee80211_vif *vif,
5151 struct ieee80211_sta *sta,
5152 s8 *rssi_dbm)
5153{
5154 struct wl1271 *wl = hw->priv;
5155 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
5156 int ret = 0;
5157
5158 wl1271_debug(DEBUG_MAC80211, "mac80211 get_rssi");
5159
5160 mutex_lock(&wl->mutex);
5161
5162 if (unlikely(wl->state != WLCORE_STATE_ON))
5163 goto out;
5164
5165 ret = wl1271_ps_elp_wakeup(wl);
5166 if (ret < 0)
5167 goto out_sleep;
5168
5169 ret = wlcore_acx_average_rssi(wl, wlvif, rssi_dbm);
5170 if (ret < 0)
5171 goto out_sleep;
5172
5173out_sleep:
5174 wl1271_ps_elp_sleep(wl);
5175
5176out:
5177 mutex_unlock(&wl->mutex);
5178
5179 return ret;
5180}
5181
5095static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) 5182static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
5096{ 5183{
5097 struct wl1271 *wl = hw->priv; 5184 struct wl1271 *wl = hw->priv;
@@ -5291,6 +5378,7 @@ static const struct ieee80211_ops wl1271_ops = {
5291 .assign_vif_chanctx = wlcore_op_assign_vif_chanctx, 5378 .assign_vif_chanctx = wlcore_op_assign_vif_chanctx,
5292 .unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx, 5379 .unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx,
5293 .sta_rc_update = wlcore_op_sta_rc_update, 5380 .sta_rc_update = wlcore_op_sta_rc_update,
5381 .get_rssi = wlcore_op_get_rssi,
5294 CFG80211_TESTMODE_CMD(wl1271_tm_cmd) 5382 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
5295}; 5383};
5296 5384
@@ -5930,35 +6018,6 @@ int wlcore_free_hw(struct wl1271 *wl)
5930} 6018}
5931EXPORT_SYMBOL_GPL(wlcore_free_hw); 6019EXPORT_SYMBOL_GPL(wlcore_free_hw);
5932 6020
5933static irqreturn_t wl12xx_hardirq(int irq, void *cookie)
5934{
5935 struct wl1271 *wl = cookie;
5936 unsigned long flags;
5937
5938 wl1271_debug(DEBUG_IRQ, "IRQ");
5939
5940 /* complete the ELP completion */
5941 spin_lock_irqsave(&wl->wl_lock, flags);
5942 set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
5943 if (wl->elp_compl) {
5944 complete(wl->elp_compl);
5945 wl->elp_compl = NULL;
5946 }
5947
5948 if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) {
5949 /* don't enqueue a work right now. mark it as pending */
5950 set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags);
5951 wl1271_debug(DEBUG_IRQ, "should not enqueue work");
5952 disable_irq_nosync(wl->irq);
5953 pm_wakeup_event(wl->dev, 0);
5954 spin_unlock_irqrestore(&wl->wl_lock, flags);
5955 return IRQ_HANDLED;
5956 }
5957 spin_unlock_irqrestore(&wl->wl_lock, flags);
5958
5959 return IRQ_WAKE_THREAD;
5960}
5961
5962static void wlcore_nvs_cb(const struct firmware *fw, void *context) 6021static void wlcore_nvs_cb(const struct firmware *fw, void *context)
5963{ 6022{
5964 struct wl1271 *wl = context; 6023 struct wl1271 *wl = context;
@@ -6000,9 +6059,8 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
6000 else 6059 else
6001 irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; 6060 irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
6002 6061
6003 ret = request_threaded_irq(wl->irq, wl12xx_hardirq, wlcore_irq, 6062 ret = request_threaded_irq(wl->irq, NULL, wlcore_irq,
6004 irqflags, 6063 irqflags, pdev->name, wl);
6005 pdev->name, wl);
6006 if (ret < 0) { 6064 if (ret < 0) {
6007 wl1271_error("request_irq() failed: %d", ret); 6065 wl1271_error("request_irq() failed: %d", ret);
6008 goto out_free_nvs; 6066 goto out_free_nvs;
diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c
index 9b7b6e2e4fbc..9654577efd01 100644
--- a/drivers/net/wireless/ti/wlcore/ps.c
+++ b/drivers/net/wireless/ti/wlcore/ps.c
@@ -29,6 +29,7 @@
29#define WL1271_WAKEUP_TIMEOUT 500 29#define WL1271_WAKEUP_TIMEOUT 500
30 30
31#define ELP_ENTRY_DELAY 30 31#define ELP_ENTRY_DELAY 30
32#define ELP_ENTRY_DELAY_FORCE_PS 5
32 33
33void wl1271_elp_work(struct work_struct *work) 34void wl1271_elp_work(struct work_struct *work)
34{ 35{
@@ -98,7 +99,8 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
98 return; 99 return;
99 } 100 }
100 101
101 timeout = ELP_ENTRY_DELAY; 102 timeout = wl->conf.conn.forced_ps ?
103 ELP_ENTRY_DELAY_FORCE_PS : ELP_ENTRY_DELAY;
102 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, 104 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
103 msecs_to_jiffies(timeout)); 105 msecs_to_jiffies(timeout));
104} 106}
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index ece392c54d9c..004d02e71f01 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -24,6 +24,7 @@
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/etherdevice.h> 26#include <linux/etherdevice.h>
27#include <linux/spinlock.h>
27 28
28#include "wlcore.h" 29#include "wlcore.h"
29#include "debug.h" 30#include "debug.h"
@@ -104,7 +105,7 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl,
104 struct wl12xx_vif *wlvif, 105 struct wl12xx_vif *wlvif,
105 u8 hlid) 106 u8 hlid)
106{ 107{
107 bool fw_ps, single_link; 108 bool fw_ps;
108 u8 tx_pkts; 109 u8 tx_pkts;
109 110
110 if (WARN_ON(!test_bit(hlid, wlvif->links_map))) 111 if (WARN_ON(!test_bit(hlid, wlvif->links_map)))
@@ -112,15 +113,19 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl,
112 113
113 fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); 114 fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
114 tx_pkts = wl->links[hlid].allocated_pkts; 115 tx_pkts = wl->links[hlid].allocated_pkts;
115 single_link = (wl->active_link_count == 1);
116 116
117 /* 117 /*
118 * if in FW PS and there is enough data in FW we can put the link 118 * if in FW PS and there is enough data in FW we can put the link
119 * into high-level PS and clean out its TX queues. 119 * into high-level PS and clean out its TX queues.
120 * Make an exception if this is the only connected link. In this 120 * Make an exception if this is the only connected link. In this
121 * case FW-memory congestion is less of a problem. 121 * case FW-memory congestion is less of a problem.
122 * Note that a single connected STA means 3 active links, since we must
123 * account for the global and broadcast AP links. The "fw_ps" check
124 * assures us the third link is a STA connected to the AP. Otherwise
125 * the FW would not set the PSM bit.
122 */ 126 */
123 if (!single_link && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS) 127 if (wl->active_link_count > 3 && fw_ps &&
128 tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
124 wl12xx_ps_link_start(wl, wlvif, hlid, true); 129 wl12xx_ps_link_start(wl, wlvif, hlid, true);
125} 130}
126 131
@@ -639,6 +644,7 @@ next:
639 644
640 } 645 }
641 646
647out:
642 if (!skb && 648 if (!skb &&
643 test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) { 649 test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) {
644 int q; 650 int q;
@@ -652,7 +658,6 @@ next:
652 spin_unlock_irqrestore(&wl->wl_lock, flags); 658 spin_unlock_irqrestore(&wl->wl_lock, flags);
653 } 659 }
654 660
655out:
656 return skb; 661 return skb;
657} 662}
658 663
@@ -928,25 +933,6 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
928 933
929 wl->stats.retry_count += result->ack_failures; 934 wl->stats.retry_count += result->ack_failures;
930 935
931 /*
932 * update sequence number only when relevant, i.e. only in
933 * sessions of TKIP, AES and GEM (not in open or WEP sessions)
934 */
935 if (info->control.hw_key &&
936 (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP ||
937 info->control.hw_key->cipher == WLAN_CIPHER_SUITE_CCMP ||
938 info->control.hw_key->cipher == WL1271_CIPHER_SUITE_GEM)) {
939 u8 fw_lsb = result->tx_security_sequence_number_lsb;
940 u8 cur_lsb = wlvif->tx_security_last_seq_lsb;
941
942 /*
943 * update security sequence number, taking care of potential
944 * wrap-around
945 */
946 wlvif->tx_security_seq += (fw_lsb - cur_lsb) & 0xff;
947 wlvif->tx_security_last_seq_lsb = fw_lsb;
948 }
949
950 /* remove private header from packet */ 936 /* remove private header from packet */
951 skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); 937 skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
952 938
@@ -1061,7 +1047,8 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1061 1047
1062 /* TX failure */ 1048 /* TX failure */
1063 for_each_set_bit(i, wlvif->links_map, WL12XX_MAX_LINKS) { 1049 for_each_set_bit(i, wlvif->links_map, WL12XX_MAX_LINKS) {
1064 if (wlvif->bss_type == BSS_TYPE_AP_BSS) { 1050 if (wlvif->bss_type == BSS_TYPE_AP_BSS &&
1051 i != wlvif->ap.bcast_hlid && i != wlvif->ap.global_hlid) {
1065 /* this calls wl12xx_free_link */ 1052 /* this calls wl12xx_free_link */
1066 wl1271_free_sta(wl, wlvif, i); 1053 wl1271_free_sta(wl, wlvif, i);
1067 } else { 1054 } else {
@@ -1304,7 +1291,7 @@ bool wlcore_is_queue_stopped_by_reason_locked(struct wl1271 *wl,
1304{ 1291{
1305 int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue); 1292 int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue);
1306 1293
1307 WARN_ON_ONCE(!spin_is_locked(&wl->wl_lock)); 1294 assert_spin_locked(&wl->wl_lock);
1308 return test_bit(reason, &wl->queue_stop_reasons[hwq]); 1295 return test_bit(reason, &wl->queue_stop_reasons[hwq]);
1309} 1296}
1310 1297
@@ -1313,6 +1300,6 @@ bool wlcore_is_queue_stopped_locked(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1313{ 1300{
1314 int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue); 1301 int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue);
1315 1302
1316 WARN_ON_ONCE(!spin_is_locked(&wl->wl_lock)); 1303 assert_spin_locked(&wl->wl_lock);
1317 return !!wl->queue_stop_reasons[hwq]; 1304 return !!wl->queue_stop_reasons[hwq];
1318} 1305}
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index af9fecaefc30..0034979e97cb 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -390,6 +390,9 @@ struct wl1271 {
390 /* number of currently active RX BA sessions */ 390 /* number of currently active RX BA sessions */
391 int ba_rx_session_count; 391 int ba_rx_session_count;
392 392
393 /* Maximum number of supported RX BA sessions */
394 int ba_rx_session_count_max;
395
393 /* AP-mode - number of currently connected stations */ 396 /* AP-mode - number of currently connected stations */
394 int active_sta_count; 397 int active_sta_count;
395 398
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 508f5b0f8a70..e5e146435fe7 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -274,6 +274,13 @@ struct wl1271_link {
274 274
275 /* The wlvif this link belongs to. Might be null for global links */ 275 /* The wlvif this link belongs to. Might be null for global links */
276 struct wl12xx_vif *wlvif; 276 struct wl12xx_vif *wlvif;
277
278 /*
279 * total freed FW packets on the link - used for tracking the
280 * AES/TKIP PN across recoveries. Re-initialized each time
281 * from the wl1271_station structure.
282 */
283 u64 total_freed_pkts;
277}; 284};
278 285
279#define WL1271_MAX_RX_FILTERS 5 286#define WL1271_MAX_RX_FILTERS 5
@@ -318,6 +325,13 @@ struct wl12xx_rx_filter {
318struct wl1271_station { 325struct wl1271_station {
319 u8 hlid; 326 u8 hlid;
320 bool in_connection; 327 bool in_connection;
328
329 /*
330 * total freed FW packets on the link to the STA - used for tracking the
331 * AES/TKIP PN across recoveries. Re-initialized each time from the
332 * wl1271_station structure.
333 */
334 u64 total_freed_pkts;
321}; 335};
322 336
323struct wl12xx_vif { 337struct wl12xx_vif {
@@ -449,16 +463,15 @@ struct wl12xx_vif {
449 */ 463 */
450 struct { 464 struct {
451 u8 persistent[0]; 465 u8 persistent[0];
466
452 /* 467 /*
453 * Security sequence number 468 * total freed FW packets on the link - used for
454 * bits 0-15: lower 16 bits part of sequence number 469 * storing the AES/TKIP PN during recovery, as this
455 * bits 16-47: higher 32 bits part of sequence number 470 * structure is not zeroed out.
456 * bits 48-63: not in use 471 * For STA this holds the PN of the link to the AP.
472 * For AP this holds the PN of the broadcast link.
457 */ 473 */
458 u64 tx_security_seq; 474 u64 total_freed_pkts;
459
460 /* 8 bits of the last sequence number in use */
461 u8 tx_security_last_seq_lsb;
462 }; 475 };
463}; 476};
464 477
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 63ff69f9d3eb..a8dc95ebf2d6 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -347,6 +347,21 @@ static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in,
347 return (s8)gain; 347 return (s8)gain;
348} 348}
349 349
350static void sprom_extract_r23(struct ssb_sprom *out, const u16 *in)
351{
352 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
353 SPEX(opo, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0);
354 SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0);
355 SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0);
356 SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0);
357 SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0);
358 SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0);
359 SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0);
360 SPEX(maxpwr_ah, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0);
361 SPEX(maxpwr_al, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO,
362 SSB_SPROM2_MAXP_A_LO_SHIFT);
363}
364
350static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) 365static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
351{ 366{
352 u16 loc[3]; 367 u16 loc[3];
@@ -369,6 +384,7 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
369 SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14); 384 SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
370 SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15); 385 SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
371 SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0); 386 SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
387 SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
372 if (out->revision == 1) 388 if (out->revision == 1)
373 SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE, 389 SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
374 SSB_SPROM1_BINF_CCODE_SHIFT); 390 SSB_SPROM1_BINF_CCODE_SHIFT);
@@ -395,8 +411,7 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
395 SSB_SPROM1_ITSSI_A_SHIFT); 411 SSB_SPROM1_ITSSI_A_SHIFT);
396 SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0); 412 SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
397 SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0); 413 SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
398 if (out->revision >= 2) 414
399 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
400 SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8); 415 SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8);
401 SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0); 416 SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0);
402 417
@@ -407,6 +422,8 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
407 out->antenna_gain.a1 = r123_extract_antgain(out->revision, in, 422 out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
408 SSB_SPROM1_AGAIN_A, 423 SSB_SPROM1_AGAIN_A,
409 SSB_SPROM1_AGAIN_A_SHIFT); 424 SSB_SPROM1_AGAIN_A_SHIFT);
425 if (out->revision >= 2)
426 sprom_extract_r23(out, in);
410} 427}
411 428
412/* Revs 4 5 and 8 have partially shared layout */ 429/* Revs 4 5 and 8 have partially shared layout */
@@ -464,6 +481,7 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
464 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, 481 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
465 SSB_SPROM4_ETHPHY_ET1A_SHIFT); 482 SSB_SPROM4_ETHPHY_ET1A_SHIFT);
466 SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0); 483 SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0);
484 SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
467 if (out->revision == 4) { 485 if (out->revision == 4) {
468 SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8); 486 SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8);
469 SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0); 487 SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0);
@@ -535,6 +553,7 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
535 sprom_get_mac(out->il0mac, &in[SPOFF(SSB_SPROM8_IL0MAC)]); 553 sprom_get_mac(out->il0mac, &in[SPOFF(SSB_SPROM8_IL0MAC)]);
536 554
537 SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0); 555 SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0);
556 SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
538 SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8); 557 SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
539 SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0); 558 SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
540 SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0); 559 SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);